split keyboard handling between Text and Drawing

[?]
May 18, 2022, 5:36 AM
XNFTJHC4QSHNSIWNN7K6QZEZ37GTQYKHS4EPNSVPQCUSWREROGIQC

Dependencies

  • [2] BULPIBEG beginnings of a module for the text editor
  • [3] VHQCNMAR several more modules
  • [4] NUA5NOPI join lines on delete
  • [5] DV4TUFCN rename
  • [6] NCQ4XLLB jump between lines on left/right
  • [7] EF6MFB46 assume we always have a filename
  • [8] VG54CQZT autosave in a couple more places
  • [9] V5TP27FP ctrl-+ and ctrl-- to adjust font size
  • [10] UTF73CBL reorg
  • [11] 6LJZN727 handle chords
  • [12] RJGZD4IN binary search to most natural up/down with proportional fonts
  • [13] 7IKRRESB longer names for indices in long loops
  • [14] WAZVXUV2 simplest possible way to straighten strokes
  • [15] 7Q4B6M2D esc to cancel a shape mid-click
  • [16] O2UFJ6G3 switch from freehand to just straight lines
  • [17] 3D5RFWHV stop handling drawings in cursor_pos computations
  • [18] G77XIN7M selecting a stroke
  • [19] JCSLDGAH beginnings of support for multiple shapes
  • [20] 3XD6M3CF refactor
  • [21] D2GCFTTT clean up repl functionality
  • [22] RXE6NQTN changing your mind mid-shape
  • [23] SNDZOK6Q slightly less strange now that we have the same two ways to move points as any other operation
  • [24] JRLBUB6L more intuitive point delete from polygons
  • [25] BJ5X5O4A let's prevent the text cursor from ever getting on a drawing
  • [26] ZOOY3ME4 new mode: circle arc
  • [27] FBDRL6LH delete points or shapes
  • [28] 6PUNJS5B backspace
  • [29] OFA3PRBS autosave on keystrokes
  • [30] 3CS5KKCI up/down cursor movement
  • [31] JS6JSYOT online contextual help
  • [32] FQJ2LBUR respect zoom when drawing drawings
  • [33] HRWN5V6J Devine's suggestion to try to live with just freehand
  • [34] NJ6ZL7PW split lines on enter
  • [35] 5RTXACUS .
  • [36] 5TIFKJ7S handle space key
  • [37] H7OEU6WP experimental approach to combining keyboard and mouse while drawing
  • [38] IHG5RXP5 allow text to be typed while mouse hovers over drawing
  • [39] MGOQ5XAV start uppercasing globals
  • [40] LBQAAJN4 load/save freehand strokes
  • [41] PRPPZGDY speed up some obvious common cases
  • [42] NL5J7Z5H new mode: polygon
  • [43] U76D4P36 fix a typo
  • [44] BLWAYPKV extract a module
  • [45] FMQ74DP3 new mode: circle
  • [46] VXORMHME delete experimental REPL
  • [47] IK3N7J3B reset zoom
  • [48] AVQ5MC5D finish uppercasing all globals
  • [49] M36DBSDE bit more polish to help screen
  • [50] FEEGTRGQ bugfix: duplicate character on enter
  • [51] KVHUFUFV reorg
  • [52] IYW7X3WL left/right cursor movement, deleting characters
  • [53] TEIKBO2T don't try to append text to drawings
  • [54] VVXVV2D2 change data model; text can now have metadata
  • [55] HWPK4SMP new mode: manhattan
  • [56] 62ST7SV3 bugfix typo
  • [57] T76KKDWZ turn strokes into horizontal and vertical lines
  • [58] YKRF5V3Z starting to load/save
  • [59] I7MA5UOO move
  • [60] EFMLTMZG bugfix: restrict strokes to the drawing they started in
  • [61] XX7G2FFJ intermingle freehand line drawings with text
  • [62] TNTYISW6 rename
  • [63] ZUOL7X6V move
  • [64] PLLSUOCI some missing transitions
  • [65] KCIM5UTV revert: back to freehand
  • [66] IFGAJAF7 add a level of indirection to vertices of shapes
  • [67] OTIBCAUJ love2d scaffold
  • [68] WDWXNW7V slightly strange way to move points

