No functionality yet, but its font size is independent of zoom.
I've pulled in all the commands from the previous driver, but they will require tuning for this repo. Lots of basic assumptions will differ.
GT3XZRTCVBWCSWUXAJ7N4OK2U2G5Y7EGSC5YE76KXZG7C4L53VTQC OWBGSQM3PQWLWZ55GKXM6YA2B626GTCYKZTAUPQZ2F62KNFDJX2QC MQMKQ2JO6E3KDJN3H6WACIETJI4C2APUS5N4YQZDM75ZIZDSC4XAC OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC RME4YP33NNUXA7HCHKUMB7UTNVGUCBDU3AZW3TDUTYL2CFZMNGOQC 36Z442IVPXHZ7D2QI26YLN3TDDEMDRQ2GKBYQAD6NUHQZVCCY4VAC OI4FPFINEROK6GNDEMOBTGSPYIULCLRGGT5W3H7VLM7VFH22GMWQC R6GUSTBY5ZHR7E46DSIDQDNZDJI6QMZQDC7RPQMQWLGWQKXU6HVQC LRDM35CEK3OHXOTB7TEFJRL7P6PQWO5ZG3F2BVA7DIDFHBPJQ7KAC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC -- This app has some limited capability to juggle multiple fonts. Mostly we-- want to keep everything at a single font size at any time. However,-- there's also a notion of a "heads-up display" that's overlaid atop the-- app, whose font size is even more fixed.HUD_font_height = 20HUD_line_height = math.floor(HUD_font_height*1.3)Menu_bar_height = 5 + HUD_line_height + 5
-- a few text objects we can avoid recomputing unless the font changesText_cache = {}
-- commonly used text objectsHUD_font = nilHUD_text_cache = {} -- fixed font, never recomputedText_cache = {} -- recompute when default font changes
Menu_background_color = {r=0.6, g=0.8, b=0.6}Menu_border_color = {r=0.6, g=0.7, b=0.6}Menu_command_color = {r=0.2, g=0.2, b=0.2}Menu_highlight_color = {r=0.5, g=0.7, b=0.3}function draw_menu_bar()if App.run_tests then return end -- disable in testsApp.color(Menu_background_color)love.graphics.rectangle('fill', 0,0, App.screen.width, Menu_bar_height)App.color(Menu_border_color)love.graphics.rectangle('line', 0,0, App.screen.width, Menu_bar_height)App.color(Menu_command_color)Menu_cursor = 5if Show_manifest_navigator thendraw_manifest_navigator()returnendadd_hotkey_to_menu('ctrl+l: load definition')add_hotkey_to_menu('ctrl+d: delete definition')add_hotkey_to_menu('ctrl+f: find')add_hotkey_to_menu('ctrl+left ctrl+right: prev/next word')add_hotkey_to_menu('ctrl+z ctrl+y: undo/redo')add_hotkey_to_menu('ctrl+x ctrl+c ctrl+v: cut/copy/paste')add_hotkey_to_menu('ctrl+= ctrl+- ctrl+0: zoom')endfunction add_hotkey_to_menu(s)local s_text = to_hud_text(s)local width = App.width(s_text)if Menu_cursor > App.screen.width - 30 thenreturnendApp.color(Menu_command_color)App.screen.draw(s_text, Menu_cursor,5)Menu_cursor = Menu_cursor + width + 30endfunction load_from_iterator(f)local result = {}local i,line,drawing = 0, ''while true dolocal line = f()if line == nil then break endtable.insert(result, {data=line})endif #result == 0 thentable.insert(result, {data=''})endreturn resultendfunction draw_manifest_navigator()App.color(Menu_command_color)local filter_text = to_hud_text(Manifest_navigator.filter)App.screen.draw(filter_text, 5, 5)draw_cursor(5 + App.width(filter_text), 5)if Manifest_navigator.num_lines == nil thenManifest_navigator.num_lines = num_lines_for_manifest_navigator(Manifest_navigator.candidates)endApp.color(Menu_background_color)-- inefficient that we're computing this on every frame-- so look only in the topmost linelocal current_definition = live.get_cmd_from_buffer(Editor_state.lines[1].data)love.graphics.rectangle('fill', 0,Menu_bar_height, App.screen.width, Manifest_navigator.num_lines * (Editor_state.line_height + --[[highlight padding]]5) + --[[extra highlight padding for bottom]] 2)local x,y = 5, Menu_bar_heightfor i,definition in ipairs(Manifest_navigator.candidates) doif definition == current_definition thenif not Editor_state.saved thendefinition = definition..'*'endelseif Cached_definitions[definition] and not Cached_definitions[definition].saved thendefinition = definition..'*'endendx,y = add_def_to_menu(x,y, definition, i == Manifest_navigator.index)if Menu_cursor >= App.screen.width - 5 thenbreakendendManifest_navigator.bottom_y = y + Editor_state.line_height + --[[highlight padding]] 5endfunction draw_cursor(x, y)-- blink every 0.5sif math.floor(Cursor_time*2)%2 == 0 thenApp.color(Cursor_color)love.graphics.rectangle('fill', x,y, 3,Editor_state.line_height)endendfunction manifest_navigator_candidates()if Manifest_navigator.filter == '' thenreturn Manifestendlocal result = {}for _,def in ipairs(Manifest) doif starts_with(def, Manifest_navigator.filter) thentable.insert(result, def)endendreturn resultendfunction num_lines_for_manifest_navigator(candidates)local result = 1local x = 5for i,def in ipairs(candidates) dolocal width = App.width(to_hud_text(def))if x + width > App.screen.width - 5 thenresult = result+1x = 5 + widthelsex = x + width + 30endendreturn resultendfunction add_def_to_menu(x,y, s, cursor_highlight)local s_text = to_hud_text(s)local width = App.width(s_text)if x + width > App.screen.width - 5 theny = y + Editor_state.line_height + --[[highlight padding]] 5x = 5endlocal color = Menu_background_colorif cursor_highlight thencolor = Menu_highlight_colorendbutton(Editor_state, 'menu', {x=x-5, y=y-2, w=width+5*2, h=Editor_state.line_height+2*2, color=colortable(color),onpress1 = function()load_definition(s)end})App.color(Menu_command_color)App.screen.draw(s_text, x,y)x = x + width + 30return x,yendfunction reset_manifest_navigator()Show_manifest_navigator = falseManifest_navigator.index = 1Manifest_navigator.filter = ''Manifest_navigator.candidates = ManifestManifest_navigator.num_lines = num_lines_for_manifest_navigator(Manifest_navigator.candidates)endfunction keychord_press_on_manifest_navigator(chord, key)if chord == 'escape' thenreset_manifest_navigator()elseif chord == 'return' thenif Manifest_navigator.delete thendelete_definition(Manifest_navigator.candidates[Manifest_navigator.index])elseload_definition(Manifest_navigator.candidates[Manifest_navigator.index])endelseif chord == 'backspace' thenlocal len = utf8.len(Manifest_navigator.filter)local byte_offset = Text.offset(Manifest_navigator.filter, len)Manifest_navigator.filter = string.sub(Manifest_navigator.filter, 1, byte_offset-1)Manifest_navigator.index = 1Manifest_navigator.candidates = manifest_navigator_candidates()elseif chord == 'left' thenif Manifest_navigator.index > 1 thenManifest_navigator.index = Manifest_navigator.index-1endelseif chord == 'right' thenif Manifest_navigator.index < #Manifest_navigator.candidates thenManifest_navigator.index = Manifest_navigator.index+1endelseif chord == 'down' thenmanifest_navigator_down()elseif chord == 'up' thenmanifest_navigator_up()endendfunction load_definition(name)-- save current buffer locallylocal old_buffer = live.definition_to_string(Editor_state)if old_buffer:find('%s*%S') thenlocal old_definition_name = live.get_cmd_from_buffer(old_buffer)Cached_definitions[old_definition_name] = {saved=Editor_state.saved, data=old_buffer}end--if old_definition_name == name then return end -- don't clobber unsaved datamove_candidate_to_front_of_manifest(name)-- load new bufferEditor_state = edit.initialize_state(Menu_bar_height + Margin_top, Margin_left+Line_number_width, App.screen.width-Margin_right)local definition_string, savedif Cached_definitions[name] == nil then-- from appdefinition_string, saved = get_definition_from_app(name), trueelse-- from local storedefinition_string, saved = Cached_definitions[name].data, Cached_definitions[name].savedendEditor_state.lines = load_from_iterator(definition_string:gmatch("[^\r\n]+"))Editor_state.saved = savedText.redraw_all(Editor_state)Editor_state.font_height = Font_heightEditor_state.line_height = Line_heightEditor_state.em = emreset_manifest_navigator()endfunction get_definition_from_app(name)live.send_to_app('GET '..name)local response_stringrepeatlove.timer.sleep(0.01)response_string = live.receive_from_app()until response_stringreturn response_stringendfunction move_candidate_to_front_of_manifest(name)local index = array.find(Manifest, name)if index thentable.remove(Manifest, index)table.insert(Manifest, 1, name)endendfunction delete_definition(name)live.send_to_app('DELETE '..name)Reload_manifest = truereset_manifest_navigator()endfunction manifest_navigator_up()local y, x, width = manifest_coord(Manifest_navigator.index)local index = manifest_index(y-Editor_state.line_height, x, width)if index thenManifest_navigator.index = indexendendfunction manifest_navigator_down()local y, x, width = manifest_coord(Manifest_navigator.index)local index = manifest_index(y+Editor_state.line_height, x, width)if index thenManifest_navigator.index = indexendendfunction manifest_coord(index)local y,x = Menu_bar_height, 5for i,definition in ipairs(Manifest_navigator.candidates) dolocal width = App.width(to_hud_text(definition))if x + width > App.screen.width - 5 theny = y + Editor_state.line_heightx = 5endif i == index thenreturn y, x, widthendx = x + width + 30endendfunction manifest_index(fy, fx, fwidth)local y,x = Menu_bar_height, 5local best_guess, best_guess_x, best_guess_widthfor i,definition in ipairs(Manifest_navigator.candidates) dolocal width = App.width(to_hud_text(definition))if x + width > App.screen.width - 5 theny = y + Editor_state.line_heightx = 5endif y == fy thenif best_guess == nil thenbest_guess = ibest_guess_x = xbest_guess_width = widthelseif math.abs(fx + fwidth/2 - x - width/2) < math.abs(fx + fwidth/2 - best_guess_x - best_guess_width/2) thenbest_guess = ibest_guess_x = xbest_guess_width = widthendendx = x + width + 30endreturn best_guessendfunction text_input_on_manifest_navigator(t)Manifest_navigator.filter = Manifest_navigator.filter..tManifest_navigator.candidates = manifest_navigator_candidates()Manifest_navigator.index = 1end
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, not obj.show_cursor)endendenddraw_menu_bar()end
{"line_height":365,"y_of_schema1":364,"on":1,"Page":444,"Surface":422,"parent":451,"add_thick_line":400,"A":433,"copy_shape":396,"font":353,"on.mouse_release":367,"on.text_input":388,"Cursor_node":172,"box_height":345,"on.initialize":350,"Viewport":439,"B":379,"initialize_editor":450,"to_text":180,"on.draw":452,"vx":5,"vy":448,"compute_layout":385,"update_editor_box":451,"on.mouse_press":179,"schema1_of_y":366,"on.code_change":306,"on.update":368,"scale":7,"on.keychord_press":391}