JJ74YKGVDPNVI54TXGSXVS5ORMYHCWSILAMVVHQQXWUA65GIG7EAC
Q7AM2SYRQNFR6XKFVC2XQYVHDGK64JDYFX4J6NQ2ESR6D75OTEBAC
QZUFJMD5OTAZGSUO4HSJ2NNNRJR7NOKIVOIIGHWM6IF4PFNMQZHAC
RKSQE3PJXJCH4NVBACWIB33H5MMNCEEQ6NHMFARMM2IV55IGBORAC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
ICUW7F3XQLURK4LSNPH5E3NDEFSRHKATEUHH2UPFJTMHYR3ZJF3QC
4AC6J55RTWH6FQYHQ64Y3EGF5A27Q2DHJ2XB2LXWZQEYXM53BYLAC
3BFFX2I3V7N7QJ4Z6CKICF52IRKMSLT63MMZZ34JZPFYAZELJ4EQC
O4ZGUPZNPNAQUCBV47GSEH33HGIXYODGDMOG2PM3T6D7EVR5YEEAC
3GITFJZKVNOZGJR24ANV4FASDIXMCGMLTSVLIMXPVO2QYKYIHABAC
SPSW74Y5OJ54Y7VQ3SJFCJR5CYDKTR4A3TOEVZODDZLUSDDU2GZAC
GX5PD3CLX63YPRCVKQTLSPDZTBWLZFJ4G6LJTPSMR6UGXFBM4AYAC
LLQC2M2IMEJBJQXZTKC3OAKG5WKHSERXKAKCYHQRUZZD6CVRIHAQC
6PCE7VUWEE5UVSE3ZZSQAMGUJDDHOBNO2MVD6POUWFP7UY7WOZHAC
3TDOZESEOYHGF6LYKR6PYSPNFI3QUGED2BKM5LUDEKJKRIX3ACEAC
MTJEVRJR5GLWUSK7HMIM4UXM6GS6O6YCRWJT3DUSU2RYMHCQNOEQC
G3DLS5OUO77V4MC6754KTETRCTVUBYBHMGR7MTV52IYYM7QA3ROQC
QAMVLUK22RP5RBDTDV5XVPQCSJUWDWESV4TRCUTNUM46E26BH2AQC
JOPVPUSAMMU6RFVDQR4NJC4GNNUFB7GPKVH7OS5FKCYS5QZ53VLQC
5XMBCKJZ7YCUOOQWWZRNLXMXD3MUYC2VAF3VKA4BIEHQRPDQMUMAC
2QLTVKM6MVC25L44BSHKPZAXOOLK2VAUCGCYRUDRXXNYNSWDIWQAC
KHOQZJWF3SNBCKLU5A7YDKPI6QHKZN7TERN2CRLB7GHG5GYBNNLAC
VTCPDL3ATJW4KWWCRDKOI2HG36JEBIKFLFYFNGWTZEUIAA4M3U5AC
3VHUIIATPOF7FXB7NTL5MESCV5BCQACII2D7QZ4UIUCBX3CWXMMAC
KKQKPGCIHAG2JESQAWEMCBTAKBDC5AVIQ6LCZ2ORQM2AUCFQYLSQC
3PSFWAILGRA4OYXWS2DX7VF332AIBPYBXHEA4GIQY2XEJVD65UMAC
ZJ7HAYDJZ6ET7CJ5566C4Z53MTCAEQBY3U5XM7VAWB5JHAYGMAFAC
F52PSTYSIIUD7UPEVLEJPVSBQU7IKVHM4GN4YASNSKFP4MRE6S6AC
SNQM42QARHDYXSD5NF3O5HFRL34SFEPYV4ZIC3WJL4KYSU7MD2YAC
IDS27PX6ITX6XVQ7PAPNGQBQUHBSM4WY2TBI4PU37PCJBYTVJ6UAC
Q65423XUYWJ5ESAH2B63MJKJUXSTQDANPZRRMQNYTDF3YGT5HLRAC
ORKN6EOBUFVAD2TXYW5OIKSL55RU24LOFDTTTXHDZUZ57QRDCY7QC
REAIVN7WJ3JMUKLX4BIACO2VMNHVTWLP3DMXPYD7PHVSYFFSV64QC
R2ASHK5CEE3PTRLS37GP4PXJ7HIGJ6UD72KKBI57UDJI7VRROQGQC
2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC
CQVWNL4MQYXJVKECYVKSUMRXYMQVEMYUBHHDTDMEU5GOZ67M7QOAC
QMRQL2FOIIXU3PCSH7UQIDRLKJN2DQHB5IUL4TLBVANNHWWETL6AC
MBAJPTDJ4KHWACEHWYGCFMHPQYM6FQKCSIIDKWCE765UI3VTDMIAC
CRBLAWBOTECOU5MFURWCRBR43OO7NWIHP5LC35IMGTQKN73AUS6AC
-- The modifiers didn't change the key. Handle it in keychord_press.
--== shortcuts that mutate text (must schedule_save)
record_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)})
schedule_save(State)
record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
schedule_save(State)
-- The modifiers didn't change the key. Handle it in keychord_press.
schedule_save(State)
record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
schedule_save(State)
-- dispatch to drawing or text
elseif App.mouse_down(1) or chord:sub(1,2) == 'C-' then
local drawing_index, drawing = Drawing.current_drawing(State)
if drawing_index then
local before = snapshot(State, drawing_index)
record_undo_event(State, {before=before, after=snapshot(State, drawing_index)})
schedule_save(State)
end
elseif chord == 'escape' and not App.mouse_down(1) then
for _,line in ipairs(State.lines) do
if line.mode == 'drawing' then
line.show_help = false
end
end
if chord == 'return' then
State.current_drawing_mode = State.previous_drawing_mode
State.previous_drawing_mode = nil
else
local before = snapshot(State, State.lines.current_drawing_index)
local drawing = State.lines.current_drawing
local p = drawing.points[drawing.pending.target_point]
if chord == 'escape' then
p.name = nil
record_undo_event(State, {before=before, after=snapshot(State, State.lines.current_drawing_index)})
elseif chord == 'backspace' then
local len = utf8.len(p.name)
State.line_height = math.floor(font_height*1.3)
end
--== some methods for tests
-- 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.
Test_margin_left = 25
Test_margin_right = 0
function edit.initialize_test_state()
-- if you change these values, tests will start failing
return edit.initialize_state(
15, -- top margin
Test_margin_left,
App.screen.width - Test_margin_right,
15) -- line height
end
-- all text_input events are also keypresses
-- TODO: handle chords of multiple keys
function edit.run_after_text_input(State, t)
edit.keychord_press(State, t)
edit.text_input(State, t)
edit.key_release(State, t)
App.screen.contents = {}
edit.update(State, 0)
edit.draw(State)
end
-- not all keys are text_input
App.screen.contents = {}
edit.update(State, 0)
edit.draw(State)
end
function edit.run_after_mouse_click(State, x,y, mouse_button)
App.fake_mouse_press(x,y, mouse_button)
edit.mouse_press(State, x,y, mouse_button)
App.fake_mouse_release(x,y, mouse_button)
edit.mouse_release(State, x,y, mouse_button)
App.screen.contents = {}
edit.update(State, 0)
edit.draw(State)
end
function edit.run_after_mouse_press(State, x,y, mouse_button)
App.fake_mouse_press(x,y, mouse_button)
edit.mouse_press(State, x,y, mouse_button)
App.screen.contents = {}
edit.update(State, 0)
edit.draw(State)
end
function edit.run_after_mouse_release(State, x,y, mouse_button)
App.fake_mouse_release(x,y, mouse_button)
edit.mouse_release(State, x,y, mouse_button)
App.screen.contents = {}
edit.update(State, 0)
edit.draw(State)
end