beginnings of support for multiple shapes

[?]
May 14, 2022, 8:08 PM
JCSLDGAH2F6AIY4Z6XM6K4LOMW7EFY3E4NF5YXLMHLTYTX3A4Z3QC

Dependencies

  • [2] KCIM5UTV revert: back to freehand
  • [3] HRWN5V6J Devine's suggestion to try to live with just freehand
  • [4] EFMLTMZG bugfix: restrict strokes to the drawing they started in
  • [5] TRCAEE2A clip drawings inside the border
  • [6] Z2CJVAPV lighter border for figures
  • [7] XX7G2FFJ intermingle freehand line drawings with text
  • [8] MNWHXPBL more lightweight; select just the stroke at the mouse
  • [9] D2GCFTTT clean up repl functionality
  • [10] 3XD6M3CF refactor
  • [11] O2UFJ6G3 switch from freehand to just straight lines
  • [12] G77XIN7M selecting a stroke
  • [13] T76KKDWZ turn strokes into horizontal and vertical lines
  • [14] JVRL5TWL store device-independent coordinates inside drawings
  • [15] OTIBCAUJ love2d scaffold
  • [16] 6LJZN727 handle chords
  • [17] 4NDYV4WD fix 2 bugs in line selection
  • [18] WAZVXUV2 simplest possible way to straighten strokes
  • [*] 2C7CTIQY make space for multiple kinds of width

