M5JXTW56XOOHCPAXPRERPQHHJUNTLGYTDIKTRGQZVW2HVIBKSI5QC
RIAFJLMZD4DCRT5J3YIRP4OTNZJTQR4Q7VWKYHDZY65MIFQ5RF3QC
R2ASHK5CEE3PTRLS37GP4PXJ7HIGJ6UD72KKBI57UDJI7VRROQGQC
R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC
BLWAYPKV3MLDZ4ALXLUJ25AIR6PCIL4RFYNRYLB26GFVC2KQBYBAC
QD4LOFQRYRXS5GCJLR4EKQPQBFYZA5CGRVJYVFT2U7GXZDAIUJNQC
ORKN6EOBUFVAD2TXYW5OIKSL55RU24LOFDTTTXHDZUZ57QRDCY7QC
34BZ5ZKNAB4XQGXOPVBZHBDYD5D3X4V6T72XZSR5LJXF4UIVSWQAC
2CK5QI7WA7M4IVSACFGOJYAIDKRUTZVMMPSFWEJTUNMWTN7AX4NAC
KYNGDE2CKNOKUC2XMAS5MEU6YT2C3IW5SIZLOJE64G3ERT7BSWFAC
JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC
KWIVKQQ7AANRG6R4ZRB5TDBZ2TZTXAXIR2P6JNT362KIAJ7JQ4VQC
VOU73AK6XOVIOCY6PHUXS5RQZ2TGFEF7RYNOKFE2XSHRCZBAJMYQC
3PSFWAILGRA4OYXWS2DX7VF332AIBPYBXHEA4GIQY2XEJVD65UMAC
U3MJNFUY4ER65BIKP4D7JGVYWFPXA55KBJYD4RH5KRRKRQXBAW5AC
2TQUKHBC2EB3WDBD5UL62DQYV7CV6B7OJYK7CHOEDNOZENSOG42AC
4U4VQWNYWI53T7JQ2WSA4HZU3AWUIVXWMFCHOGUKT3ZN5C3GF6AQC
ATQO62TFDZ7J4RCOSB3K2QCCB5R6PNYQIIGNXTLZMEFG5UG5PUJQC
CNCYMM6ABOXCRI2IP5A4T2OGBO5FQ7GWBXBP2OQYL4YET5BLJCGQC
JCXL74WVQ23V53EOCKA2NXQIYA5NNOXGN5WYC7ZW42EI2I6D5IJAC
2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC
PJEQCTBL2ZX5Q7NJQ3KCWSHHBV2QWGYS5NVMRDNK5LOOIIRRIPHAC
APX2PY6GAMJSUH7SFSMBFOQJBSAWLLOCKH4L4ZQP2VLHNEXJPREAC
MD3W5IRAC6UQALQE4LJC52VQNDO3I3HXF3XE2XHDABXBYJBUVAXQC
7VGDIPLCFDG3PVE4JH3WDKZ4A7PG5UYW7TLFFFOWN2JEUZYYTFJQC
R56CKHYZLUOTRK42EKTFC4KUUYI76PREFVFE2YKCZCODFKIJKAQQC
3XNFQDDNFGTN6ZFAB47AR6Q3663WLXDYC3K5TERYUWDM6U2FNOVAC
LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC
function Drawing.mouse_release(State, x,y, mouse_button)
if line_cache.starty == nil then
-- some event cleared starty just this frame
-- draw in this frame will soon set starty
-- just skip this frame
return
end
assert(drawing.mode == 'drawing')
local pmx, pmy = App.mouse_x(), App.mouse_y()
local mx = Drawing.coord(pmx-State.left, State.width)
local my = Drawing.coord(pmy-line_cache.starty, State.width)
if App.mouse_down(1) then
if Drawing.in_drawing(drawing, line_cache, pmx,pmy, State.left,State.right) then
if drawing.pending.mode == 'freehand' then
table.insert(drawing.pending.points, {x=mx, y=my})
elseif drawing.pending.mode == 'move' then
drawing.pending.target_point.x = mx
drawing.pending.target_point.y = my
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
end
end
elseif State.current_drawing_mode == 'move' then
if Drawing.in_drawing(drawing, line_cache, pmx, pmy, State.left,State.right) then
drawing.pending.target_point.x = mx
drawing.pending.target_point.y = my
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
end
else
-- do nothing
end
end
function Drawing.relax_constraints(drawing, p)
for _,shape in ipairs(drawing.shapes) do
if shape.mode == 'manhattan' then
if shape.p1 == p then
shape.mode = 'line'
elseif shape.p2 == p then
shape.mode = 'line'
end
elseif shape.mode == 'rectangle' or shape.mode == 'square' then
for _,v in ipairs(shape.vertices) do
if v == p then
shape.mode = 'polygon'
end
end
end
end
end
function Drawing.mouse_press(State, drawing_index, x,y, mouse_button)
love.graphics.circle('line', cx,cy, Drawing.pixels(r, width))
elseif shape.mode == 'arc' then
local center = drawing.points[shape.center]
if mx < 0 or mx >= 256 or my < 0 or my >= drawing.h then
return
end
shape.end_angle = geom.angle_with_hint(center.x,center.y, mx,my, shape.end_angle)
local cx,cy = px(center.x), py(center.y)
love.graphics.arc('line', 'open', cx,cy, Drawing.pixels(shape.radius, width), shape.start_angle, shape.end_angle, 360)
elseif shape.mode == 'move' then
-- nothing pending; changes are immediately committed
elseif shape.mode == 'name' then
-- nothing pending; changes are immediately committed
else
print(shape.mode)
assert(false)
end
end
function Drawing.in_drawing(drawing, line_cache, x,y, left,right)
if line_cache.starty == nil then return false end -- outside current page
local width = right-left
return y >= line_cache.starty and y < line_cache.starty + Drawing.pixels(drawing.h, width) and x >= left and x < right
end
local r = round(geom.dist(center.x, center.y, mx, my))
local cx,cy = px(center.x), py(center.y)
if show_line_numbers then
App.color(Line_number_color)
love.graphics.print(line_index, State.left-Line_number_width*App.width('m')+10,y)
end
initialize_color()
function Text.draw(State, line_index, y, startpos, hide_cursor, show_line_numbers)
local line = State.lines[line_index]
local line_cache = State.line_cache[line_index]
line_cache.starty = y
line_cache.startpos = startpos
edit.put_cursor_on_next_text_line(State)
for i=1,math.floor(-dy) do
Text.down(State)
end
edit.put_cursor_on_next_text_line(State)
for i=1,math.floor(dy) do
Text.up(State)
end
elseif dy < 0 then
State.cursor1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos}
y, screen_bottom1.pos = Text.draw(State, line_index, y, startpos, hide_cursor, show_line_numbers)
--? print('=> y', y)
elseif line.mode == 'drawing' then
y = y+Drawing_padding_top
Drawing.draw(State, line_index, y)
y = y + Drawing.pixels(line.h, State.width) + Drawing_padding_bottom
else
print(line.mode)
assert(false)
local buttonx = State.left-Margin_left+4
if show_line_numbers then
buttonx = 4 -- HACK: position draw buttons at a fixed x on screen
end
button(State, 'draw', {x=buttonx, y=y+4, w=12,h=12, color={1,1,0},
icon = icon.insert_drawing,
onpress1 = function()
Drawing.before = snapshot(State, line_index-1, line_index)
table.insert(State.lines, line_index, {mode='drawing', y=y, h=256/2, points={}, shapes={}, pending={}})
table.insert(State.line_cache, line_index, {})
if State.cursor1.line >= line_index then
State.cursor1.line = State.cursor1.line+1
end
schedule_save(State)
record_undo_event(State, {before=Drawing.before, after=snapshot(State, line_index-1, line_index+1)})
end,
})
function edit.draw(State, hide_cursor, show_line_numbers)
State.button_handlers = {}
App.color(Text_color)
function edit.put_cursor_on_next_text_line(State)
while true do
if State.cursor1.line >= #State.lines then
break
end
if State.lines[State.cursor1.line].mode == 'text' then
break
end
State.cursor1.line = State.cursor1.line+1
State.cursor1.pos = 1
end
end
edit.put_cursor_on_next_text_line(State)
end
end
function edit.invalid1(State, loc1)
left = math.floor(left), -- left margin for text; line numbers go to the left of this
right = math.floor(right),
edit.draw(Editor_state, --[[hide cursor?]] Show_file_navigator, --[[show line numbers]] true)
if Show_log_browser_side then
-- divider
App.color(Divider_color)
love.graphics.rectangle('fill', App.screen.width/2-1,Menu_status_bar_height, 3,App.screen.height)
--
love.window.setTitle('text.love - source - '..Editor_state.filename)
source.switch_to_file(s..'.lua')
love.window.setTitle('lines.love - source - '..Editor_state.filename)
reset_file_navigator()
end
function move_candidate_to_front(s)
local index = array.find(File_navigation.all_candidates, s)
assert(index)
table.remove(File_navigation.all_candidates, index)
table.insert(File_navigation.all_candidates, 1, s)
end
function reset_file_navigator()
Show_file_navigator = false
File_navigation.index = 1
File_navigation.filter = ''
File_navigation.candidates = File_navigation.all_candidates
end
App.screen.width - Test_margin_right,
Test_margin_right = 0
-- Insulate tests from some key globals so I don't have to change the vast
-- majority of tests when they're modified for the real app.
if State.next_save and State.next_save < Current_time then
end
State.search_backup = {
cursor={line=State.cursor1.line, pos=State.cursor1.pos},
screen_top={line=State.screen_top1.line, pos=State.screen_top1.pos},
}