Editors also have some padding within their borders.
6C3UZDESM2HPFIHAW5YIPUV6VXO4YV5DIEY574HUGP2DGOQNUVOAC ZV5ZL57L2M3Y4PQCAZDS44YMTASLVJZYDTEFSIMBQE5R7PJR2LHAC AZS44H5MHGCREAQDHLCKHLN7CATGCGO2V4SZ6ZNLXEGYGIFUKDMQC YFQRJ4EYPIIUN26G4XKLAXK4YHJ54IKUDI272U4UT6BP2JEXWK6QC UGWH4VEHN5G6REWZU6BCXZ57AFU7PGK4MULMMHMJCMEMVVEDH2KAC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC O5GJ6PNNBYHH4X3DU4XOB7IDJ4QEW5KXFETIDUJESBUKJYXBSYYAC 7TQAF4BYIK75EEYCCK7VEUSZHNCWMWIA3HZGQKIILYESUZ5ZZRVQC AKQBXWCVTZ5LEG76QW54B7MHXYFA7GD2Y2GSEN7RUXO5CHMYCZKAC JIBCE66ZTWM5WEHEHNKKTRWBJQSQWBDDWPMOJIJR5Q676OSHYCNAC SUPHTPXYKS4JBDPASHAYA5OBVJ45QT7ZV2HYNTF7OJYOKKS6DW5QC BF7TW3EKRIDYC6J2Q2J4YOBAVQF55Y3H6KGZIHNXMH4N72MR6GXQC TBPJ5WSRM5IKQH7FTAVYTWWUBWW7G2CLT5M6FN7CMPLD6Y77YIWQC OLCKKDVSDTIBX5U3IRCLRL6KQMG2RDWKGDN4OTPI3WMN4FSX6ROQC FBDRJ53NJ5BWDQGU2GWZ6NEYHKCCRD7RODMIG7QQZBRFUB4HR7OAC ZANGJNNX6EITFBOF6NWCF2EM5BDQDEIOD4UPWMF5I6SKAURRTIHAC X7HYGAL2QVKG7M5EMZ2VSH37UYWGE3EPUXYQBJOVL6IGJFZ2I5AAC JE6PEYCDKZAOTTEWA35OZ2YGAEAWNHMAPCRPDI4ZV5H3NAVQVCSQC XCEP7G5GRX6WQGCROJDNZRTLSITGAETL7EFCFTR74S36VXK32HBQC DXFOMHQIWZ6EAUIDZQLY3ZRRDWJRB2VQHJXHBBNXQYCYCABIMJ5QC initialize_global_viewport = function()local minx, miny, maxx, maxy = surface_bounds(Definitions)-- ensure 1px of white background all around-- just in case the viewport ever goes-- outside canvas bounds while animatingminx,miny, maxx,maxy = minx-1,miny-1, maxx+2,maxy+1local zoomx = App.screen.width/(maxx-minx)local zoomy = App.screen.height/(maxy-miny)local zoom, cw, chif zoomx < zoomy thenzoom = zoomxcw = maxx-minxch = cw*App.screen.height/App.screen.widthelsezoom = zoomych = maxy-minycw = ch*App.screen.width/App.screen.heightendGlobal_viewport = {x=minx, y=miny, w=cw, h=ch, zoom=zoom}end
survey_animation = function()---[[ '--' at start to disable animation, '---' to enablelocal minx, miny, maxx, maxy = surface_bounds(Definitions)-- ensure 1px of white background all around-- just in case the viewport ever goes-- outside canvas bounds while animatingminx,miny, maxx,maxy = minx-1,miny-1, maxx+2,maxy+1local zoomx = App.screen.width/(maxx-minx)local zoomy = App.screen.height/(maxy-miny)local zoom, cw, chif zoomx < zoomy thenzoom = zoomxcw = maxx-minxch = cw*App.screen.height/App.screen.widthelsezoom = zoomych = maxy-minycw = ch*App.screen.width/App.screen.heightendGlobal_viewport = {x=minx, y=miny, w=cw, h=ch, zoom=zoom}snapshot_canvas()-- initialize animationAnimating = {copy_viewport(Global_viewport),copy_viewport(Viewport),}Viewport.x = -App.screen.width/2Viewport.y = -App.screen.height/2Viewport.w = App.screen.widthViewport.h = App.screen.heightViewport.zoom = 1.0 --]]end
on.code_submit = function(editor)if not editor.load_time_error thenManifest_navigator.reload = trueend-- update definition backgrounds of failing testsfor name,node in pairs(Definitions) do-- ignore temporary definitions with numeric indices; they haven't been saved yetif type(name) == 'string' and starts_with(name, 'test_') thenif Client_app_test_failures[name] thennode.bg = Failing_test_definition_background_colorelsenode.bg = Test_definition_background_colorendendendA()endnode.editor.load_time_error = nilnode.editor.load_time_error = Client_app_test_failures[name]
zoom_in = function(x,y)-- precondition: Zoomed_out-- precondition: Viewport == Global_viewport-- precondition: Save_viewport exists-- center Viewport on x,y at zoom level Saved_viewport.zoomsnapshot_canvas()Animating = {{x=sx(x)-App.screen.width/Save_viewport.zoom/2,y=sy(y)-App.screen.height/Save_viewport.zoom/2,w=App.screen.width/Save_viewport.zoom,h=App.screen.height/Save_viewport.zoom,zoom=Save_viewport.zoom,},}Zoomed_out = nilSave_viewport = nilend
animate_next_frame = function(state, dt)if state.initial == nil thenstate.initial = from_viewport(state)-- once we've checked keys, pollute the keyspacestate.step = 0state.frame_time = 0returnendstate.frame_time = state.frame_time + dtif state.frame_time > 0.01 thenstate.frame_time = state.frame_time - 0.01state.step = state.step+1interpolate_viewport(state.initial, state, state.step)B()endend
animate_next = function(dt)if Animating[1].step and Animating[1].step >= Num_animation_frames thentable.remove(Animating, 1)if #Animating == 0 thenAnimating = nilCanvas = nilA()returnendendanimate_next_frame(Animating[1], dt)end
snapshot_canvas = function()-- Render the canvas at pixel perfect resolution.local winw,winh = App.screen.width, App.screen.heightApp.screen.width,App.screen.height = Global_viewport.w, Global_viewport.hlocal saved_viewport = ViewportViewport = copy_viewport(Global_viewport)Viewport.zoom = 1.0A()Canvas = love.graphics.newCanvas(Global_viewport.w, Global_viewport.h)love.graphics.setCanvas(Canvas)App.fake_key_press = true -- Hack; disable drawing the menu and tickson.draw()App.fake_key_press = nillove.graphics.setCanvas()Viewport = saved_viewportApp.screen.width,App.screen.height = winw,winhend
zoom_out = function()Save_viewport = copy_viewport(Viewport)snapshot_canvas()Animating = {copy_viewport(Global_viewport),}Zoomed_out = trueendinitialize_global_viewport()
interpolate_viewport = function(initial, final, step)for k,v in pairs(initial) doViewport[k] = (initial[k]*(Num_animation_frames - step) + final[k]*step) / Num_animation_framesendend
Animating = nil -- set this to enable animation-- When enabled, animation should consist of a series of viewport states that we animate into.-- Each viewport state will be attained in Num_animation_frames frames, each of 0.01 ms or 1 Love frame.-- Each state will specify the final state of various viewport keys. Keys not mentioned will remain unchanged.
draw_manifest_navigator = function()App.color(Menu_command_color)local filter_text = to_hud_text(Manifest_navigator.filter)App.screen.draw(filter_text, 5, 5)draw_cursor(5 + filter_text:getWidth(), 5)App.color(Menu_background_color)love.graphics.rectangle('fill', 0,Menu_bar_height, App.screen.width, Manifest_navigator.num_lines * (HUD_line_height + --[[highlight padding]]5))local x,y = 5, Menu_bar_heightfor i,definition in ipairs(Manifest_navigator.candidates) dox,y = add_def_to_menu(x,y, definition, i == Manifest_navigator.index)if Menu_cursor >= App.screen.width - 5 thenbreakendendManifest_navigator.bottom_y = y + HUD_line_height + --[[highlight padding]] 5end
on_handle = 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/2-5) thenif y >= vy(node.y-30) and node.h and y < vy(node.y-10) thenreturn nodeendendendendend
maybe_update_key_in_definitions = function(old_definition_name, definition_name, Cursor_node)--print(old_definition_name, definition_name)if old_definition_name ~= definition_name thenif old_definition_name == nil or Definitions[old_definition_name] ~= Cursor_node thenlocal pos = array.find(Definitions, Cursor_node)--print('found at index', pos)assert(pos)table.remove(Definitions, pos)elseif Definitions[old_definition_name] == Cursor_node then--print('found at key', old_definition_name)Definitions[old_definition_name] = nilendif definition_name and Definitions[definition_name] == nil then--print('moving to key', definition_name)Definitions[definition_name] = Cursor_nodeelseif definition_name == nil or Definitions[definition_name] then-- temporary collision; try again later-- deleting and reinserting is inefficient, but hopefully rare--print('moving to index', #Definitions+1)table.insert(Definitions, Cursor_node)end--print('-- definition keys')--for k in pairs(Definitions) do--print(k)--endendend
if Manifest_navigator.show thendraw_manifest_navigator()returnendif Zoomed_out == nil thenadd_hotkey_to_menu('ctrl+g: zoom out')elseadd_hotkey_to_menu('ctrl+g: undo zoom out')endadd_hotkey_to_menu('ctrl+l: load definition')add_hotkey_to_menu('ctrl+n: new definition')add_hotkey_to_menu('ctrl+d: delete definition')
if Animating thenlocal q = love.graphics.newQuad((Viewport.x-Global_viewport.x)*Viewport.zoom,(Viewport.y-Global_viewport.y)*Viewport.zoom, App.screen.width, App.screen.height, Global_viewport.w*Viewport.zoom, Global_viewport.h*Viewport.zoom)App.color{r=1,g=1,b=1}love.graphics.draw(Canvas, q, 0,0)returnend
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h), scale(obj.rx or 2), scale(obj.ry or 2))
love.graphics.rectangle(obj.drawmode or 'fill', vx(obj.x),vy(obj.y), scale(obj.w),scale(obj.h), scale(obj.rx or 5), scale(obj.ry or 5))
elseif chord == 'C-n' thennew_definition()A()elseif chord == 'C-l' thenManifest_navigator.show = trueManifest_navigator.for_delete = falseinitialize_manifest_navigator()elseif chord == 'C-d' thenManifest_navigator.show = trueManifest_navigator.for_delete = trueinitialize_manifest_navigator()
node_to_render = {type='rectangle', drawmode='line', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x, y=node.y, key=node.key}
node_to_render = {type='rectangle', drawmode='line', r=node.bg.r, g=node.bg.g, b=node.bg.b, x=node.x-5, y=node.y-5, key=node.key}
local node = on_handle(x,y)if node then-- move nodeMove = {xoff=App.mouse_x()-vx(node.x), yoff=App.mouse_y()-vy(node.y), node=node}returnend