Change contents

  • edit in text.lua at line 3
    [2.43]
    [2.43]
    local utf8 = require 'utf8'
  • edit in text.lua at line 13
    [2.458]
    [2.458]
    end
    end
    function love.textinput(t)
    if love.mouse.isDown('1') then return end
    if Lines[Cursor_line].mode == 'drawing' then return end
    local byte_offset
    if Cursor_pos > 1 then
    byte_offset = utf8.offset(Lines[Cursor_line].data, Cursor_pos-1)
    else
    byte_offset = 0
    end
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_offset)..t..string.sub(Lines[Cursor_line].data, byte_offset+1)
    Cursor_pos = Cursor_pos+1
    save_to_disk(Lines, Filename)
    end
    -- Don't handle any keys here that would trigger love.textinput above.
    function Text.keychord_pressed(chord)
    if chord == 'return' then
    local byte_offset = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    table.insert(Lines, Cursor_line+1, {mode='text', data=string.sub(Lines[Cursor_line].data, byte_offset)})
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_offset-1)
    Cursor_line = Cursor_line+1
    Cursor_pos = 1
    save_to_disk(Lines, Filename)
    elseif chord == 'left' then
    assert(Lines[Cursor_line].mode == 'text')
    if Cursor_pos > 1 then
    Cursor_pos = Cursor_pos-1
    else
    local new_cursor_line = Cursor_line
    while new_cursor_line > 1 do
    new_cursor_line = new_cursor_line-1
    if Lines[new_cursor_line].mode == 'text' then
    Cursor_line = new_cursor_line
    Cursor_pos = #Lines[Cursor_line].data+1
    break
    end
    end
    end
    elseif chord == 'right' then
    assert(Lines[Cursor_line].mode == 'text')
    if Cursor_pos <= #Lines[Cursor_line].data then
    Cursor_pos = Cursor_pos+1
    else
    local new_cursor_line = Cursor_line
    while new_cursor_line <= #Lines-1 do
    new_cursor_line = new_cursor_line+1
    if Lines[new_cursor_line].mode == 'text' then
    Cursor_line = new_cursor_line
    Cursor_pos = 1
    break
    end
    end
    end
    elseif chord == 'home' then
    Cursor_pos = 1
    elseif chord == 'end' then
    Cursor_pos = #Lines[Cursor_line].data+1
    elseif chord == 'backspace' then
    if Cursor_pos > 1 then
    local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos-1)
    local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    if byte_start then
    if byte_end then
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end)
    else
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)
    end
    Cursor_pos = Cursor_pos-1
    end
    elseif Cursor_line > 1 then
    if Lines[Cursor_line-1].mode == 'drawing' then
    table.remove(Lines, Cursor_line-1)
    else
    -- join lines
    Cursor_pos = utf8.len(Lines[Cursor_line-1].data)+1
    Lines[Cursor_line-1].data = Lines[Cursor_line-1].data..Lines[Cursor_line].data
    table.remove(Lines, Cursor_line)
    end
    Cursor_line = Cursor_line-1
    end
    save_to_disk(Lines, Filename)
    elseif chord == 'delete' then
    if Cursor_pos <= #Lines[Cursor_line].data then
    local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos+1)
    if byte_start then
    if byte_end then
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end)
    else
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)
    end
    -- no change to Cursor_pos
    end
    elseif Cursor_line < #Lines then
    if Lines[Cursor_line+1].mode == 'drawing' then
    table.remove(Lines, Cursor_line+1)
    else
    -- join lines
    Lines[Cursor_line].data = Lines[Cursor_line].data..Lines[Cursor_line+1].data
    table.remove(Lines, Cursor_line+1)
    end
    end
    save_to_disk(Lines, Filename)
    elseif chord == 'up' then
    assert(Lines[Cursor_line].mode == 'text')
    local new_cursor_line = Cursor_line
    while new_cursor_line > 1 do
    new_cursor_line = new_cursor_line-1
    if Lines[new_cursor_line].mode == 'text' then
    local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos)
    Cursor_line = new_cursor_line
    Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos)
    break
    end
    end
    elseif chord == 'down' then
    assert(Lines[Cursor_line].mode == 'text')
    local new_cursor_line = Cursor_line
    while new_cursor_line < #Lines do
    new_cursor_line = new_cursor_line+1
    if Lines[new_cursor_line].mode == 'text' then
    local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos)
    Cursor_line = new_cursor_line
    Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos)
    break
    end
    end
  • edit in main.lua at line 248
    [9.876][9.23:50](),[9.1934][9.23:50](),[9.2004][9.23:50](),[9.2010][9.23:50](),[9.451][9.23:50](),[9.50][9.3:47](),[9.47][9.2747:2805](),[9.2805][5.3:23](),[5.23][9.2806:2831](),[9.509][9.2806:2831](),[9.2831][5.24:93](),[5.93][9.597:604](),[9.947][9.597:604](),[9.2899][9.597:604](),[9.3285][9.597:604](),[9.597][9.597:604](),[9.604][5.94:114](),[5.114][9.623:629](),[9.623][9.623:629](),[9.629][5.115:250](),[5.250][9.3033:3061](),[9.3033][9.3033:3061](),[9.3061][7.36:68](),[7.68][9.85:90](),[9.121][9.85:90](),[9.85][9.85:90]()
    function love.textinput(t)
    if love.mouse.isDown('1') then return end
    if Lines[Cursor_line].mode == 'drawing' then return end
    local byte_offset
    if Cursor_pos > 1 then
    byte_offset = utf8.offset(Lines[Cursor_line].data, Cursor_pos-1)
    else
    byte_offset = 0
    end
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_offset)..t..string.sub(Lines[Cursor_line].data, byte_offset+1)
    Cursor_pos = Cursor_pos+1
    save_to_disk(Lines, Filename)
    end
  • replacement in main.lua at line 249
    [9.123][9.123:196](),[9.196][9.1:25](),[9.25][9.196:224](),[9.196][9.196:224](),[9.224][9.3:76](),[9.76][9.3:247](),[9.247][8.3:37](),[8.37][9.3:33](),[9.247][9.3:33](),[9.358][9.3:33](),[9.3229][9.3:33](),[9.33][6.3:49](),[6.49][9.33:92](),[9.33][9.33:92](),[9.92][6.50:362](),[6.362][9.92:131](),[9.92][9.92:131](),[9.131][6.363:409](),[6.409][9.131:214](),[9.131][9.131:214](),[9.214][6.410:705](),[6.705][9.214:389](),[9.214][9.214:389](),[9.389][9.31:66](),[9.516][9.31:66](),[9.3229][9.31:66](),[9.555][9.31:66](),[9.66][9.3230:3405](),[9.3405][9.867:917](),[9.3667][9.867:917](),[9.867][9.867:917](),[9.917][9.3406:3542](),[9.3542][9.1053:1066](),[9.3804][9.1053:1066](),[9.1053][9.1053:1066](),[9.1066][9.3543:3632](),[9.3632][9.1155:1167](),[9.3894][9.1155:1167](),[9.1155][9.1155:1167](),[9.1167][9.3633:3667](),[9.3667][9.1201:1211](),[9.1201][9.1201:1211](),[9.1211][9.3668:3796](),[9.1339][9.1377:1388](),[9.3796][9.1377:1388](),[9.3991][9.1377:1388](),[9.1377][9.1377:1388](),[9.1388][4.3:25](),[4.25][9.3797:3984](),[9.4014][9.3797:3984](),[9.1549][9.1411:1421](),[9.3984][9.1411:1421](),[9.4201][9.1411:1421](),[9.1411][9.1411:1421](),[9.1421][9.3985:4019](),[9.4079][9.1391:1399](),[9.1391][9.1391:1399](),[9.1399][8.38:72](),[8.72][9.26:58](),[9.4228][9.26:58](),[9.4298][9.26:58](),[9.2192][9.26:58](),[9.58][9.4229:4428](),[9.4428][9.257:307](),[9.4498][9.257:307](),[9.257][9.257:307](),[9.307][9.4429:4565](),[9.4565][9.443:456](),[9.4635][9.443:456](),[9.443][9.443:456](),[9.456][9.4566:4655](),[9.4655][9.545:557](),[9.4725][9.545:557](),[9.545][9.545:557](),[9.557][9.4656:4691](),[9.4691][4.26:330](),[4.330][9.592:610](),[9.4691][9.592:610](),[9.592][9.592:610](),[9.610][8.73:107](),[8.107][9.525:553](),[9.276][9.525:553](),[9.655][9.525:553](),[9.2192][9.525:553](),[9.525][9.525:553](),[9.553][9.4692:4778](),[9.4778][9.1636:1711](),[9.1636][9.1636:1711](),[9.1711][9.4773:4825](),[9.4825][2.1641:1718](),[2.1718][9.4851:4889](),[9.4851][9.4851:4889](),[9.4889][2.1719:1808](),[2.1808][9.1874:1888](),[9.4973][9.1874:1888](),[9.4982][9.1874:1888](),[9.237][9.1874:1888](),[9.37][9.284:294](),[9.1888][9.284:294](),[9.284][9.284:294](),[9.78][9.1510:1518](),[9.294][9.1510:1518](),[9.404][9.1510:1518](),[9.715][9.1510:1518](),[9.2342][9.1510:1518](),[9.1510][9.1510:1518](),[9.1518][9.716:746](),[9.746][9.4974:5060](),[9.5060][9.5030:5068](),[9.1975][9.5030:5068](),[9.5068][9.2013:2055](),[9.2013][9.2013:2055](),[9.2055][9.5069:5121](),[9.5121][2.1809:1886](),[2.1886][9.5133:5171](),[9.5133][9.5133:5171](),[9.5171][2.1887:1976](),[2.1976][9.2218:2232](),[9.5255][9.2218:2232](),[9.5278][9.2218:2232](),[9.531][9.2218:2232](),[9.2232][9.578:588](),[9.578][9.578:588](),[9.156][9.913:921](),[9.532][9.913:921](),[9.588][9.913:921](),[9.2492][9.913:921](),[9.913][9.913:921](),[9.921][9.137:166](),[9.166][9.5256:5354](),[9.60][9.186:215](),[9.5354][9.186:215](),[9.186][9.186:215](),[9.215][9.5355:5453](),[9.5453][9.30:59](),[9.30][9.30:59](),[9.59][9.5454:5547](),[9.120][9.656:684](),[9.235][9.656:684](),[9.5547][9.656:684](),[9.921][9.656:684](),[9.684][9.2:61](),[9.1135][9.2:61](),[9.61][3.2747:2793](),[3.2793][9.99:124](),[9.99][9.99:124](),[9.124][9.499:559](),[9.1135][9.499:559](),[9.559][3.2794:2832](),[3.2832][9.560:620](),[9.5578][9.560:620](),[9.141][9.560:620](),[9.620][3.2833:2870](),[3.2870][9.32:86](),[9.5608][9.32:86](),[9.32][9.32:86](),[9.86][3.2871:2954](),[3.2954][9.2:49](),[9.125][9.2:49](),[9.49][3.2955:3085](),[3.3085][9.171:369](),[9.171][9.171:369](),[9.369][9.222:407](),[9.222][9.222:407](),[9.407][3.3086:3380](),[3.3380][9.2247:2293](),[9.2247][9.2247:2293](),[9.2293][9.621:681](),[9.681][3.3381:3554](),[3.3554][9.2126:2159](),[9.2126][9.2126:2159](),[9.2159][3.3555:3711](),[3.3711][9.2291:2414](),[9.2291][9.2291:2414](),[9.2414][3.3712:3783](),[3.3783][9.408:462](),[9.2485][9.408:462](),[9.462][3.3784:3866](),[3.3866][9.370:417](),[9.528][9.370:417](),[9.417][3.3867:3993](),[3.3993][9.535:621](),[9.535][9.535:621](),[9.621][9.571:774](),[9.571][9.571:774](),[9.774][9.141:195](),[9.1410][9.141:195](),[9.2293][9.141:195](),[9.2485][9.141:195](),[9.141][9.141:195](),[9.195][3.3994:4074](),[3.4074][9.775:822](),[9.259][9.775:822](),[9.822][3.4075:4197](),[3.4197][9.936:1068](),[9.936][9.936:1068](),[9.1068][9.622:727](),[9.727][9.1068:1076](),[9.1068][9.1068:1076](),[9.1076][9.306:340](),[9.306][9.306:340](),[9.446][9.877:906](),[9.2179][9.877:906](),[9.1135][9.877:906](),[9.906][3.4198:4292](),[9.433][9.958:978](),[3.4292][9.958:978](),[9.958][9.958:978](),[9.978][9.2180:2215](),[9.2215][9.1014:1022](),[9.3388][9.1014:1022](),[9.1014][9.1014:1022](),[9.1022][9.1323:1377](),[9.1377][3.4293:4386](),[3.4386][9.728:775](),[9.1454][9.728:775](),[9.775][3.4387:4509](),[3.4509][9.889:936](),[9.889][9.889:936](),[9.936][9.1120:1385](),[9.1120][9.1120:1385](),[9.1385][9.1454:1493](),[9.1454][9.1454:1493](),[9.1493][9.682:742](),[9.742][3.4510:4609](),[9.486][9.92:112](),[3.4609][9.92:112](),[9.92][9.92:112](),[9.112][9.2216:2254](),[9.151][9.111:119](),[9.2254][9.111:119](),[9.3418][9.111:119](),[9.111][9.111:119](),[9.119][9.743:803](),[9.803][3.4610:4670](),[9.539][9.84:126](),[3.4670][9.84:126](),[9.84][9.84:126](),[9.126][9.474:482](),[9.482][9.804:864](),[9.864][3.4671:4727](),[9.497][9.910:930](),[3.4727][9.910:930](),[9.910][9.910:930](),[9.930][3.4728:4883](),[3.4883][9.5279:5309](),[9.6106][9.5279:5309](),[9.379][9.5279:5309](),[9.5309][9.409:471](),[9.409][9.409:471](),[9.471][3.4884:4940](),[9.546][9.517:537](),[3.4940][9.517:537](),[9.517][9.517:537](),[9.537][3.4941:5096](),[3.5096][9.5310:5340](),[9.6230][9.5310:5340](),[9.660][9.5310:5340](),[9.5340][9.547:615](),[9.1064][9.547:615](),[9.615][3.5097:5153](),[3.5153][9.663:730](),[9.663][9.663:730](),[9.730][3.5154:5203](),[3.5203][9.3:326](),[9.771][9.3:326](),[9.326][9.804:873](),[9.804][9.804:873](),[9.873][3.5204:5264](),[9.592][9.925:974](),[3.5264][9.925:974](),[9.925][9.925:974](),[9.974][9.249:317](),[9.317][3.5265:5319](),[3.5319][9.363:414](),[9.363][9.363:414](),[9.414][9.1064:1072](),[9.974][9.1064:1072](),[9.1064][9.1064:1072](),[9.1072][9.415:478](),[9.478][9.5341:5376](),[9.5376][9.78:146](),[9.78][9.78:146](),[9.1812][9.1812:1822](),[9.342][9.342:350]()
    -- Don't handle any keys here that would trigger love.textinput above.
    -- shortcuts for text
    if chord == 'return' then
    local byte_offset = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    table.insert(Lines, Cursor_line+1, {mode='text', data=string.sub(Lines[Cursor_line].data, byte_offset)})
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_offset-1)
    Cursor_line = Cursor_line+1
    Cursor_pos = 1
    save_to_disk(Lines, Filename)
    elseif chord == 'left' then
    assert(Lines[Cursor_line].mode == 'text')
    if Cursor_pos > 1 then
    Cursor_pos = Cursor_pos-1
    else
    local new_cursor_line = Cursor_line
    while new_cursor_line > 1 do
    new_cursor_line = new_cursor_line-1
    if Lines[new_cursor_line].mode == 'text' then
    Cursor_line = new_cursor_line
    Cursor_pos = #Lines[Cursor_line].data+1
    break
    end
    end
    end
    elseif chord == 'right' then
    assert(Lines[Cursor_line].mode == 'text')
    if Cursor_pos <= #Lines[Cursor_line].data then
    Cursor_pos = Cursor_pos+1
    else
    local new_cursor_line = Cursor_line
    while new_cursor_line <= #Lines-1 do
    new_cursor_line = new_cursor_line+1
    if Lines[new_cursor_line].mode == 'text' then
    Cursor_line = new_cursor_line
    Cursor_pos = 1
    break
    end
    end
    end
    elseif chord == 'home' then
    Cursor_pos = 1
    elseif chord == 'end' then
    Cursor_pos = #Lines[Cursor_line].data+1
    -- transitioning between drawings and text
    elseif chord == 'backspace' then
    if Cursor_pos > 1 then
    local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos-1)
    local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    if byte_start then
    if byte_end then
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end)
    else
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)
    end
    Cursor_pos = Cursor_pos-1
    end
    elseif Cursor_line > 1 then
    if Lines[Cursor_line-1].mode == 'drawing' then
    table.remove(Lines, Cursor_line-1)
    else
    -- join lines
    Cursor_pos = utf8.len(Lines[Cursor_line-1].data)+1
    Lines[Cursor_line-1].data = Lines[Cursor_line-1].data..Lines[Cursor_line].data
    table.remove(Lines, Cursor_line)
    end
    Cursor_line = Cursor_line-1
    end
    save_to_disk(Lines, Filename)
    elseif chord == 'delete' then
    if Cursor_pos <= #Lines[Cursor_line].data then
    local byte_start = utf8.offset(Lines[Cursor_line].data, Cursor_pos)
    local byte_end = utf8.offset(Lines[Cursor_line].data, Cursor_pos+1)
    if byte_start then
    if byte_end then
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)..string.sub(Lines[Cursor_line].data, byte_end)
    else
    Lines[Cursor_line].data = string.sub(Lines[Cursor_line].data, 1, byte_start-1)
    end
    -- no change to Cursor_pos
    end
    elseif Cursor_line < #Lines then
    if Lines[Cursor_line+1].mode == 'drawing' then
    table.remove(Lines, Cursor_line+1)
    else
    -- join lines
    Lines[Cursor_line].data = Lines[Cursor_line].data..Lines[Cursor_line+1].data
    table.remove(Lines, Cursor_line+1)
    end
    end
    save_to_disk(Lines, Filename)
    elseif chord == 'up' then
    assert(Lines[Cursor_line].mode == 'text')
    local new_cursor_line = Cursor_line
    while new_cursor_line > 1 do
    new_cursor_line = new_cursor_line-1
    if Lines[new_cursor_line].mode == 'text' then
    local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos)
    Cursor_line = new_cursor_line
    Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos)
    break
    end
    end
    elseif chord == 'down' then
    assert(Lines[Cursor_line].mode == 'text')
    local new_cursor_line = Cursor_line
    while new_cursor_line < #Lines do
    new_cursor_line = new_cursor_line+1
    if Lines[new_cursor_line].mode == 'text' then
    local old_x = Text.cursor_x(Lines[new_cursor_line].data, Cursor_pos)
    Cursor_line = new_cursor_line
    Cursor_pos = Text.nearest_cursor_pos(Lines[Cursor_line].data, old_x, Cursor_pos)
    break
    end
    end
    elseif chord == 'C-=' then
    Drawing_width = Drawing_width/Zoom
    Zoom = Zoom+0.5
    Drawing_width = Drawing_width*Zoom
    elseif chord == 'C--' then
    Drawing_width = Drawing_width/Zoom
    Zoom = Zoom-0.5
    Drawing_width = Drawing_width*Zoom
    elseif chord == 'C-0' then
    Drawing_width = Drawing_width/Zoom
    Zoom = 1.5
    Drawing_width = Drawing_width*Zoom
    -- shortcuts for drawings
    elseif chord == 'escape' and love.mouse.isDown('1') then
    local drawing = Drawing.current_drawing()
    drawing.pending = {}
    elseif chord == 'C-f' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'freehand'
    elseif chord == 'C-g' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'polygon'
    elseif love.mouse.isDown('1') and chord == 'g' then
    Current_drawing_mode = 'polygon'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
    elseif drawing.pending.mode == 'line' or drawing.pending.mode == 'manhattan' then
    if drawing.pending.vertices == nil then
    drawing.pending.vertices = {drawing.pending.p1}
    end
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.vertices = {drawing.pending.center}
    end
    drawing.pending.mode = 'polygon'
    elseif love.mouse.isDown('1') and chord == 'p' and Current_drawing_mode == 'polygon' then
    local drawing = Drawing.current_drawing()
    local mx,my = Drawing.coord(love.mouse.getX()-16), Drawing.coord(love.mouse.getY()-drawing.y)
    local j = Drawing.insert_point(drawing.points, mx,my)
    table.insert(drawing.pending.vertices, j)
    elseif chord == 'C-c' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'circle'
    elseif love.mouse.isDown('1') and chord == 'a' and Current_drawing_mode == 'circle' then
    local drawing = Drawing.current_drawing()
    drawing.pending.mode = 'arc'
    local mx,my = Drawing.coord(love.mouse.getX()-16), Drawing.coord(love.mouse.getY()-drawing.y)
    local j = Drawing.insert_point(drawing.points, mx,my)
    local center = drawing.points[drawing.pending.center]
    drawing.pending.radius = math.dist(center.x,center.y, mx,my)
    drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
    elseif love.mouse.isDown('1') and chord == 'c' then
    Current_drawing_mode = 'circle'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.center = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'line' or drawing.pending.mode == 'manhattan' then
    drawing.pending.center = drawing.pending.p1
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.center = drawing.pending.vertices[1]
    end
    drawing.pending.mode = 'circle'
    elseif love.mouse.isDown('1') and chord == 'l' then
    Current_drawing_mode = 'line'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.p1 = drawing.pending.center
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.p1 = drawing.pending.vertices[1]
    end
    drawing.pending.mode = 'line'
    elseif chord == 'C-l' then
    Current_drawing_mode = 'line'
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    convert_line(drawing, shape)
    end
    elseif love.mouse.isDown('1') and chord == 'm' then
    Current_drawing_mode = 'manhattan'
    local drawing = Drawing.select_drawing_at_mouse()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'line' then
    -- do nothing
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.p1 = drawing.pending.vertices[1]
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.p1 = drawing.pending.center
    end
    drawing.pending.mode = 'manhattan'
    elseif chord == 'C-m' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'manhattan'
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    convert_horvert(drawing, shape)
    end
    elseif chord == 'C-s' and not love.mouse.isDown('1') then
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    smoothen(shape)
    end
    elseif chord == 'C-v' and not love.mouse.isDown('1') then
    local drawing,_,p = Drawing.select_point_at_mouse()
    if drawing then
    Previous_drawing_mode = Current_drawing_mode
    Current_drawing_mode = 'move'
    drawing.pending = {mode=Current_drawing_mode, target_point=p}
    Lines.current = drawing
    end
    elseif love.mouse.isDown('1') and chord == 'v' then
    local drawing,_,p = Drawing.select_point_at_mouse()
    if drawing then
    Previous_drawing_mode = Current_drawing_mode
    Current_drawing_mode = 'move'
    drawing.pending = {mode=Current_drawing_mode, target_point=p}
    Lines.current = drawing
    end
    elseif chord == 'C-d' and not love.mouse.isDown('1') then
    local drawing,i,p = Drawing.select_point_at_mouse()
    if drawing then
    for _,shape in ipairs(drawing.shapes) do
    if Drawing.contains_point(shape, i) then
    if shape.mode == 'polygon' then
    local idx = table.find(shape.vertices, i)
    assert(idx)
    table.remove(shape.vertices, idx)
    if #shape.vertices < 3 then
    shape.mode = 'deleted'
    end
    else
    shape.mode = 'deleted'
    end
    end
    end
    drawing.points[i].deleted = true
    end
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    shape.mode = 'deleted'
    end
    elseif chord == 'C-h' and not love.mouse.isDown('1') then
    local drawing = Drawing.select_drawing_at_mouse()
    if drawing then
    drawing.show_help = true
    end
    elseif chord == 'escape' and not love.mouse.isDown('1') then
    for _,line in ipairs(Lines) do
    if line.mode == 'drawing' then
    line.show_help = false
    end
    end
    [9.123]
    [9.350]
    if love.mouse.isDown('1') or chord:sub(1,2) == 'C-' then
    Drawing.keychord_pressed(chord)
    else
    Text.keychord_pressed(chord)
  • edit in main.lua at line 258
    [9.331][9.331:417](),[9.3391][9.857:871](),[9.857][9.857:871](),[9.118][9.871:875](),[9.871][9.871:875]()
    function table.find(h, x)
    for k,v in pairs(h) do
    if v == x then
    return k
    end
    end
    end
  • replacement in geom.lua at line 14
    [3.12094][3.12094:12155]()
    return math.dist(center.x,center.y, x,y) == shape.radius
    [3.12094]
    [3.12155]
    return geom.dist(center.x,center.y, x,y) == shape.radius
  • replacement in geom.lua at line 17
    [3.12237][3.12237:12288]()
    local dist = math.dist(center.x,center.y, x,y)
    [3.12237]
    [3.12288]
    local dist = geom.dist(center.x,center.y, x,y)
  • replacement in geom.lua at line 112
    [3.14613][3.14613:14652]()
    local angle = math.angle(ox,oy, x,y)
    [3.14613]
    [3.14652]
    local angle = geom.angle(ox,oy, x,y)
  • edit in drawing.lua at line 52
    [3.19077]
    [3.19077]
    function Drawing.keychord_pressed(chord)
    if chord == 'C-=' then
    Drawing_width = Drawing_width/Zoom
    Zoom = Zoom+0.5
    Drawing_width = Drawing_width*Zoom
    elseif chord == 'C--' then
    Drawing_width = Drawing_width/Zoom
    Zoom = Zoom-0.5
    Drawing_width = Drawing_width*Zoom
    elseif chord == 'C-0' then
    Drawing_width = Drawing_width/Zoom
    Zoom = 1.5
    Drawing_width = Drawing_width*Zoom
    elseif chord == 'escape' and love.mouse.isDown('1') then
    local drawing = Drawing.current_drawing()
    drawing.pending = {}
    elseif chord == 'C-f' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'freehand'
    elseif chord == 'C-g' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'polygon'
    elseif love.mouse.isDown('1') and chord == 'g' then
    Current_drawing_mode = 'polygon'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
    elseif drawing.pending.mode == 'line' or drawing.pending.mode == 'manhattan' then
    if drawing.pending.vertices == nil then
    drawing.pending.vertices = {drawing.pending.p1}
    end
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.vertices = {drawing.pending.center}
    end
    drawing.pending.mode = 'polygon'
    elseif love.mouse.isDown('1') and chord == 'p' and Current_drawing_mode == 'polygon' then
    local drawing = Drawing.current_drawing()
    local mx,my = Drawing.coord(love.mouse.getX()-16), Drawing.coord(love.mouse.getY()-drawing.y)
    local j = Drawing.insert_point(drawing.points, mx,my)
    table.insert(drawing.pending.vertices, j)
    elseif chord == 'C-c' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'circle'
    elseif love.mouse.isDown('1') and chord == 'a' and Current_drawing_mode == 'circle' then
    local drawing = Drawing.current_drawing()
    drawing.pending.mode = 'arc'
    local mx,my = Drawing.coord(love.mouse.getX()-16), Drawing.coord(love.mouse.getY()-drawing.y)
    local j = Drawing.insert_point(drawing.points, mx,my)
    local center = drawing.points[drawing.pending.center]
    drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
    drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
    elseif love.mouse.isDown('1') and chord == 'c' then
    Current_drawing_mode = 'circle'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.center = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'line' or drawing.pending.mode == 'manhattan' then
    drawing.pending.center = drawing.pending.p1
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.center = drawing.pending.vertices[1]
    end
    drawing.pending.mode = 'circle'
    elseif love.mouse.isDown('1') and chord == 'l' then
    Current_drawing_mode = 'line'
    local drawing = Drawing.current_drawing()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.p1 = drawing.pending.center
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.p1 = drawing.pending.vertices[1]
    end
    drawing.pending.mode = 'line'
    elseif chord == 'C-l' then
    Current_drawing_mode = 'line'
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    convert_line(drawing, shape)
    end
    elseif love.mouse.isDown('1') and chord == 'm' then
    Current_drawing_mode = 'manhattan'
    local drawing = Drawing.select_drawing_at_mouse()
    if drawing.pending.mode == 'freehand' then
    drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
    elseif drawing.pending.mode == 'line' then
    -- do nothing
    elseif drawing.pending.mode == 'polygon' then
    drawing.pending.p1 = drawing.pending.vertices[1]
    elseif drawing.pending.mode == 'circle' or drawing.pending.mode == 'arc' then
    drawing.pending.p1 = drawing.pending.center
    end
    drawing.pending.mode = 'manhattan'
    elseif chord == 'C-m' and not love.mouse.isDown('1') then
    Current_drawing_mode = 'manhattan'
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    convert_horvert(drawing, shape)
    end
    elseif chord == 'C-s' and not love.mouse.isDown('1') then
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    smoothen(shape)
    end
    elseif chord == 'C-v' and not love.mouse.isDown('1') then
    local drawing,_,p = Drawing.select_point_at_mouse()
    if drawing then
    Previous_drawing_mode = Current_drawing_mode
    Current_drawing_mode = 'move'
    drawing.pending = {mode=Current_drawing_mode, target_point=p}
    Lines.current = drawing
    end
    elseif love.mouse.isDown('1') and chord == 'v' then
    local drawing,_,p = Drawing.select_point_at_mouse()
    if drawing then
    Previous_drawing_mode = Current_drawing_mode
    Current_drawing_mode = 'move'
    drawing.pending = {mode=Current_drawing_mode, target_point=p}
    Lines.current = drawing
    end
    elseif chord == 'C-d' and not love.mouse.isDown('1') then
    local drawing,i,p = Drawing.select_point_at_mouse()
    if drawing then
    for _,shape in ipairs(drawing.shapes) do
    if Drawing.contains_point(shape, i) then
    if shape.mode == 'polygon' then
    local idx = table.find(shape.vertices, i)
    assert(idx)
    table.remove(shape.vertices, idx)
    if #shape.vertices < 3 then
    shape.mode = 'deleted'
    end
    else
    shape.mode = 'deleted'
    end
    end
    end
    drawing.points[i].deleted = true
    end
    local drawing,_,shape = Drawing.select_shape_at_mouse()
    if drawing then
    shape.mode = 'deleted'
    end
    elseif chord == 'C-h' and not love.mouse.isDown('1') then
    local drawing = Drawing.select_drawing_at_mouse()
    if drawing then
    drawing.show_help = true
    end
    elseif chord == 'escape' and not love.mouse.isDown('1') then
    for _,line in ipairs(Lines) do
    if line.mode == 'drawing' then
    line.show_help = false
    end
    end
    end
    end
  • replacement in drawing.lua at line 379
    [3.24958][3.24958:24999]()
    draw_shape(left,top, drawing, shape)
    [3.24958]
    [3.24999]
    Drawing.draw_shape(left,top, drawing, shape)
  • replacement in drawing.lua at line 416
    [3.26805][3.26805:26900]()
    love.graphics.circle('line', cx,cy, math.dist(cx,cy, love.mouse.getX(),love.mouse.getY()))
    [3.26805]
    [3.26900]
    love.graphics.circle('line', cx,cy, geom.dist(cx,cy, love.mouse.getX(),love.mouse.getY()))
  • edit in drawing.lua at line 434
    [3.27620]
    [9.1521]
    end
    function table.find(h, x)
    for k,v in pairs(h) do
    if v == x then
    return k
    end
    end