KJLZCK2RECVH77W4AJJMSXWYPU3U6Q3W3BY73TMXNLRZJZVQZAZAC
R6MB3UPBWL3PYRPVDCJFJIYGIJUV4ALGYUIGKGD3BZXCIAE6R5CQC
ULKNZUZKI5PQM36OHZAJHMZVXSEM7UUEOVZPI55B64UBU3UD3REAC
5GHT3LUX5SHCBV5ZPHCZM5H56BV5IVY7MXBDEO2NZKSMSL24PZOAC
2CEAF7YRI2ZKITZES5XGJEAPTCU46PPDNQTMJQQNVOE5Y656LWYAC
VSGPLJFA25LH5JYS5SQBQCKD7T763WSK7UYN4XMOFHUMQWAWSI7QC
ESH2GCJ65I27ODSOBQHEGPLUTWEEFQGNTTTEYU2I227L534YNJPQC
R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC
BLWAYPKV3MLDZ4ALXLUJ25AIR6PCIL4RFYNRYLB26GFVC2KQBYBAC
VLTU33KW2BVZFSNENNEGWMFZNWSWSTOXS6NHG7NWW43N3NDCNLTAC
ORKN6EOBUFVAD2TXYW5OIKSL55RU24LOFDTTTXHDZUZ57QRDCY7QC
TOXPJJYYZY7QRCVXJJDGDAM7NBSHEXNPRW5X4THW55FTSIZ3GKVQC
VHQCNMARPMNBSIUFLJG7HVK4QGDNPCGNVFLHS3I4IGNVSV5MRLYQC
QD4LOFQRYRXS5GCJLR4EKQPQBFYZA5CGRVJYVFT2U7GXZDAIUJNQC
ZLJYLPOTXIVBVWJ4NTRM2YCQPT2FCSN7446P56MJFEFY45QTB7IAC
R3KXFRZNL4CAT5OSKIIGWR3CHL2YJ5S4TKQDIPEHIJ2HW2WS46BQC
KMSL74GAMFNTAKGDKZFP2AMQXUMOC3XH373BO4IABZWBEP3YAXKAC
GFBOJWNEEYQ5JE2ILT7FX3HWTBBZTEOI7SSNDLKR3XGKL56YC3AAC
AQMZJXUR5NFNATJ4LPTVGVLQFIKRKRSPYAICXWHGQCQ4WLMQ2JTQC
JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC
34BZ5ZKNAB4XQGXOPVBZHBDYD5D3X4V6T72XZSR5LJXF4UIVSWQAC
KWIVKQQ7AANRG6R4ZRB5TDBZ2TZTXAXIR2P6JNT362KIAJ7JQ4VQC
KWHC65JIQZP77ZVU2YUF7M7MFZ7OWO3GPGOXJ6Q7JIZPXVVQLKAQC
JYZKEDDGZMLIH3GHTMURYCJ6H7IHZKPG4NT2RUZXLMENPV2UTCVAC
3PSFWAILGRA4OYXWS2DX7VF332AIBPYBXHEA4GIQY2XEJVD65UMAC
2TQUKHBC2EB3WDBD5UL62DQYV7CV6B7OJYK7CHOEDNOZENSOG42AC
7JEYXICU3ADDBDE7N6KLIA7F32FCEEZF7MIKK7O3KXWFZSNKTYNQC
6Z6WH62W4SGWWX75JQ2HVH2TC3IIWLNMA66UMTWWYSKPV7VS7IXAC
B6DS4GZC46Q4QSD3TXP5Q7NDERTOBAQV66JBCT5O6FAKKTLEVJLAC
ATQO62TFDZ7J4RCOSB3K2QCCB5R6PNYQIIGNXTLZMEFG5UG5PUJQC
KKQKPGCIHAG2JESQAWEMCBTAKBDC5AVIQ6LCZ2ORQM2AUCFQYLSQC
QYIFOHW3WDDQMK4ATY6IOSQRFHJOQ5QCPDKRC4GVGWLQEH4HGWVQC
ISOFHXB2DX6IRN4HVBYWLADZM7QXQKRNAAS577G542KS4L6G5H3QC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
I64IPGJXWRTGHHVAYJUBUIWFR4BY6NM5P7TLTV4JOD7K4BVYDECQC
Y5XAFGMWTCVHNO4XQAHN7J2SAMNALDM7TCDGJ56HFRQCTHQ4SQ6AC
OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC
36Z442IVPXHZ7D2QI26YLN3TDDEMDRQ2GKBYQAD6NUHQZVCCY4VAC
VPRGENLAJTF52YSY6NNZAPWQOD2TLP7DJU7DAAWGL4WFHOYAZF5QC
AVTNUQYRBW7IX2YQ3KDLVQ23RGW3BAKTAE7P73ASBYNKOHMQMH5AC
3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC
IZGZEWFGSMVXXFGMBITHUZUSFAJGWZNBE7LR7PCZ52P2JEO5HAUQC
4HAEKSJVXYUDFYJVYI5BYANWLOMFL74W4Y4YEUCZVEVBXOUFDYNQC
name_width = State.font:getWidth('m')
name_width = State.font:getWidth(p.name)
end
else
function 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+10
love.graphics.print("Things you can do:", State.left+30,y)
y = y + State.line_height
love.graphics.print("* Press the mouse button to start drawing a "..current_shape(State), State.left+30,y)
y = y + State.line_height
love.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_height
love.graphics.print("then press the mouse button to drop it", State.left+30+State.font:getWidth('* '),y)
y = y + State.line_height
love.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", State.left+30,y)
y = y + State.line_height
love.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", State.left+30,y)
y = y + State.line_height
if State.current_drawing_mode ~= 'freehand' then
love.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'line' then
love.graphics.print("* Press 'ctrl+l' to switch to drawing lines", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'manhattan' then
love.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'circle' then
love.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'polygon' then
love.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'rectangle' then
love.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'square' then
love.graphics.print("* Press 'ctrl+s' to switch to drawing squares", State.left+30,y)
y = y + State.line_height
end
love.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", State.left+30,y)
y = y + State.line_height
love.graphics.print("Press 'esc' now to hide this message", State.left+30,y)
y = y + State.line_height
App.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))
end
function 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+10
love.graphics.print("You're currently drawing a "..current_shape(State, drawing.pending), State.left+30,y)
y = y + State.line_height
love.graphics.print('Things you can do now:', State.left+30,y)
y = y + State.line_height
if State.current_drawing_mode == 'freehand' then
love.graphics.print('* Release the mouse button to finish drawing the stroke', State.left+30,y)
y = y + State.line_height
elseif State.current_drawing_mode == 'line' or State.current_drawing_mode == 'manhattan' then
love.graphics.print('* Release the mouse button to finish drawing the line', State.left+30,y)
y = y + State.line_height
elseif State.current_drawing_mode == 'circle' then
if drawing.pending.mode == 'circle' then
love.graphics.print('* Release the mouse button to finish drawing the circle', State.left+30,y)
y = y + State.line_height
love.graphics.print("* Press 'a' to draw just an arc of a circle", State.left+30,y)
else
love.graphics.print('* Release the mouse button to finish drawing the arc', State.left+30,y)
end
y = y + State.line_height
elseif State.current_drawing_mode == 'polygon' then
love.graphics.print('* Release the mouse button to finish drawing the polygon', State.left+30,y)
y = y + State.line_height
love.graphics.print("* Press 'p' to add a vertex to the polygon", State.left+30,y)
y = y + State.line_height
elseif State.current_drawing_mode == 'rectangle' then
if #drawing.pending.vertices < 2 then
love.graphics.print("* Press 'p' to add a vertex to the rectangle", State.left+30,y)
y = y + State.line_height
else
love.graphics.print('* Release the mouse button to finish drawing the rectangle', State.left+30,y)
y = y + State.line_height
love.graphics.print("* Press 'p' to replace the second vertex of the rectangle", State.left+30,y)
y = y + State.line_height
end
elseif State.current_drawing_mode == 'square' then
if #drawing.pending.vertices < 2 then
love.graphics.print("* Press 'p' to add a vertex to the square", State.left+30,y)
y = y + State.line_height
else
love.graphics.print('* Release the mouse button to finish drawing the square', State.left+30,y)
y = y + State.line_height
love.graphics.print("* Press 'p' to replace the second vertex of the square", State.left+30,y)
y = y + State.line_height
end
end
love.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", State.left+30,y)
y = y + State.line_height
y = y + State.line_height
if State.current_drawing_mode ~= 'line' then
love.graphics.print("* Press 'l' to switch to drawing lines", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'manhattan' then
love.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'circle' then
love.graphics.print("* Press 'o' to switch to drawing circles/arcs", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'polygon' then
love.graphics.print("* Press 'g' to switch to drawing polygons", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'rectangle' then
love.graphics.print("* Press 'r' to switch to drawing rectangles", State.left+30,y)
y = y + State.line_height
end
if State.current_drawing_mode ~= 'square' then
love.graphics.print("* Press 's' to switch to drawing squares", State.left+30,y)
y = y + State.line_height
end
App.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))
end
function current_shape(State, shape)
if State.current_drawing_mode == 'freehand' then
return 'freehand stroke'
elseif State.current_drawing_mode == 'line' then
return 'straight line'
elseif State.current_drawing_mode == 'manhattan' then
return 'horizontal/vertical line'
elseif State.current_drawing_mode == 'circle' and shape and shape.start_angle then
return 'arc'
else
return State.current_drawing_mode
end
end
lo_px = State.font:getWidth(before)
love.graphics.rectangle('fill', x+lo_px,y, State.font:getWidth(s),State.line_height)
App.color(Text_color)
return lo_px
end
end
end
love.graphics.print(line_index, State.left-Line_number_width*State.font:getWidth('m')+10,y)
local lo, hi = Text.clip_wikiword_with_screen_line(State.font, line, line_cache, i, s, e)
Text.draw_cursor(State, State.left+Text.x(State.font, screen_line, State.cursor1.pos-pos+1), y)
Text.draw_cursor(State, State.left+Text.x(State.font, screen_line, State.cursor1.pos-pos+1), y)
x = x+State.font:getWidth(frag)
local frag_width = State.font:getWidth(frag)
local bpos = Text.nearest_pos_less_than(State.font, frag, State.width - x)
frag_width = State.font:getWidth(frag)
function Text.clip_wikiword_with_screen_line(font, line, line_cache, i, s, e)
return font:getWidth(line.data:sub(soff, loff-1)), font:getWidth(line.data:sub(soff, hoff))
State.cursor1.pos = screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, State.cursor_x, State.left) - 1
State.cursor1.pos = new_screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, State.cursor_x, State.left) - 1
pos = Text.nearest_cursor_pos(State.font, State.lines[new_cursor_line].data, State.cursor_x, State.left),
State.cursor1.pos = new_screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, State.cursor_x, State.left) - 1
--? print('return', mx, Text.nearest_cursor_pos(State.font, s, mx, State.left), '=>', screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, mx, State.left) - 1)
return screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, mx, State.left) - 1
return State.font:getWidth(screen_line)
function Text.nearest_cursor_pos(font, line, x, left)
local max_x = left+Text.x(font, line, len+1)
local currxmin = left+Text.x(font, line, curr)
local currxmax = left+Text.x(font, line, curr+1)
function Text.nearest_pos_less_than(font, line, x)
local max_x = Text.x_after(font, line, len)
local currxmin = Text.x_after(font, line, curr+1)
local currxmax = Text.x_after(font, line, curr+2)
function Text.x_after(font, s, pos)
return font:getWidth(s_before)
function Text.x(font, s, pos)
return font:getWidth(s_before)
end
function Text.to2(State, loc1)
local offset = Text.offset(s, pos)
local s_before = s:sub(1, offset-1)
end
local len = utf8.len(s)
local offset = Text.offset(s, math.min(pos+1, len+1))
--? print('', x, left, right, curr, currxmin, currxmax)
if currxmin <= x and x < currxmax then
return curr
end
if left >= right-1 then
return left
end
if currxmin > x then
right = curr
else
left = curr
end
end
if x > max_x then
return len+1
end
local left, right = 0, len+1
while true do
local curr = math.floor((left+right)/2)
--? print('', '-- nearest_pos_less_than', line, x)
local len = utf8.len(line)
--? print('nearest', x, leftpos, rightpos, curr, currxmin, currxmax)
if currxmin <= x and x < currxmax then
if x-currxmin < currxmax-x then
return curr
else
return curr+1
end
end
if leftpos >= rightpos-1 then
return rightpos
end
if currxmin > x then
rightpos = curr
else
leftpos = curr
end
end
if x > max_x then
return len+1
end
local leftpos, rightpos = 1, len+1
--? print('-- nearest', x)
while true do
--? print('nearest', x, '^'..line..'$', leftpos, rightpos)
if leftpos == rightpos then
return leftpos
end
local curr = math.floor((leftpos+rightpos)/2)
if x < left then
return 1
end
local len = utf8.len(line)
end
end
y = nexty
end
--? print('cursor pos is now', State.cursor1.line, State.cursor1.pos)
if scroll_down then
--? print('scroll up preserving cursor')
Text.snap_cursor_to_bottom_of_screen(State)
--? print('screen top after:', State.screen_top1.line, State.screen_top1.pos)
end
}
--? print(State.cursor1.pos)
break
end
--? print('cursor pos is now '..tostring(State.cursor1.pos))
end
if Text.lt1(State.cursor1, State.screen_top1) then
break
end
end
local spos = line_cache.screen_line_starting_pos[i]
local soff = Text.offset(line.data, spos)
if e < soff then
return
end
local eoff
if i < #line_cache.screen_line_starting_pos then
local epos = line_cache.screen_line_starting_pos[i+1]
eoff = Text.offset(line.data, epos)
if s > eoff then
return
end
--? print('screen line:', pos)
if x == 0 and bpos == 0 then
assert(false, ("Infinite loop while line-wrapping. Editor is %dpx wide; window is %dpx wide"):format(State.width, App.screen.width))
end
--? 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
-- long word; chop it at some letter
-- We're not going to reimplement TeX here.
end
end
end
end
elseif pos + frag_len == State.cursor1.pos then
-- Show cursor at end of line.
-- This place also catches end of wrapping screen lines. That doesn't seem worth distinguishing.
-- It seems useful to see a cursor whether your eye is on the left or right margin.
if lo then
end
Editor_state = edit.initialize_state(Margin_top, Margin_left + Line_number_width*font:getWidth('m'), right, font, settings.font_height, math.floor(settings.font_height*1.3))
Editor_state = edit.initialize_state(Margin_top, Margin_left + Line_number_width*font:getWidth('m'), App.screen.width-Margin_right, font, font_height, math.floor(font_height*1.3))
Editor_state.filename = 'run.lua'
Editor_state.filename = settings.filename
love.graphics.line(xleft+50+State.font:getWidth(line.section_name)+2,sectiony, xright,sectiony)
love.graphics.line(xleft+50+State.font:getWidth(line.section_name)+2,sectiony, xright,sectiony)
love.graphics.print(line.section_stack[i].name, x+State.font_height+5, App.screen.height-State.font:getWidth(line.section_stack[i].name)-5, --[[vertically]] math.pi/2)
love.graphics.print(line.section_stack[i].name, x, App.screen.height-State.font:getWidth(line.section_stack[i].name)-5, --[[vertically]] math.pi/2)
end
end
return log_browser.right_margin(State, line)
end
function should_show(line)
-- Show a line if every single section it's in is expanded.
for i=1,#line.section_stack do
local section = line.section_stack[i]
if not section.expanded then
return false
end
end
return true
end
function log_browser.left_margin(State, line)
return State.left + #line.section_stack*Section_border_padding_horizontal
end
function log_browser.right_margin(State, line)
return State.right - #line.section_stack*Section_border_padding_horizontal
end
function log_browser.update(State, dt)
end
function log_browser.quit(State)
end
end
end
return log_browser.left_margin(State, line)
end
function render_stack_right_margin(State, line_index, line, y)
App.color(Section_border_color)
for i=1,#line.section_stack do
local x = State.right - (i-1)*Section_border_padding_horizontal
love.graphics.line(x,y, x,y+log_browser.height(State, line_index))
if y < 30 then
love.graphics.print(line.section_stack[i].name, x, y+5, --[[vertically]] math.pi/2)
end
if y > App.screen.height-log_browser.height(State, line_index) then
end
else
if type(line.data) == 'string' then
local old_left, old_right = State.left,State.right
State.left,State.right = xleft,xright
else assert(line.section_end, "log line has a section name, but it's neither the start nor end of a section")
if Disable_all_quit_handlers then return end
end
function warning_message()
assert(type(Current_app) == 'table')
return Current_app.message