J62CVGNGJZSN7TMTE2SG53O47YG4SJGJFTUFKVOZY4TM4KAC566QC AB5WZZKYX4HAWSO25E7DPU2DTAE2TWY3HOZE6V74OF5SQDMYZC7AC QSFUGJRQ3I6WMKXUPY6TYMTGWDVONXY7A3EJ4SH5E32DEZFA5B4AC QXJ3HUDHKPVZNC4LF6IC5VWQWDT7XRKASM2PLFMTSM3NGJKSHDPQC S5KEQNTQJ5K5NS2NZUQ37SKQM6XOVI5OHLZUGBED553RPCHJ3KQQC NDP75JUBOFE5AWPWGNMCZUOTLM4CYXG3WHOSEFJPPSS4QNLG5CKQC VYVZXEKURUING6SYXEB2LP4QQSSM3II7JZ5ZMGC2BF2LWTMXYONAC MFBZCXOUHS7ELP3SRTA7VDO32CUSRDIX44LXSMBPIAE5JXKFWXOQC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC WA5RXMGA4V7BAL3QEW6BNYCOM4BAGKZJCKBZWCXYBC2VLDV7Z27QC JBYPLGW2C3JYDIEYAUIRYGI33CWQJXUW2BTXYQWVK7FNMAL6FGUAC VF2FRNK5O53KGL47ECLLXIF6PKX4ZMH54WALEKLNPVNDPUTLLUMQC XH2FW3YDKFHC6KKCAJ5LE6EAEUUJZ23BIGNYG37PMUPHFW5KTFKAC EHVOKKDTAH4ED432LZCX2Y4BK63BP6YAIL2U7WXWBNWJRIACY7WQC ACEWU2ORP2QPYQQL2MXWLOQGAG4XBU5YWOO57K6KJBPJU4VDNH5AC C3DUID2HUFDX5WXG4YZX2TUHJ5OBVEAOPSBUSGZTJW7RB4SGK46QC U4DYD4L2LZQ4U4ZNBVA4E5DMHCWTF25A6Q4GS35B3FKB74MPIQ4AC CKGWLO67CSR67ZO6CZAICVAC4FNCO2QBQWOBQA6CU6ISUAXLBDYAC OZNETUSGD7GQD3XDGBFEQBSXYE4UM6G5D6OBFVNQW3XLJERHU5WQC 6QK4TD73S6BE3KJGEZG2APZKSPENEZSJ22EZUTL5GFQEJ6EBXEDQC 35W3XPSDT72C3DGWNEWRF5A42SV6PDQ3ZAWVGCA3U42EYWDVKK7QC U3YIPNIJ6JBWKXZOKDFZFUDL3USFDIMDDVGP2JZMXGPZQ7ELKF6QC YUQ4YINAT5YTK3CAY4VK3HSYQ4D63FXLLPMC4R3DUFHIZIUQO7WQC S4QPRGGMVRDOB5FINBVTWSXMSOX4HA2GPRFQ5UIXRHTIHUUGZIZQC 3MH6NUDYVAVUVGBI6KC3P4FVNKBJ6EIHC2H5UPLEVGTIZJDGYCRQC UJ2RZ43LIVRIBWIXHXMLIQIQTL32VVEN4CVU7PEBTITQFPO4EXXQC 4GXHYH5IYHUBCNQVJMXYJMVU5BF6C6TEOQEMGFFYYAL7GRCZX4XQC 2GOAQOS3LSYMBT2H6SFEN23EV6F47BDQQY2G2IENB5CGE6SF7PKAC NNIKYLOXQHZ6TZ7SDOA2OPNVTBJGNZRVXPVFLUTKIABM7XPAPB5AC HJQFU6IFL4WBNSG4KINMYAWNYE7GEPCXW7FM5CLNLFFA46QHTQKAC K3TL4FPX65XC7EKRQEF4YYZVVP242NRSR4BGGBJ4H5LXVLN44ECAC GMDEH4RHOR6DJABQ5WVGY4GVUU3QPWFTPFUHYUOULTVJZA2FTPAQC LFAROW2YSPM7534MX4G4BM6GSIHEQWQJH4QTGP4EGYQKRX5FP27AC FS2ITYYHBLFT66YUC3ENPFYI2HOYHOVEPQIN7NQR6KF5MEK4NKZAC 5TDFTJBI6I633A4W2NWMMP3YRYOTLRSBJU7XBU5H45UETXSPGSBQC to_text = function(x,y)for _,node in ipairs(Surface) doif node.type == 'text' thenif 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
{"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 = 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)endnode.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.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
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)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
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=#editor.lines+1, pos=1}, y_offset -- positive valueend
{"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}
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()
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
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
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 = 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,"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}
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)B()elseif chord == 'down' thenViewport.y = Viewport.y + scale(20)B()elseif chord == 'left' thenViewport.x = Viewport.x - scale(50)B()elseif chord == 'right' thenViewport.x = Viewport.x + scale(50)B()elseif chord == 'pageup' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomB()elseif chord == 'S-up' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomB()elseif chord == 'pagedown' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomB()elseif chord == 'S-down' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomB()elseif chord == 'S-left' thenViewport.x = Viewport.x - App.screen.width/Viewport.zoomB()elseif chord == 'S-right' thenViewport.x = Viewport.x + App.screen.width/Viewport.zoomB()endendend
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)endA(--[[preserve screen_top of cursor node]] true)endend
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,g=0.8,b=0}}
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
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'},},}},}},}},},}
{"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}
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
{"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}
y_of_schema1 = function(editor, loc)local result = 0if loc.line == 1 and loc.pos == 1 thenreturn resultendfor i=1,loc.line-1 doText.populate_screen_line_starting_pos(editor, i)result = result + line_height(editor, i)endText.populate_screen_line_starting_pos(editor, loc.line)for i,screen_line_starting_pos in ipairs(editor.line_cache[loc.line].screen_line_starting_pos) doif screen_line_starting_pos >= loc.pos thenbreakendresult = result + editor.line_heightendreturn resultend
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
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
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
{"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}
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'},},}},}},}},},}
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
{"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}
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
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
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'},},}},}},}},},}
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
{"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}
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
{"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}
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
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
{"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}
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
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}}
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
{"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}
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
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
{"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}
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)compute_layout(Page2, Page2.x,Page2.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
{"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}
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(node, 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
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
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
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
{"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}
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.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
{"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}
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 = 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
{"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}
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 = 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.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
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
{"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}
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
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.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
{"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 = 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
{"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}
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.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}}
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 = 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 = 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
{"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}
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
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 = {-- 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}},}
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)
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
{"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}
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 = 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
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'},},}},}},}},},}
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}},}
{"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}
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
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
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}}
{"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}
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 = 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
{"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}
Surface = {-- test data{type='line', data={0,-1000, 0,1000}},{type='line', data={-10000,0, 10000,0}},{type='text', data={'0'}, x=-20,y=-30},{type='rectangle', x=50,y=50, w=20,h=80, r=1,g=0,b=0},{type='text', data={'abc', 'def'}, x=150, y=50, w=50,h=50, fg={r=0,g=0.4, b=0.9}},{type='circle', x=300,y=200, radius=40, r=1,g=0,b=1},{type='arc', x=0,y=0, radius=50, angle1=0, angle2=math.pi*2/3},{type='ellipse', x=100,y=100, radiusx=10, radiusy=50},{type='bezier', data={25,25, 25,125, 75,25, 125,25}},}
print('code changed')A() -- just in case we edited Pageendon.code_change = function()
{"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}
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
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
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
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
{"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}
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
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
{"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}
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
{"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 = 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
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}},}
{"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}
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))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
{"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}
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 = 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
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
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}},}
{"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}
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
{"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}
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
{"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}
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
on.update = function(dt)if Pan thenB()endendViewport.x = Pan.x - App.mouse_x()/Viewport.zoomViewport.y = Pan.y - App.mouse_y()/Viewport.zoom
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
{"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}
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
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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
{"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}
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
{"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.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
{"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}
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
{"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}
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.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}
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
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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
{"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}
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
{"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}
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
{"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}
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":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}
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
{"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}
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
{"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}
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
{"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}
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
{"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}
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":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 = 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'},},}},}},}},},}
{"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}
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
{"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}
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":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}
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
{"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}
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":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 = 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
{"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}
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
{"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}
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":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}
add_thick_line = function(s, thickness)-- increase the thickness of a horizontal-ish linetable.insert(Surface, s)for i=1,thickness-1 dos = copy_shape(s)for j=2,#s.data, 2 dos.data[j] = s.data[j]+1endtable.insert(Surface, s)endend
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
{"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}
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
{"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}
{"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}
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.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}
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
{"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}
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.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.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
{"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}
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.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}
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.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.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
{"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}
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
{"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}
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
{"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}
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
{"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}
{"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}
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
{"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}
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.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}
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()
{"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}
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
{"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}
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
{"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}
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.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}
{"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.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
{"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}
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
{"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}
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
{"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}
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.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}
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.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.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.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}
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
{"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}
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.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.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
{"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}
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.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}
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
{"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}
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()
{"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}
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'},},}},}},}},},}
{"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}
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()
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":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}
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()
{"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}
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 thenCursor_node.show_cursor = nilCursor_node = nilendlocal node = to_text(x,y)if node thenCursor_node = nodeelseendendPan = {x=Viewport.x+x/Viewport.zoom,y=Viewport.y+y/Viewport.zoom}edit.mouse_press(node.editor, x,y, mouse_button)on.mouse_press = function(x,y, mouse_button)
{"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}
if Pan thenPan = nilelseif Cursor_node thenCursor_node.show_cursor = trueendendedit.mouse_release(Cursor_node.editor, x,y, mouse_button)on.mouse_release = function(x,y, mouse_button)
{"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}
if Cursor_node thenendendedit.text_input(Cursor_node.editor, t)on.text_input = function(t)
{"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}
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)
{"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}
if Pan thenPan = nilelseif Cursor_node thenendendedit.mouse_release(Cursor_node.editor, x,y, mouse_button)on.mouse_release = function(x,y, mouse_button)
{"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}
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)
{"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}
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
{"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}
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)
{"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}
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)
{"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}
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
{"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}
{"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}
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}},}
{"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}
{"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}
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
{"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}
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
{"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}
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
{"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}
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
{"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.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
{"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}
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.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}
{"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.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
{"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}
{"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}
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.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.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
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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
{"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}
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.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.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.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.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
{"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}
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'},},}},}},}},},}
{"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}
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()
{"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}
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()
{"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}
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
{"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}
{"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}
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
{"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}
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()
{"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}
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
{"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}
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":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}
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
{"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}
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()
{"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}
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()
{"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}
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
{"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}
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
{"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}
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()
{"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}
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.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}
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
{"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}
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.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}
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.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}
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()
{"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}
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()
{"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}
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
{"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}
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'},},}},}},}},},}
{"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}
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()
{"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}
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
{"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}
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
{"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}
{"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}
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'},},}},}},}},},}
{"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}
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()
{"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}
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'},},}},}},}},},}
{"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}
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()
{"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}
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()
{"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}
{"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}
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()
{"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}
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()
{"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}
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()
{"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}
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":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}
{"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}
{"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 = 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":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}
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
{"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}
{"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}
{"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.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}
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)
{"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":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}
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)
{"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}
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
{"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}
{"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}
if chord == 'C-=' then-- zoom inViewport.zoom = Viewport.zoom+0.1endendon.keychord_press = function(chord, key)
{"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}
{"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":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}
{"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}
{"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}
{"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}
{"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}
{"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}
{"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}
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}},}
{"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}
{"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}
{"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}
{"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}
{"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.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.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}
{"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}
{"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}
{"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}
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
{"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.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}
{"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}
{"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}
{"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}
{"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}
{"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}
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
{"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}
{"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}
{"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}
{"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}
{"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}
{"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()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
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
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
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,},}},}},}},},}
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)endnode.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
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,g=0.8,b=0}}
A = function(preserve_screen_top_of_cursor_node)-- translate Page to Surfacewhile #Surface > 0 do table.remove(Surface) 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
{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='line', data={0,-1000, 0,1000}},{type='line', data={-10000,0, 10000,0}},{type='text', data={'0'}, x=-20,y=-30},{type='rectangle', x=50,y=50, w=20,h=80, r=1,g=0,b=0},
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)
add_thick_line = function(s, thickness)-- increase the thickness of a horizontal-ish linetable.insert(Surface, s)for i=1,thickness-1 dos = copy_shape(s)for j=2,#s.data, 2 dos.data[j] = s.data[j]+1endtable.insert(Surface, s)endend
copy_shape = function(s)local result = {}for k,v in pairs(s) doresult[k] = vendresult.data = {}for _,d in ipairs(s.data) dotable.insert(result.data, d)endreturn resultend
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)B()elseif chord == 'down' thenViewport.y = Viewport.y + scale(20)B()elseif chord == 'left' thenViewport.x = Viewport.x - scale(50)B()elseif chord == 'right' thenViewport.x = Viewport.x + scale(50)B()elseif chord == 'pageup' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomB()elseif chord == 'S-up' thenViewport.y = Viewport.y - App.screen.height/Viewport.zoomB()elseif chord == 'pagedown' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomB()elseif chord == 'S-down' thenViewport.y = Viewport.y + App.screen.height/Viewport.zoomB()elseif chord == 'S-left' thenViewport.x = Viewport.x - App.screen.width/Viewport.zoomB()elseif chord == 'S-right' thenViewport.x = Viewport.x + App.screen.width/Viewport.zoomB()endendend
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)endA(--[[preserve screen_top of cursor node]] true)endend
Page = {type='text', x=0, y=0,name='editor',doc='prose goes here, on the left half of the window',margin=Margin_left,data={"Lorem Ipsum",'1','2','3','mno','Acb','g','hij','klm','nop',},width=400,}
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
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=#editor.lines+1, pos=1}, y_offset -- positive valueend
line_height = function(editor, line_index)local line = editor.lines[line_index]local line_cache = editor.line_cache[line_index]return editor.line_height*#line_cache.screen_line_starting_posend
y_of_schema1 = function(editor, loc)local result = 0if loc.line == 1 and loc.pos == 1 thenreturn resultendfor i=1,loc.line-1 doText.populate_screen_line_starting_pos(editor, i)result = result + line_height(editor, i)endText.populate_screen_line_starting_pos(editor, loc.line)for i,screen_line_starting_pos in ipairs(editor.line_cache[loc.line].screen_line_starting_pos) doif screen_line_starting_pos >= loc.pos thenbreakendresult = result + editor.line_heightendreturn resultend
on.initialize = function()A()end
obj.editor = edit.initialize_state(vy(obj.y), vx(obj.x), vx(obj.x+obj.w), scaled_fontsize, math.floor(scaled_fontsize*1.3))
local scaled_fontsize = scale(20)local scaled_lineheight = math.floor(scaled_fontsize*1.3)obj.editor = edit.initialize_state(vy(obj.y), math.floor(vx(obj.x)), math.ceil(vx(obj.x+obj.w)), scaled_fontsize, scaled_lineheight)
Viewport = {x=-50, y=-50, w=800,h=600, zoom=1.0}
to_text = function(x,y)for _,node in ipairs(Surface) doif node.type == 'text' thenif 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
on.mouse_press = function(x,y, mouse_button)if Cursor_node thenCursor_node.show_cursor = nilCursor_node = nilendlocal node = to_text(x,y)if node thenCursor_node = nodeedit.mouse_press(node.editor, x,y, mouse_button)elsePan = {x=Viewport.x+x/Viewport.zoom,y=Viewport.y+y/Viewport.zoom}endend
Cursor_node = nil
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.