Change contents

  • edit in main.lua at line 6
    [4.22]
    [4.3]
    -- lines is an array of lines
    -- a line is either:
    -- a string containing text
    -- or a drawing
    -- a drawing is a table with:
    -- a (y) coord in pixels,
    -- a (h)eight,
    -- an array of points, and
    -- an array of shapes
    -- a shape is a table containing:
    -- a mode
    -- an array points for mode 'freehand' (raw x,y coords; freehand drawings don't pollute the points array of a drawing)
    -- an array vertices for mode 'polygon', 'rectangle', 'square'
    -- p1, p2 for mode 'line'
    -- p1, p2, arrow-mode for mode 'arrow-line'
    -- cx,cy, r for mode 'circle'
    -- pc, r for mode 'circle'
    -- pc, r, s, e for mode 'arc'
    -- Unless otherwise specified, coord fields are normalized; a drawing is always 256 units wide
    -- The field names are carefully chosen so that switching modes in midstream
    -- remembers previously entered points where that makes sense.
    --
    -- Open question: how to maintain Sketchpad-style constraints? Answer for now:
    -- we don't. Constraints operate only for the duration of a drawing operation.
    -- We'll continue to persist them just to keep the option open to continue
    -- solving for them. But for now, this is a program to create static drawings
    -- once, and read them passively thereafter.
  • edit in main.lua at line 34
    [4.14]
    [20.3]
  • edit in main.lua at line 36
    [20.45]
    [4.3]
    current_mode = 'freehand'
  • replacement in main.lua at line 90
    [4.849][2.3:45]()
    if on_freehand(mx,my, shape) then
    [4.849]
    [4.45]
    if on_shape(mx,my, shape) then
  • edit in main.lua at line 94
    [4.138][4.138:150](),[4.150][2.46:280]()
    end
    prev = nil
    for _,point in ipairs(shape) do
    if prev then
    love.graphics.line(pixels(prev.x)+12,pixels(prev.y)+line.y, pixels(point.x)+12,pixels(point.y)+line.y)
    end
    prev = point
  • edit in main.lua at line 95
    [2.292]
    [4.1043]
    draw_shape(12,line.y, shape)
  • replacement in main.lua at line 97
    [4.1053][2.293:522](),[4.313][4.1230:1240](),[2.522][4.1230:1240](),[4.1230][4.1230:1240]()
    prev = nil
    for _,point in ipairs(line.pending) do
    if prev then
    love.graphics.line(pixels(prev.x)+12,pixels(prev.y)+line.y, pixels(point.x)+12,pixels(point.y)+line.y)
    end
    prev = point
    end
    [4.1053]
    [4.1240]
    draw_pending_shape(12,line.y, line.pending)
  • replacement in main.lua at line 118
    [4.957][2.523:634]()
    table.insert(drawing.pending, {x=coord(love.mouse.getX()-12), y=coord(love.mouse.getY()-drawing.y)})
    [4.957]
    [4.1647]
    if drawing.pending.mode == 'freehand' then
    table.insert(drawing.pending.points, {x=coord(love.mouse.getX()-12), y=coord(love.mouse.getY()-drawing.y)})
    end
  • edit in main.lua at line 132
    [4.451]
    [4.143]
    function love.mousereleased(x,y, button)
    if lines.current then
    if lines.current.pending then
    if lines.current.pending.mode == 'freehand' then
    -- the last point added during update is good enough
    elseif lines.current.pending.mode == 'line' then
    lines.current.pending.x2 = coord(x-12)
    lines.current.pending.y2 = coord(y-lines.current.y)
    end
    table.insert(lines.current.shapes, lines.current.pending)
    lines.current.pending = {}
    lines.current = nil
    end
    end
    end
  • edit in main.lua at line 153
    [4.1168]
    [4.408]
    if current_mode == 'freehand' then
    drawing.pending = {mode='freehand', points={x=coord(x-12), y=coord(y-drawing.y)}}
    elseif current_mode == 'line' then
    drawing.pending = {mode='line', x1=coord(x-12), y1=coord(y-drawing.y)}
    end
  • edit in main.lua at line 164
    [4.469]
    [4.409]
    function draw_shape(left,top, shape)
    if shape.mode == 'freehand' then
    local prev = nil
    for _,point in ipairs(shape.points) do
    if prev then
    love.graphics.line(pixels(prev.x)+left,pixels(prev.y)+top, pixels(point.x)+left,pixels(point.y)+top)
    end
    prev = point
    end
    elseif shape.mode == 'line' then
    love.graphics.line(pixels(shape.x1)+left,pixels(shape.y1)+top, pixels(shape.x2)+left,pixels(shape.y2)+top)
    end
    end
    function draw_pending_shape(left,top, shape)
    if shape.mode == 'freehand' then
    draw_shape(left,top, shape)
    elseif shape.mode == 'line' then
    love.graphics.line(pixels(line.pending.x1)+left,pixels(line.pending.y1)+top, love.mouse.getX(),love.mouse.getY())
    end
    end
    function on_shape(x,y, shape)
    if shape.mode == 'freehand' then
    return on_freehand(x,y, shape)
    elseif shape.mode == 'line' then
    return on_line(x,y, shape)
    else
    assert(false)
    end
    end
  • replacement in main.lua at line 198
    [4.455][4.455:485]()
    for _,p in ipairs(shape) do
    [4.455]
    [4.485]
    for _,p in ipairs(shape.points) do
  • edit in main.lua at line 231
    [4.1128][2.635:876]()
    function love.mousereleased(x,y, button)
    if lines.current then
    if lines.current.pending then
    table.insert(lines.current.shapes, lines.current.pending)
    lines.current.pending = {}
    lines.current = nil
    end
    end
    end
  • replacement in main.lua at line 256
    [2.978][2.978:1014]()
    convert_line(drawing,i,shape)
    [2.978]
    [2.1014]
    convert_line(shape)
  • replacement in main.lua at line 261
    [4.112][4.112:151]()
    convert_horvert(drawing,i,shape)
    [4.112]
    [4.111]
    convert_horvert(shape)
  • replacement in main.lua at line 278
    [4.433][2.1023:1067]()
    if on_freehand(mx,my, shape) then
    [4.433]
    [4.507]
    if on_shape(mx,my, shape) then
  • replacement in main.lua at line 287
    [2.1073][2.1073:1114]()
    function convert_line(drawing, i, shape)
    [2.1073]
    [2.1114]
    function convert_line(shape)
  • replacement in main.lua at line 292
    [2.1353][2.1353:1401]()
    drawing.shapes[i] = {shape[1], shape[#shape]}
    [2.1353]
    [4.152]
    assert(shape.mode == 'freehand')
    shape.mode = 'line'
    shape.x1 = shape.points[1].x
    shape.y1 = shape.points[1].y
    shape.x2 = shape.points[#shape.points].x
    shape.y2 = shape.points[#shape.points].y
  • replacement in main.lua at line 300
    [4.157][4.157:260](),[4.260][2.1402:1587]()
    -- turn a stroke into either a horizontal or vertical line
    function convert_horvert(drawing, i, shape)
    local x1,y1 = shape[1].x, shape[1].y
    local x2,y2 = shape[#shape].x, shape[#shape].y
    if math.abs(x1-x2) > math.abs(y1-y2) then
    drawing.shapes[i] = {{x=x1, y=y1}, {x=x2, y=y1}}
    [4.157]
    [4.445]
    -- turn a line either horizontal or vertical
    function convert_horvert(shape)
    if shape.mode == 'freehand' then
    convert_line(shape)
    end
    assert(shape.mode == 'line')
    if math.abs(shape.x1-shape.x2) > math.abs(shape.y1-shape.y2) then
    shape.y2 = shape.y1
  • replacement in main.lua at line 309
    [4.452][2.1588:1641]()
    drawing.shapes[i] = {{x=x1, y=y1}, {x=x1, y=y2}}
    [4.452]
    [4.505]
    shape.x2 = shape.x1
  • edit in main.lua at line 314
    [3.160]
    [3.160]
    assert(shape.mode == 'freehand')
  • replacement in main.lua at line 316
    [3.175][3.175:278]()
    for i=2,#shape-1 do
    local a = shape[i-1]
    local b = shape[i]
    local c = shape[i+1]
    [3.175]
    [3.278]
    for i=2,#shape.points-1 do
    local a = shape.points[i-1]
    local b = shape.points[i]
    local c = shape.points[i+1]