FJAM6Z3SJ4WITRPEEBOPIIU4CQAT33EC26CB2WXVZHGSWI56FQEAC 7XZGKYGGRZ6T5G4MI4SXACPKLLDMT3WIUDGFBAOQ5CJ7DVUVNSVQC OAVZNCHCW2UFP6KBB3W7AJ4TUDD4IMB2SUJWBPMOFCQ5AQD5HSJQC SVSD5NO3MQFKEFX4Y34OT5OO7SF5PK3PODCYZ4DUOM4OH5UTWWCAC R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC VHQCNMARPMNBSIUFLJG7HVK4QGDNPCGNVFLHS3I4IGNVSV5MRLYQC R3KXFRZNL4CAT5OSKIIGWR3CHL2YJ5S4TKQDIPEHIJ2HW2WS46BQC BLWAYPKV3MLDZ4ALXLUJ25AIR6PCIL4RFYNRYLB26GFVC2KQBYBAC 7AI33WIR6M4LFX7E7ZMYQMNDI6NLJ7EENSWAXFYVVZBG5H7JFWCQC RNDKROV3B4W7AAJUB65JGHZZ66OX6KVBGHVWVZGIITBNZH2UE3CAC 2CK5QI7WA7M4IVSACFGOJYAIDKRUTZVMMPSFWEJTUNMWTN7AX4NAC JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC KHPSHJN4BMTJ3CHUFQQZU7ZIQDOQDF3L5HV3TRT5OJMYICJAEB5QC QEXZHD2VPCM4TAPP7PR2K2PIR4BVES5IZWC3T6ZRNJWKWOXFILNQC KMSL74GAMFNTAKGDKZFP2AMQXUMOC3XH373BO4IABZWBEP3YAXKAC ISOFHXB2DX6IRN4HVBYWLADZM7QXQKRNAAS577G542KS4L6G5H3QC VYAIL5M4DLB7L3L34JX4XBBX6LZJKQDNC4TVNALP5L5XLUBM7TIQC UJDZ24YPXMDGJ6KJUXPELYZTXYUC4Y45EHV2VAREEONIDY7L3QNQC 2I6URQ573QKGO433M4J7GQOZZLW34BIGMDWDYLAZFTQBWKFW4QBQC 7P6XKA2DCFG5YJAVTCAZMQNNDJ6K6OO5AILBBCVYV37XKZNYKHPAC DQ5SFBFUZOJGL5VYGYNODUXHDIIWQNCP6N7TBHYDN6GZ5SBHVFCAC HOSPP2ANSW654DYRTC6CQUQA2GUKV6T2FI7QBKXD2DZS3R32IMGAC MIKAQWHPJFAELPV7ATGH6DWR7V4FKHAOYMPAKVFFSGEUNE5IVIDQC BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC I64IPGJXWRTGHHVAYJUBUIWFR4BY6NM5P7TLTV4JOD7K4BVYDECQC QYIFOHW3WDDQMK4ATY6IOSQRFHJOQ5QCPDKRC4GVGWLQEH4HGWVQC LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC 2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC YWJZXFOROWKREZ76THNMQLWEOVWDYMNEEPGRMDXX32DJPRIJY76QC 3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC 76XOJEND6OWBWA7V6YXTQV2NP5SVVMLVZCCINBWKOBJARSUWNJJQC AVTNUQYRBW7IX2YQ3KDLVQ23RGW3BAKTAE7P73ASBYNKOHMQMH5AC return App.width('* ')endendfunction draw_help_without_mouse_pressed(State, drawing_index)local drawing = State.lines[drawing_index]local line_cache = State.line_cache[drawing_index]App.color(Help_color)local y = line_cache.starty+10love.graphics.print("Things you can do:", State.left+30,y)y = y + State.line_heightlove.graphics.print("* Press the mouse button to start drawing a "..current_shape(State), State.left+30,y)y = y + State.line_heightlove.graphics.print("* Hover on a point and press 'ctrl+u' to pick it up and start moving it,", State.left+30,y)y = y + State.line_heightlove.graphics.print("then press the mouse button to drop it", State.left+30+bullet_indent(),y)y = y + State.line_heightlove.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", State.left+30,y)y = y + State.line_heightlove.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", State.left+30,y)y = y + State.line_heightif State.current_drawing_mode ~= 'freehand' thenlove.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'line' thenlove.graphics.print("* Press 'ctrl+l' to switch to drawing lines", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'manhattan' thenlove.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'circle' thenlove.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'polygon' thenlove.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'rectangle' thenlove.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'square' thenlove.graphics.print("* Press 'ctrl+s' to switch to drawing squares", State.left+30,y)y = y + State.line_heightendlove.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", State.left+30,y)y = y + State.line_heightlove.graphics.print("Press 'esc' now to hide this message", State.left+30,y)y = y + State.line_heightApp.color(Help_background_color)love.graphics.rectangle('fill', State.left,line_cache.starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-line_cache.starty))endfunction draw_help_with_mouse_pressed(State, drawing_index)local drawing = State.lines[drawing_index]local line_cache = State.line_cache[drawing_index]App.color(Help_color)local y = line_cache.starty+10love.graphics.print("You're currently drawing a "..current_shape(State, drawing.pending), State.left+30,y)y = y + State.line_heightlove.graphics.print('Things you can do now:', State.left+30,y)y = y + State.line_heightif State.current_drawing_mode == 'freehand' thenlove.graphics.print('* Release the mouse button to finish drawing the stroke', State.left+30,y)y = y + State.line_heightelseif State.current_drawing_mode == 'line' or State.current_drawing_mode == 'manhattan' thenlove.graphics.print('* Release the mouse button to finish drawing the line', State.left+30,y)y = y + State.line_heightelseif State.current_drawing_mode == 'circle' thenif drawing.pending.mode == 'circle' thenlove.graphics.print('* Release the mouse button to finish drawing the circle', State.left+30,y)y = y + State.line_heightlove.graphics.print("* Press 'a' to draw just an arc of a circle", State.left+30,y)elselove.graphics.print('* Release the mouse button to finish drawing the arc', State.left+30,y)endy = y + State.line_heightelseif State.current_drawing_mode == 'polygon' thenlove.graphics.print('* Release the mouse button to finish drawing the polygon', State.left+30,y)y = y + State.line_heightlove.graphics.print("* Press 'p' to add a vertex to the polygon", State.left+30,y)y = y + State.line_heightelseif State.current_drawing_mode == 'rectangle' thenif #drawing.pending.vertices < 2 thenlove.graphics.print("* Press 'p' to add a vertex to the rectangle", State.left+30,y)y = y + State.line_heightelselove.graphics.print('* Release the mouse button to finish drawing the rectangle', State.left+30,y)y = y + State.line_heightlove.graphics.print("* Press 'p' to replace the second vertex of the rectangle", State.left+30,y)y = y + State.line_heightendelseif State.current_drawing_mode == 'square' thenif #drawing.pending.vertices < 2 thenlove.graphics.print("* Press 'p' to add a vertex to the square", State.left+30,y)y = y + State.line_heightelselove.graphics.print('* Release the mouse button to finish drawing the square', State.left+30,y)y = y + State.line_heightlove.graphics.print("* Press 'p' to replace the second vertex of the square", State.left+30,y)y = y + State.line_heightendendlove.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", State.left+30,y)y = y + State.line_heighty = y + State.line_heightif State.current_drawing_mode ~= 'line' thenlove.graphics.print("* Press 'l' to switch to drawing lines", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'manhattan' thenlove.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'circle' thenlove.graphics.print("* Press 'o' to switch to drawing circles/arcs", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'polygon' thenlove.graphics.print("* Press 'g' to switch to drawing polygons", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'rectangle' thenlove.graphics.print("* Press 'r' to switch to drawing rectangles", State.left+30,y)y = y + State.line_heightendif State.current_drawing_mode ~= 'square' thenlove.graphics.print("* Press 's' to switch to drawing squares", State.left+30,y)y = y + State.line_heightendApp.color(Help_background_color)love.graphics.rectangle('fill', State.left,line_cache.starty, State.width, math.max(Drawing.pixels(drawing.h, State.width),y-line_cache.starty))endfunction current_shape(State, shape)if State.current_drawing_mode == 'freehand' thenreturn 'freehand stroke'elseif State.current_drawing_mode == 'line' thenreturn 'straight line'elseif State.current_drawing_mode == 'manhattan' thenreturn 'horizontal/vertical line'elseif State.current_drawing_mode == 'circle' and shape and shape.start_angle thenreturn 'arc'elsereturn State.current_drawing_modeendendfunction bullet_indent()
local name_widthname_width = App.width('m')name_width = App.width(p.name)love.graphics.rectangle('fill', x,y, name_width, State.line_height)-- after mouse_releaseendendendendApp.color(Current_stroke_color)Drawing.draw_pending_shape(line, line_cache.starty, State.left,State.right)endfunction Drawing.draw_shape(drawing, shape, top, left,right)local width = right-leftlocal function px(x) return Drawing.pixels(x, width)+left endlocal function py(y) return Drawing.pixels(y, width)+top endif shape.mode == 'freehand' thenlocal prev = nilfor _,point in ipairs(shape.points) doif prev thenlove.graphics.line(px(prev.x),py(prev.y), px(point.x),py(point.y))endprev = pointendelseif shape.mode == 'line' or shape.mode == 'manhattan' thenlocal p1 = drawing.points[shape.p1]local p2 = drawing.points[shape.p2]love.graphics.line(px(p1.x),py(p1.y), px(p2.x),py(p2.y))elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' thenlocal prev = nilfor _,point in ipairs(shape.vertices) dolocal curr = drawing.points[point]if prev thenlove.graphics.line(px(prev.x),py(prev.y), px(curr.x),py(curr.y))endprev = currend-- close the looplocal curr = drawing.points[shape.vertices[1]]love.graphics.line(px(prev.x),py(prev.y), px(curr.x),py(curr.y))elseif shape.mode == 'circle' then-- TODO: cliplocal center = drawing.points[shape.center]love.graphics.circle('line', px(center.x),py(center.y), Drawing.pixels(shape.radius, width))elseif shape.mode == 'arc' thenlocal center = drawing.points[shape.center]love.graphics.arc('line', 'open', px(center.x),py(center.y), Drawing.pixels(shape.radius, width), shape.start_angle, shape.end_angle, 360)elseif shape.mode == 'deleted' then-- ignoreelseprint(shape.mode)assert(false)endendfunction Drawing.draw_pending_shape(drawing, top, left,right)local width = right-leftlocal pmx,pmy = App.mouse_x(), App.mouse_y()local function px(x) return Drawing.pixels(x, width)+left endlocal function py(y) return Drawing.pixels(y, width)+top endlocal mx = Drawing.coord(pmx-left, width)local my = Drawing.coord(pmy-top, width)-- recreate pixels from coords to precisely mimic how the drawing will lookendelseif p.name == '' then
table.insert(event.lines, {mode='text', data=line.data}) -- I've forgotten: should we deepcopy(line.data)?table.insert(event.lines, {mode='drawing', h=line.h, points=deepcopy(line.points), shapes=deepcopy(line.shapes), pending={}})elseprint(line.mode)assert(false)endelseif line.mode == 'drawing' then
love.graphics.rectangle('fill', x+lo_px,y, App.width(s),State.line_height)App.color(Text_color)return lo_pxendend-- inefficient for some reason, so don't do it on every framefunction Text.mouse_pos(State)local time = love.timer.getTime()if State.recent_mouse.time and State.recent_mouse.time > time-0.1 thenreturn State.recent_mouse.line, State.recent_mouse.posendState.recent_mouse.time = timelocal line,pos = Text.to_pos(State, App.mouse_x(), App.mouse_y())if line thenState.recent_mouse.line = lineState.recent_mouse.pos = posendreturn State.recent_mouse.line, State.recent_mouse.posendfunction Text.to_pos(State, x,y)for line_index,line in ipairs(State.lines) doif line.mode == 'text' thenif Text.in_line(State, line_index, x,y) thenreturn line_index, Text.to_pos_on_line(State, line_index, x,y)endendendendfunction Text.cut_selection(State)if State.selection1.line == nil then return endlocal result = Text.selection(State)Text.delete_selection(State)return resultendfunction Text.delete_selection(State)if State.selection1.line == nil then return endlocal minl,maxl = minmax(State.selection1.line, State.cursor1.line)local before = snapshot(State, minl, maxl)Text.delete_selection_without_undo(State)record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})endfunction Text.delete_selection_without_undo(State)if State.selection1.line == nil then return end-- min,max = sorted(State.selection1,State.cursor1)local minl,minp = State.selection1.line,State.selection1.poslocal maxl,maxp = State.cursor1.line,State.cursor1.posif minl > maxl thenminl,maxl = maxl,minlminp,maxp = maxp,minpelseif minl == maxl thenif minp > maxp thenminp,maxp = maxp,minpendend-- update State.cursor1 and State.selection1State.cursor1.line = minlState.cursor1.pos = minpif Text.lt1(State.cursor1, State.screen_top1) thenState.screen_top1.line = State.cursor1.lineState.screen_top1.pos = Text.pos_at_start_of_screen_line(State, State.cursor1)endState.selection1 = {}-- delete everything between min (inclusive) and max (exclusive)Text.clear_screen_line_cache(State, minl)local min_offset = Text.offset(State.lines[minl].data, minp)local max_offset = Text.offset(State.lines[maxl].data, maxp)if minl == maxl then--? print('minl == maxl')State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..State.lines[minl].data:sub(max_offset)returnendassert(minl < maxl)local rhs = State.lines[maxl].data:sub(max_offset)for i=maxl,minl+1,-1 dotable.remove(State.lines, i)table.remove(State.line_cache, i)endState.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..rhsendfunction Text.selection(State)if State.selection1.line == nil then return end-- min,max = sorted(State.selection1,State.cursor1)local minl,minp = State.selection1.line,State.selection1.poslocal maxl,maxp = State.cursor1.line,State.cursor1.posif minl > maxl thenminl,maxl = maxl,minlminp,maxp = maxp,minpelseif minl == maxl thenif minp > maxp thenminp,maxp = maxp,minpendendlocal min_offset = Text.offset(State.lines[minl].data, minp)local max_offset = Text.offset(State.lines[maxl].data, maxp)if minl == maxl thenreturn State.lines[minl].data:sub(min_offset, max_offset-1)endassert(minl < maxl)local result = {State.lines[minl].data:sub(min_offset)}for i=minl+1,maxl-1 doif State.lines[i].mode == 'text' thentable.insert(result, State.lines[i].data)endendtable.insert(result, State.lines[maxl].data:sub(1, max_offset-1))return table.concat(result, '\n')endlo_px = App.width(before)end--? print(lo,pos,hi, '--', lo_offset,pos_offset,hi_offset, '--', lo_px)local s = line.data:sub(lo_offset, hi_offset-1)
Text.populate_screen_line_starting_pos(State, line_index)select_color(f)local frag_len = utf8.len(f)--? print('text.draw:', f, 'at', line_index,pos, 'after', x,y)--? print('skipping', f)local frag_width = App.width(f)local frag_width = App.width(f)pos = pos + utf8.len(f)local frag1_width = App.width(frag1)table.insert(line_cache.fragments, frag1)frag_width = App.width(frag)table.insert(line_cache.fragments, frag)return App.width(s_before)return App.width(s_before)endfunction Text.to2(State, loc1)endfunction Text.x(s, pos)local offset = Text.offset(s, pos)local s_before = s:sub(1, offset-1)return App.width(screen_line)endendx = x + frag_widthendx = State.left -- new lineendif #frag > 0 thenfrag = string.sub(frag, boffset)assert(x + frag1_width <= State.right)local frag_width = App.width(frag)while x + frag_width > State.right doendendfunction Text.compute_fragments(State, line_index)if x + frag_width > State.right thenx = State.lefttable.insert(line_cache.screen_line_starting_pos, pos)endx = x + frag_widthText.draw_cursor(State, x+Text.x(f, State.cursor1.pos-pos+1), y)App.color(Text_color)endendendx = x + frag_widthendpos = pos + frag_lenendlocal trimmed_word = rtrim(f) -- compute_fragments puts whitespace at the endbutton(State, 'link', {x=x+App.width('[['), y=y, w=App.width(filename), h=State.line_height, color={1,1,1},App.screen.print(f, x,y)-- render cursor if necessaryicon = icon.hyperlink_decoration,onpress1 = function()source.switch_to_file(filename)end,})endendif starts_with(trimmed_word, '[[') and ends_with(trimmed_word, ']]') thenlocal filename = trimmed_word:gsub('^..(.*)..$', '%1')if source.link_exists(State, filename) thenif x + frag_width > State.right thenassert(x > State.left) -- no overfull linesy = y + State.line_heightif y + State.line_height > App.screen.height thenelse-- render fragmentif pos < startpos then-- render nothinglocal pos = 1initialize_color()for _, f in ipairs(line_cache.fragments) doApp.color(Text_color)
line_info.data = linetable.insert(result, line_info)table.insert(result, {mode='text', data=line})end
-- fragments: snippets of the line guaranteed to not straddle screen lines-- screen_line_starting_pos: optional array of grapheme indices if it wraps over more than one screen lineline_cache = {},-- Given wrapping, any potential location for the text cursor can be described in two ways:-- * schema 1: As a combination of line index and position within a line (in utf8 codepoint units)-- * schema 2: As a combination of line index, screen line index within the line, and a position within the screen line.
source.initialize_window_geometry(App.width('m'))Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right)
function width(s)return love.graphics.getFont():getWidth(s)endrun.initialize_window_geometry(App.width('m'))Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right)Editor_state.font_height = font_heightEditor_state.line_height = math.floor(font_height*1.3)
love.graphics.print(line.section_name, xleft+50,y)love.graphics.line(xleft+50+App.width(line.section_name)+2,sectiony, xright,sectiony)love.graphics.print(line.section_name, xleft+50,y)love.graphics.line(xleft+50+App.width(line.section_name)+2,sectiony, xright,sectiony)love.graphics.print(line.section_stack[i].name, x+State.font_height+5, App.screen.height-App.width(line.section_stack[i].name)-5, --[[vertically]] math.pi/2)love.graphics.print(line.section_stack[i].name, x, App.screen.height-App.width(line.section_stack[i].name)-5, --[[vertically]] math.pi/2)endendreturn log_browser.right_margin(State, line)endfunction should_show(line)-- Show a line if every single section it's in is expanded.for i=1,#line.section_stack dolocal section = line.section_stack[i]if not section.expanded thenreturn falseendendreturn trueendfunction log_browser.left_margin(State, line)return State.left + #line.section_stack*Section_border_padding_horizontalendfunction log_browser.right_margin(State, line)return State.right - #line.section_stack*Section_border_padding_horizontalendfunction log_browser.update(State, dt)endfunction log_browser.quit(State)endendendreturn log_browser.left_margin(State, line)endfunction render_stack_right_margin(State, line_index, line, y)App.color(Section_border_color)for i=1,#line.section_stack dolocal x = State.right - (i-1)*Section_border_padding_horizontallove.graphics.line(x,y, x,y+log_browser.height(State, line_index))if y < 30 thenlove.graphics.print(line.section_stack[i].name, x, y+5, --[[vertically]] math.pi/2)endif y > App.screen.height-log_browser.height(State, line_index) thenendelseif type(line.data) == 'string' thenlocal old_left, old_right = State.left,State.rightState.left,State.right = xleft,xrighty = Text.draw(State, line_index, y, --[[startpos]] 1)State.left,State.right = old_left,old_rightelseheight = log_render[line.data.name](line.data, xleft, y, xright-xleft)endendif App.mouse_x() > Log_browser_state.left and line_index == mouse_line_index thenApp.color(Cursor_line_background_color)love.graphics.rectangle('fill', xleft,y, xright-xleft, height)endy = y + heightendendendfunction render_stack_left_margin(State, line_index, line, y)if line.section_stack == nil then-- assertion messagefor k,v in pairs(line) doprint(k)endendApp.color(Section_border_color)for i=1,#line.section_stack dolocal x = State.left + (i-1)*Section_border_padding_horizontallove.graphics.line(x,y, x,y+log_browser.height(State, line_index))if y < 30 thenlove.graphics.print(line.section_stack[i].name, x+State.font_height+5, y+5, --[[vertically]] math.pi/2)endif y > App.screen.height-log_browser.height(State, line_index) thenelse assert(line.section_end)local sectiony = y+State.line_height-Section_border_padding_verticallove.graphics.line(xleft,y, xleft,sectiony)love.graphics.line(xright,y, xright,sectiony)love.graphics.line(xleft,sectiony, xleft+50-2,sectiony)
width = App.width(filename)width = App.width(filename)App.screen.print(filename, x + x3-menu_xmin, y3)local width = App.width(filename)local width = App.width(filename)if x + width > App.screen.width - 5 theny = y + Editor_state.line_heightx = 5endif y == fy thenlog(2, ('%d: correct row; considering %d %s %d %d'):format(y, i, filename, x, width))if best_guess == nil thenlog(2, 'nil')best_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 = widthendlog(2, ('best guess now %d %s %d %d'):format(best_guess, File_navigation.candidates[best_guess], best_guess_x, best_guess_width))endx = x + width + 30endlog_end('file index')return best_guessendif x + width > App.screen.width - 5 theny = y + Editor_state.line_heightx = 5endif i == index thenreturn y, x, widthendx = x + width + 30endendfunction file_index(fy, fx, fwidth)log_start('file index')log(2, ('for %d %d %d'):format(fy, fx, fwidth))local y,x = Menu_status_bar_height, 5local best_guess, best_guess_x, best_guess_widthfor i,filename in ipairs(File_navigation.candidates) doendx3 = x3 + width + 30end--return h+20endfunction file_navigator_up()local y, x, width = file_coord(File_navigation.index)local index = file_index(y-Editor_state.line_height, x, width)if index thenFile_navigation.index = indexendendfunction file_navigator_down()local y, x, width = file_coord(File_navigation.index)local index = file_index(y+Editor_state.line_height, x, width)if index thenFile_navigation.index = indexendendfunction file_coord(index)local y,x = Menu_status_bar_height, 5for i,filename in ipairs(File_navigation.candidates) doif x3 + width > App.screen.width - 5 theny3 = y3 + Editor_state.line_heightx3 = 0endif i == o.index thenApp.color(Menu_highlight_color)love.graphics.rectangle('fill', x + x3-menu_xmin - 5, y3-2, width+5*2, Editor_state.line_height+2*2)endif x3 >= menu_xmin and x3 + width < menu_xmax thenApp.color(Menu_command_color)if x2 + width > App.screen.width - 5 theny2 = y2 + Editor_state.line_heightx2 = 0endif i == o.index thenbreakendx2 = x2 + width + 30end-- figure out how much of the menu to displaylocal menu_xmin = math.max(0, x2-w/2)local menu_xmax = math.min(App.screen.width, x2+w/2)-- now selectively print out entrieslocal x3,y3 = 0,y -- x3 is relative, y3 is absolutelocal width = 0for i,filename in ipairs(o.files) doApp.screen.print(s, x,y)x = x + width + 30return x,ylocal width = App.width(filename)local width = App.width(s)if x + width > App.screen.width - 5 theny = y + Editor_state.line_heightx = 5if x + width > App.screen.width - 5 thenresult = result+1x = 5 + widthelsex = x + width + 30endendreturn resultendfunction add_file_to_menu(x,y, s, cursor_highlight)App.screen.print(File_navigation.filter, 5, 5)draw_cursor(5 + App.width(File_navigation.filter), 5)if File_navigation.num_lines == nil thenFile_navigation.num_lines = source.num_lines_for_file_navigator(File_navigation.candidates)endApp.color(Menu_background_color)love.graphics.rectangle('fill', 0,Menu_status_bar_height, App.screen.width, File_navigation.num_lines * Editor_state.line_height + --[[highlight padding]] 2)local x,y = 5, Menu_status_bar_heightfor i,filename in ipairs(File_navigation.candidates) doApp.screen.print(s, Menu_cursor,5)Menu_cursor = Menu_cursor + width + 30endfunction source.draw_file_navigator()local width = App.width(s)if Menu_cursor > App.screen.width - 30 then
local frag_width = App.width(frag)--? print('-- frag:', frag, pos, x, frag_width, State.width)while x + frag_width > State.width do--? print('frag:', frag, pos, x, frag_width, State.width)if x < 0.8 * State.width then