K6ZDYZKXSLTLCCHWYK6K6WOCNXBZOXEDKDVNNJVCZUFOLLSUO5UAC 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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endA(--[[preserve screen_top of cursor node]] true)endend
{"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 thenendif App.mouse_down(1) thenB()endendViewport.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 settingslove.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update itfor _,obj in ipairs(Surface) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w theninitialize_editor(obj)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
B = function()-- recompute various aspects based on the current viewport settingslove.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update itfor _,obj in ipairs(Surface) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w thenupdate_editor_box(obj)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
{"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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endText.clear_screen_line_cache(node.editor, i)endreturn yend
{"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 thenendif App.mouse_down(1) thenB()clip_all()endendViewport.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 endobj.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 textlocal 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)endend
{"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 = {-- pagetype='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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
{"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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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}
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal text = love.graphics.newText(font(20), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendif not child.width thenchild.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory.endsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))endendend
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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal 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 endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendif not child.width thenchild.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory.endsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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 itlove.graphics.setFont(love.graphics.newFont(scale(20)))for _,obj in ipairs(Surface) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w theninitialize_editor(obj)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
{"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 = {-- pagetype='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,-- pagetype='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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endA(--[[preserve screen_top of cursor node]] true)elseif chord == 'up' thenViewport.y = Viewport.y - scale(20)elseif chord == 'down' thenViewport.y = Viewport.y + scale(20)elseif chord == 'left' thenViewport.x = Viewport.x - scale(50)elseif chord == 'right' thenViewport.x = Viewport.x + scale(50)elseif chord == 'pageup' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomelseif chord == 'S-up' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomelseif chord == 'pagedown' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomelseif chord == 'S-down' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomelseif chord == 'S-left' thenViewport.x = Viewport.x - App.screen.width/Viewport.zoomelseif chord == 'S-right' thenViewport.x = Viewport.x + App.screen.width/Viewport.zoomendendend
{"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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB()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 textlocal 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)endend
{"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 = {-- pagetype='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 = yfor i=1,#editor.lines doText.populate_screen_line_starting_pos(editor, i)local height = line_height(editor, i)if y_offset < height thenlocal 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-indexingy_offset = y_offset - nlines*editor.line_heightreturn {line=i, pos=pos}, -y_offsetendy_offset = y_offset - heightend-- y is below the panereturn {line=#pane.lines+1, pos=1}, y_offset -- positive valueend
{"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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endendreturn yend
{"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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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) dolove.graphics.setColor(obj.r or 1, obj.g or 1, obj.b or 1)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))endendend
{"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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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,-- pagetype='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 settingslove.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update itfor _,obj in ipairs(Surface) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w thenupdate_editor_box(obj, preserve_screen_top_of_cursor_node)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
{"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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal 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 endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendif node.width and not child.width thenchild.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory.endsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal 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 endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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 = {-- pagetype='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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endendreturn yend
{"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}
{"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 = yfor i=1,#editor.lines doText.populate_screen_line_starting_pos(editor, i)local height = line_height(editor, i, editor.left, editor.right)if y_offset < height thenlocal 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-indexingy_offset = y_offset - nlines*editor.line_heightreturn {line=i, pos=pos}, -y_offsetendy_offset = y_offset - heightend-- y is below the panereturn {line=#pane.lines+1, pos=1}, y_offset -- positive valueend
{"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) docolor(obj.r or 1, obj.g or 1, obj.b or 1)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))endendend
{"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) doif node.type == 'text' thenprint(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) thenif y >= vy(node.y) and node.h and y < vy(node.y + node.h) thenreturn nodeendendendendend
update_editor_box = function(node, preserve_screen_top_of_cursor_node)if node.editor == nil then return endif node.y > Viewport.y thenif not preserve_screen_top_of_cursor_node or node ~= Cursor_node thennode.editor.screen_top1.line = 1node.editor.screen_top1.pos = 1endnode.editor.top = vy(node.y)elsenode.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)endprint('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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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,-- pagetype='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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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}, 0assert(y >= 0)local y_offset = yfor i=1,#editor.lines doText.populate_screen_line_starting_pos(editor, i)local height = line_height(editor, i, editor.left, editor.right)if y_offset < height thenlocal 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-indexingy_offset = y_offset - nlines*editor.line_heightreturn {line=i, pos=pos}, -y_offsetendy_offset = y_offset - heightend-- y is below the panereturn {line=#pane.lines+1, pos=1}, y_offset -- positive valueend
{"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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endB(--[[skip_cursor_node]] true)endend
{"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) doif node.type == 'text' thenprint(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 thenif y >= node.y and node.h and y < node.y + node.h thenreturn nodeendendendendend
{"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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal 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 endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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 endif obj.y > Viewport.y thenobj.editor.screen_top1.line = 1obj.editor.screen_top1.pos = 1obj.editor.top = vy(obj.y)elseobj.editor.screen_top1, obj.editor.top = schema1_of_y(obj.editor, Viewport.y - obj.y)endprint('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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelsenode.w = 0for i,s in ipairs(node.data) dolocal text = love.graphics.newText(font(20), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendif node.editor == nil theninitialize_editor(node)elseupdate_editor_box(obj, preserve_screen_top_of_cursor_node)endnode.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendif not child.width thenchild.width = node.width -- HACK: should we set child.w or child.width? Neither is quite satisfactory.endsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenprint('before', Viewport.y)Viewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)print('after', Viewport.y)endB(--[[skip_cursor_node]] true)endend
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 = {-- pagetype='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 textprint(x,y, node.data[1])node.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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) docolor(obj.r or 1, obj.g or 1, obj.b or 1)if obj.type == 'rect' thenrect(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendline(unpack(obj.zdata))elseif obj.type == 'circle' thencirc(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endline(unpack(obj.zdata))endendend
{"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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenprint('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' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
to_text = function(x,y)for _,node in ipairs(Surface) doif node.type == 'text' thenprint(x, y, node.data[1], node.x, node.y, node.w, node.h)if x >= node.x and x < node.x + node.w thenif y >= node.y and y < node.y + node.h thenreturn nodeendendendendend
{"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) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w theninitialize_editor(obj)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endB(--[[preserve screen_top of cursor node]] true)endend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenendendedit.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) doif node.type == 'text' thenprint(node.data[1])if x >= node.x and x < node.x + node.w thenif y >= node.y and y < node.y + node.h thenreturn nodeendendendendend
{"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 textlocal 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)endend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endB(--[[skip_cursor_node]] true)endend
{"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 = {-- pagetype='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 thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.editor.screen_top1)endB(--[[preserve screen_top of cursor node]] true)endend
{"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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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 = {-- pagetype='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 textlocal 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)endend
{"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 inViewport.zoom = Viewport.zoom+0.1B()elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1B()elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0B()elseif Cursor_node thenlocal 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) thenViewport.y = Cursor_node.y + y_of_schema1(Cursor_node.editor, Cursor_node.screen_top1)endB(--[[skip_cursor_node]] true)endend
{"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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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 textlocal 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)endend
{"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 = {-- pagetype='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' thenlocal node_to_renderif node.bg thennode_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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endendreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
update_editor_box = function(node, skip_cursor_node)if node.editor == nil then return endif skip_cursor_node and node == Cursor_node then return endif node.y > Viewport.y thennode.editor.screen_top1.line = 1node.editor.screen_top1.pos = 1node.editor.top = vy(node.y)elsenode.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)endprint('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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
{"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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,2000,300 dofor y=-10000,10000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
{"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 textlocal 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)endend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
{"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 endif skip_cursor_node and node == Cursor_node then return endif node.y > Viewport.y thennode.editor.screen_top1.line = 1node.editor.screen_top1.pos = 1node.editor.top = vy(node.y)elsenode.editor.screen_top1, node.editor.top = schema1_of_y(node.editor, Viewport.y - node.y)endprint('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 = {-- pagetype='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 textlocal 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)endend
{"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 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface) -- just in case we edited Pageendon.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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
{"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 endif skip_cursor_node and obj == Cursor_node then return endif obj.y > Viewport.y thenobj.editor.screen_top1.line = 1obj.editor.screen_top1.pos = 1obj.editor.top = vy(obj.y)elseobj.editor.screen_top1, obj.editor.top = schema1_of_y(obj.editor, Viewport.y - obj.y)endprint('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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, obj.show_cursor)endendendend
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 textlocal 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)endend
{"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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
to_text = function(x,y)for _,node in ipairs(Surface) doif node.type == 'text' thenif x >= node.x and x < node.x + node.w thenif y >= node.y and y < node.y + node.h thenreturn nodeendendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
Page = {-- pagetype='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 textlocal 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)endend
B = function(skip_cursor_node)-- recompute various aspects based on the current viewport settingslove.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font so update itfor _,obj in ipairs(Surface) doif obj.type == 'line' thenobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endelseif obj.type == 'bezier' thenzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenif obj.w thenupdate_editor_box(obj, skip_cursor_node)elseobj.text = love.graphics.newText(love.graphics.getFont(), obj.data)endendendend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,2000,300 dofor y=-1000,1000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()love.graphics.setColor(1,0,0)for y=0,1000,100 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
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 textnode.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for i,s in ipairs(node.data) dolocal 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 endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
while #Surface > 3 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface)endon.code_change = function()
Page = {-- pagetype='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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,300 dofor y=-1000,1000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
while #Surface > 3 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
while #Surface > 3 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface)endon.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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
box_height = function(node)-- return the height of a node. The result is scaled.if #node.editor.lines > 1 then Box_heights = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thenprint('box height', i, y)table.insert(Box_heights, y)endendreturn yend
Page = {-- pagetype='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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,200 dofor y=-1000,1000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
Page = {-- pagetype='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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + node.editor.line_height*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thenprint('box height', i, y)table.insert(Box_heights, y)endendreturn yend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,400 dofor y=-1000,1000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
Page = {-- pagetype='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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenprint('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' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
box_height = function(node)-- return the height of a node. The result is scaled.if #node.editor.lines > 1 then Box_heights = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thenprint('box height', i, y)table.insert(Box_heights, y)endendreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,1000 dofor y=-1000,1000,200 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,1000 dofor y=-1000,1000,100 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
box_height = function(node)-- return the height of a node. The result is scaled.if #node.editor.lines > 1 then Box_heights = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thenprint('box height', i, y)table.insert(Box_heights, y)endendreturn yend
Page = {-- pagetype='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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()print('== draw')for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenprint('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' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseprint('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 cursorendendendend
box_height = function(node)-- return the height of a node. The result is scaled.if #node.editor.lines > 1 then Box_heights = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endendreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('creating text of size', scaled_fontsize)love.graphics.setFont(scaled_fontsize)obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKlocal red = falsefor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_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 redendendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
Page = {-- pagetype='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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_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)endendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseprint('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 cursorendendendend
on.draw = function()love.graphics.setColor(1,0,0)for y=0,1000,100 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in ipairs(Box_heights) dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_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)endendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
Page = {-- pagetype='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 Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_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)endendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=1,g=0,b=0}, 10)endendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseprint('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 cursorendendendend
Page = {-- pagetype='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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endlove.graphics.setColor(0,1,0)for _,y in Box_heights dolove.graphics.line(vx(0), vy(y), vx(10), vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor x=-1000,1000,100 dofor y=-1000,1000,100 doadd_thick_line({type='line', data={x,y, x+2000,y+2000, x,y+4000}, r=1,g=0,b=0}, 10)endendcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor y=-1000,1000,100 doadd_thick_line({type='line', data={-1000,y, 1000,y+2000, -6000,y+4000}, r=1,g=0,b=0}, 10)endcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
box_height = function(node)-- return the height of a node. The result is scaled.Box_heights = {}local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_postable.insert(Box_heights, y)endreturn yend
Page = {-- pagetype='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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseprint('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 cursorendendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor y=-1000,1000,100 doadd_thick_line({type='line', data={-6000,y, 6000,y+2000, -6000,y+4000}, r=1,g=0,b=0}, 10)endcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
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 = {} endlocal y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posif #node.editor.lines > 1 thentable.insert(Box_heights, y)endText.clear_screen_line_cache(node.editor, i)endreturn yend
box_height = function(node)-- return the height of a node. The result is scaled.local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor y=-1000,1000,100 doadd_thick_line({type='line', data={-6000,y, 6000,y+2000}, r=1,g=0,b=0}, 10)endcompute_layout(Page, Page.x,Page.y, Surface, preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
box_height = function(node)-- return the height of a node. The result is scaled.local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKfor y=-1000,1000,100 doadd_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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endprint('draw text', obj.data[1], obj.editor.lines[1].data, obj.w)if obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
box_height = function(node)-- return the height of a node. The result is scaled.local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKadd_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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
box_height = function(node)-- return the height of a node. The result is scaled.local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKadd_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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
add_thick_line = function(s, thickness)-- increase the thickness of a horizontal-ish linetable.insert(Surface, s)for i=1,thickness-1 dolocal s = copy_shape(s)for j=2,#s.data, 2 dos.data[j] = s.data[j]+1endtable.insert(Surface, s)endend
on.draw = function()love.graphics.setColor(1,0,0)for y=0,1000,100 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
add_thick_line = function(s, thickness)-- increase the thickness of a horizontal-ish linetable.insert(Surface, s)for i=1,thickness-1 dofor j=2,#s.data, 2 dos.data[j] = s.data[j]+1endtable.insert(Surface, s)endend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endprint('draw text', obj.data, obj.data[1], obj.w, obj.fg)if obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKtable.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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKtable.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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()love.graphics.setColor(1,0,0)for y=0,1000,100 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseprint('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)endendendend
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 3 do table.remove(Surface) end -- HACKtable.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 pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endprint('draw text', obj.data, obj.data[1], obj.w)if obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('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)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + math.floor(scale(node.editor.line_height))*#node.editor.line_cache[i].screen_line_starting_posendreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
while #Surface > 3 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface)endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posy = y + scale(node.editor.line_height)*#node.editor.line_cache[i].screen_line_starting_posprint('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)endreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('creating text of size', scaled_fontsize)obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('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)endreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
while #Surface > 3 dotable.remove(Surface)endprint('code changed', Page.x,Page.y)compute_layout(Page, Page.x,Page.y, Surface)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('updating editor', obj.data[1])obj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0elseif Cursor_node thenendendedit.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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeprint('setting font', scaled_fontsize)love.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
while #Surface > 3 dotable.remove(Surface)endprint('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)endon.code_change = function()
while #Surface > 3 dotable.remove(Surface)endprint('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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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 textprint(x,y, node.data[1])node.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
while #Surface > 3 dotable.remove(Surface)endprint('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)endon.code_change = function()
on.draw = function()love.graphics.setColor(1,0,0)for y=0,1000,100 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor x=0,1000,100 dolove.graphics.line(vx(x),vy(-5), vx(x),vy(5))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
while #Surface > 3 dotable.remove(Surface)endprint('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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
print('code changed')while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
Page = {-- pagetype='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 dotable.remove(Surface)endcompute_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)endon.code_change = function()
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
if Cursor_node thenendendedit.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 dolove.graphics.line(vx(-5),vy(y), vx(5),vy(y))endfor _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0elseif Cursor_node thenendendedit.keychord_press(Cursor_node.editor, chord, key)on.keychord_press = function(chord, key)
if Pan thenPan = nilelseif Cursor_node thenendendedit.mouse_release(Cursor_node.editor, x,y, mouse_button)on.mouse_release = function(x,y, mouse_button)
if Cursor_node thenCursor_node.show_cursor = nilCursor_node = nilendlocal node = to_text(x,y)if node thenCursor_node = nodenode.show_cursor = trueelsePan = {x=Viewport.x+x,y=Viewport.y+y}endendedit.mouse_press(node.editor, x,y, mouse_button)on.mouse_press = function(x,y, mouse_button)
local node = to_text(x,y)if node thenCursor_node = nodenode.show_cursor = trueelsePan = {x=Viewport.x+x,y=Viewport.y+y}endendedit.mouse_press(node.editor, x,y, mouse_button)on.mouse_press = function(x,y, mouse_button)
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endassert(obj.w)edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
if Pan thenPan = nilelselocal node = to_text(x,y)if node thenendendendedit.mouse_release(node.editor, x,y, mouse_button)on.mouse_release = function(x,y, mouse_button)
if Pan thenPan = nilelselocal node = to_text(x,y)if node thenendendedit.mouse_release(node.editor, x,y, mouse_button)on.mouse_release = function(x,y, mouse_button)
Page = {-- pagetype='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 thennode.show_cursor = trueprint('show cursor')elseprint('pan')Pan = {x=Viewport.x+x,y=Viewport.y+y}endendedit.mouse_press(node.editor, x,y, mouse_button)on.mouse_press = function(x,y, mouse_button)
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolove.graphics.line(obj.editor.left,vy(y), obj.editor.right,vy(y))endendendendend
local node = to_text(x,y)if node thennode.show_cursor = trueprint('show cursor')elseprint('pan')Pan = {x=Viewport.x+x,y=Viewport.y+y}endendon.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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenprint('initializing editor')obj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeinitialize_editor(obj)print('updating editor', obj.editor)endprint('editor', obj.editor)edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
local node = to_text(x,y)if node thennode.show_cursor = trueelsePan = {x=Viewport.x+x,y=Viewport.y+y}endendon.mouse_press = function(x,y, mouse_button)
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolove.graphics.line(obj.editor.left,y, obj.editor.right,y)endendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
on.draw = function()print('on.draw')for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenprint('initializing editor')obj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeinitialize_editor(obj)print('updating editor', obj.editor)endprint('editor', obj.editor)edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolocal y = obj.y + obj.editor.line_cache[i].startylove.graphics.line(obj.editor.left,y, obj.editor.right,y)endendendendend
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 textprint(x,y, node.data[1])node.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 15)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
on.draw = function()print('on.draw')for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeinitialize_editor(obj)print('updating editor', obj.editor)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)endendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolocal y = obj.y + obj.editor.line_cache[i].startylove.graphics.line(0,y, 800,y)endendendendend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)print('node editor', node.editor)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
Page = {-- pagetype='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 dotable.remove(Surface)endcompute_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)endon.code_change = function()print('on.code_change')
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolocal y = vy(obj.editor.line_cache[i].starty)love.graphics.line(0,y, 800,y)endendendendend
Page = {-- pagetype='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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeinitialize_editor(obj)print('updating editor', obj.editor)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizelove.graphics.setFont(font(scaled_fontsize))obj.text = love.graphics.newText(love.graphics.getFont(), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.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 dolocal y = vy(obj.editor.lines[i].starty)love.graphics.line(0,y, 800,y)endendendendend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('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)endreturn yend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)print('node editor', node.editor)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
Page = {-- pagetype='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 textlocal 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)endend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)print(node.editor)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textlocal 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)endend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.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 textprint(x,y, node.data[1])node.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('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)endreturn yend
while #Surface > 3 dotable.remove(Surface)endcompute_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)endon.code_change = function()
while #Surface > 3 dotable.remove(Surface)endlocal 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)endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)Text.clear_screen_line_cache(node.editor, i)endreturn yend
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},}endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)Text.clear_screen_line_cache(node.editor, i)endreturn yend
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},}endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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 textprint(node.data[1])node.x = xnode.y = y-- render background if necessarylocal node_to_renderif node.bg thennode_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 contentsif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)if node_to_render thennode_to_render.w = node.wnode_to_render.h = node.hendelseif node.type == 'rows' thennode.x = xnode.y = ylocal node_to_renderif node.bg thennode_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 bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal node_to_renderif node.bg thennode_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)endlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node_to_render thennode_to_render.w = wnode_to_render.h = hendendreturn x+node.w,y+node.hend
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},}endon.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},}endon.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},}endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posprint('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)Text.clear_screen_line_cache(node.editor, i)endreturn yend
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},}endon.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},}endon.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},}endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posText.clear_screen_line_cache(node.editor, i)print('height', i, node.editor.line_height, #node.editor.line_cache[i].screen_line_starting_pos, y)endreturn yend
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},}endon.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},}endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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},}endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posText.clear_screen_line_cache(node.editor, i)print('height', i, y)endreturn yend
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)endon.code_change = function()
Page = {-- pagetype='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)endon.code_change = function()
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posText.clear_screen_line_cache(node.editor, i)print('height', i, y)endreturn yend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.w = 0for _,s in ipairs(node.data) dolocal text = love.graphics.newText(font(node, scaled_fontsize), node.data)local width = text:getWidth()if node.w < width then node.w = width endendendinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
Page = {-- pagetype='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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal 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()endinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
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)endon.code_change = function()
Page = {-- pagetype='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 = {-- pagetype='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)endon.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)endon.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)endon.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)endon.code_change = function()
on.update = function(dt)if Pan thenendif App.mouse_down(1) thenclip_all()endendViewport.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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal 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()endinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
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')endon.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}endon.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)endon.code_change = function()
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) doprint(obj.type, obj.data)love.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1elseif chord == 'C-0' then-- reset zoomViewport.zoom = 1.0endendon.keychord_press = function(chord, key)
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1elseif chord == 'C--' then-- zoom outViewport.zoom = Viewport.zoom-0.1endendon.keychord_press = function(chord, key)
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1endendon.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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)node.w = node.text:getWidth()endinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = hif node.bg thentable.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})endelseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hif node.bg thentable.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})endendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)node.w = node.text:getWidth()endinitialize_editor(node)node.h = box_height(node)table.insert(nodes_to_render, node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)node.w = node.text:getWidth()endinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
Page = {-- pagetype='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 = {-- pagetype='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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)node.w = node.text:getWidth()endinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = yif node.width thennode.w = node.widthelselocal scaled_fontsize = scale(node.fontsize or 20)node.text = love.graphics.newText(font(node, scaled_fontsize), node.data)node.w = node.text:getWidth()endinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
on.draw = function()for i,obj in ipairs(Surface) doprint(i, obj.type)love.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeobj.text = love.graphics.newText(font(obj, scaled_fontsize), obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = dom.compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = dom.compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
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 textnode.x = xnode.y = ynode.w = node.widthinitialize_editor(node)node.h = box_height(node)elseif node.type == 'rows' thennode.x = xnode.y = y-- lay out children top to bottomlocal subx,suby = x,ylocal w,h = 0,0local subnodesfor _,child in ipairs(node.data) doif child.margin thensuby = suby+child.marginh = h+child.marginendsubx,suby = dom.compute_layout(child, x,suby, nodes_to_render)if w < child.w thenw = child.wendh = h+child.hendnode.w = wnode.h = helseif node.type == 'cols' thennode.x = xnode.y = y-- lay out children left to rightlocal subx,suby = x,ylocal w,h = 0,0for _,child in ipairs(node.data) doif child.margin thensubx = subx+child.marginw = w+child.marginendsubx,suby = dom.compute_layout(child, subx,y, nodes_to_render)w = w + child.wif h < child.h thenh = child.hendendnode.w = wnode.h = hendreturn x+node.w,y+node.hend
on.draw = function()for i,obj in ipairs(Surface) doprint(i, obj.type)love.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint(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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint(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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
Page = {-- pagetype='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 textlocal 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)endend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)initialize_editor(obj)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
initialize_editor = function(obj)if obj.w then-- use an editor to wrap the textobj.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)endend
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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)if obj.w then-- use an editor to wrap the textobj.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)endendif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)if obj.w then-- use an editor to wrap the textobj.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)endendif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
compute_layout = function(node, x,y)if node.type == 'text' and node.width thennode.x = xnode.y = ynode.w = node.widthnode.h = box_height(node)endreturn nodeend--[[edit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorend]]
compute_layout = function(node, x,y)if node.type == 'text' and node.width thennode.x = xnode.y = ynode.editor = edit.initializenode.editor.top = ynode.editor.left = xnode.editor.right = x + node.wnode.w = node.widthnode.h = box_height(node)endreturn nodeend--[[if obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorend]]
compute_layout = function(node, x,y)if node.type == 'text' and node.width thennode.x = xnode.y = ynode.editor = edit.initializenode.editor.top = ynode.editor.left = xnode.editor.right = x + node.wnode.w = node.widthnode.h = dom.height(node)endreturn nodeend--[[local scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorend]]
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
compute_layout = function(node, x,y)if node.type == 'text' and node.width thennode.x = xnode.y = ynode.editor.top = ynode.editor.left = xnode.editor.right = x + node.wnode.w = node.widthnode.h = dom.height(node)endreturn nodeend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenprint('rendering', obj.data)local scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
compute_layout = function(node, x,y)if node.type == 'text' and node.width thennode.x = xnode.y = ynode.editor.top = ynode.editor.left = xnode.editor.right = x + node.wnode.h = dom.height(node)endreturn nodeend
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 thennode.x = xnode.y = ynode.editor.top = ynode.editor.left = xnode.editor.right = x + node.wnode.h = dom.height(node)endend
box_height = function(node)local y = 0for i=1,#node.editor.lines dolocal line = node.editor.lines[i]if node.editor.line_cache[i] == nil thennode.editor.line_cache[i] = {}endnode.editor.line_cache[i].fragments = nilnode.editor.line_cache[i].screen_line_starting_pos = nilText.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_posText.clear_screen_line_cache(node.editor, i)endreturn yend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endif obj.w == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endif obj.width == nil thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))else-- use an editor to wrap the textlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, true) -- hide cursorendendendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'edit' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endendend
Page = {-- pagetype='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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseif obj.type == 'edit' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()endelseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))love.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal 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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
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) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endprint(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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.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)endedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0})endendend
on.draw = function()for _,obj in ipairs(Surface) dolove.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)if obj.type == 'rectangle' thenlove.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.width),scale(obj.height))elseif obj.type == 'line' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endendlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'circle' thenlove.graphics.circle(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radius))elseif obj.type == 'arc' thenlove.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' thenlove.graphics.ellipse(obj.drawmode or 'fill', vx(obj.x), vy(obj.y), scale(obj.radiusx), scale(obj.radiusy))elseif obj.type == 'bezier' thenif obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.zdata = love.math.newBezierCurve(zdata):render()elseif obj.type == 'text' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))endendend
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 = {-- pagex=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 = {-- pagex=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 thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yobj.zdata = {}for i=1,#obj.data,2 dotable.insert(obj.zdata, vx(obj.data[i]))table.insert(obj.zdata, vy(obj.data[i+1]))endend
if obj.saved_zoom ~= Viewport.zoom or obj.saved_x ~= Viewport.x or obj.saved_y ~= Viewport.y thenobj.saved_zoom = Viewport.zoomobj.saved_x = Viewport.xobj.saved_y = Viewport.yzdata = {}for i=1,#obj.data,2 dotable.insert(zdata, vx(obj.data[i]))table.insert(zdata, vy(obj.data[i+1]))endobj.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 thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endobj.text = love.graphics.newText(Font[scaled_fontsize], obj.data)endlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))endlove.graphics.line(unpack(obj.zdata))elseif obj.type == 'edit' thenlocal scaled_fontsize = scale(obj.fontsize or 20)if obj.editor == nil or obj.scaled_fontsize ~= scaled_fontsize thenobj.scaled_fontsize = scaled_fontsizeif Font == nil then Font = {} endif Font[scaled_fontsize] == nil thenFont[scaled_fontsize] = love.graphics.newFont(scaled_fontsize)endprint(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 thenlove.graphics.draw(obj.text, vx(obj.x), vy(obj.y))elseedit.draw(obj.editor, obj.fg or {r=0,g=0,b=0}, not obj.show_cursor)
This file contains no definition, but is used as a marker in the save dir toindicate 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.