group all editor globals
We're still accessing them through a global. But we'll change that next.
This commit is contained in:
parent
a5f725ab3b
commit
8bbc1ffe34
186
drawing.lua
186
drawing.lua
|
@ -6,13 +6,13 @@ require 'drawing_tests'
|
||||||
-- into 256 parts.
|
-- into 256 parts.
|
||||||
function Drawing.draw(line)
|
function Drawing.draw(line)
|
||||||
local pmx,pmy = App.mouse_x(), App.mouse_y()
|
local pmx,pmy = App.mouse_x(), App.mouse_y()
|
||||||
if pmx < App.screen.width-Margin_right and pmy > line.y and pmy < line.y+Drawing.pixels(line.h) then
|
if pmx < App.screen.width-Editor_state.margin_right and pmy > line.y and pmy < line.y+Drawing.pixels(line.h) then
|
||||||
App.color(Icon_color)
|
App.color(Icon_color)
|
||||||
love.graphics.rectangle('line', Margin_left,line.y, App.screen.width-Margin_width,Drawing.pixels(line.h))
|
love.graphics.rectangle('line', Editor_state.margin_left,line.y, App.screen.width-Editor_state.margin_width,Drawing.pixels(line.h))
|
||||||
if icon[Current_drawing_mode] then
|
if icon[Editor_state.current_drawing_mode] then
|
||||||
icon[Current_drawing_mode](App.screen.width-Margin_right-22, line.y+4)
|
icon[Editor_state.current_drawing_mode](App.screen.width-Editor_state.margin_right-22, line.y+4)
|
||||||
else
|
else
|
||||||
icon[Previous_drawing_mode](App.screen.width-Margin_right-22, line.y+4)
|
icon[Editor_state.previous_drawing_mode](App.screen.width-Editor_state.margin_right-22, line.y+4)
|
||||||
end
|
end
|
||||||
|
|
||||||
if App.mouse_down(1) and love.keyboard.isDown('h') then
|
if App.mouse_down(1) and love.keyboard.isDown('h') then
|
||||||
|
@ -26,7 +26,7 @@ function Drawing.draw(line)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local mx,my = Drawing.coord(pmx-Margin_left), Drawing.coord(pmy-line.y)
|
local mx,my = Drawing.coord(pmx-Editor_state.margin_left), Drawing.coord(pmy-line.y)
|
||||||
|
|
||||||
for _,shape in ipairs(line.shapes) do
|
for _,shape in ipairs(line.shapes) do
|
||||||
assert(shape)
|
assert(shape)
|
||||||
|
@ -35,38 +35,38 @@ function Drawing.draw(line)
|
||||||
else
|
else
|
||||||
App.color(Stroke_color)
|
App.color(Stroke_color)
|
||||||
end
|
end
|
||||||
Drawing.draw_shape(Margin_left,line.y, line, shape)
|
Drawing.draw_shape(Editor_state.margin_left,line.y, line, shape)
|
||||||
end
|
end
|
||||||
for i,p in ipairs(line.points) do
|
for i,p in ipairs(line.points) do
|
||||||
if p.deleted == nil then
|
if p.deleted == nil then
|
||||||
if Drawing.near(p, mx,my) then
|
if Drawing.near(p, mx,my) then
|
||||||
App.color(Focus_stroke_color)
|
App.color(Focus_stroke_color)
|
||||||
love.graphics.circle('line', Drawing.pixels(p.x)+Margin_left,Drawing.pixels(p.y)+line.y, 4)
|
love.graphics.circle('line', Drawing.pixels(p.x)+Editor_state.margin_left,Drawing.pixels(p.y)+line.y, 4)
|
||||||
else
|
else
|
||||||
App.color(Stroke_color)
|
App.color(Stroke_color)
|
||||||
love.graphics.circle('fill', Drawing.pixels(p.x)+Margin_left,Drawing.pixels(p.y)+line.y, 2)
|
love.graphics.circle('fill', Drawing.pixels(p.x)+Editor_state.margin_left,Drawing.pixels(p.y)+line.y, 2)
|
||||||
end
|
end
|
||||||
if p.name then
|
if p.name then
|
||||||
-- TODO: clip
|
-- TODO: clip
|
||||||
local x,y = Drawing.pixels(p.x)+Margin_left+5, Drawing.pixels(p.y)+line.y+5
|
local x,y = Drawing.pixels(p.x)+Editor_state.margin_left+5, Drawing.pixels(p.y)+line.y+5
|
||||||
love.graphics.print(p.name, x,y)
|
love.graphics.print(p.name, x,y)
|
||||||
if Current_drawing_mode == 'name' and i == line.pending.target_point then
|
if Editor_state.current_drawing_mode == 'name' and i == line.pending.target_point then
|
||||||
-- create a faint red box for the name
|
-- create a faint red box for the name
|
||||||
App.color(Current_name_background_color)
|
App.color(Current_name_background_color)
|
||||||
local name_text
|
local name_text
|
||||||
-- TODO: avoid computing name width on every repaint
|
-- TODO: avoid computing name width on every repaint
|
||||||
if p.name == '' then
|
if p.name == '' then
|
||||||
name_text = Em
|
name_text = Editor_state.em
|
||||||
else
|
else
|
||||||
name_text = App.newText(love.graphics.getFont(), p.name)
|
name_text = App.newText(love.graphics.getFont(), p.name)
|
||||||
end
|
end
|
||||||
love.graphics.rectangle('fill', x,y, App.width(name_text), Line_height)
|
love.graphics.rectangle('fill', x,y, App.width(name_text), Editor_state.line_height)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
App.color(Current_stroke_color)
|
App.color(Current_stroke_color)
|
||||||
Drawing.draw_pending_shape(Margin_left,line.y, line)
|
Drawing.draw_pending_shape(Editor_state.margin_left,line.y, line)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.draw_shape(left,top, drawing, shape)
|
function Drawing.draw_shape(left,top, drawing, shape)
|
||||||
|
@ -204,51 +204,51 @@ end
|
||||||
|
|
||||||
function Drawing.in_drawing(drawing, x,y)
|
function Drawing.in_drawing(drawing, x,y)
|
||||||
if drawing.y == nil then return false end -- outside current page
|
if drawing.y == nil then return false end -- outside current page
|
||||||
return y >= drawing.y and y < drawing.y + Drawing.pixels(drawing.h) and x >= Margin_left and x < App.screen.width-Margin_right
|
return y >= drawing.y and y < drawing.y + Drawing.pixels(drawing.h) and x >= Editor_state.margin_left and x < App.screen.width-Editor_state.margin_right
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.mouse_pressed(drawing, x,y, button)
|
function Drawing.mouse_pressed(drawing, x,y, button)
|
||||||
if Current_drawing_mode == 'freehand' then
|
if Editor_state.current_drawing_mode == 'freehand' then
|
||||||
drawing.pending = {mode=Current_drawing_mode, points={{x=Drawing.coord(x-Margin_left), y=Drawing.coord(y-drawing.y)}}}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, points={{x=Drawing.coord(x-Editor_state.margin_left), y=Drawing.coord(y-drawing.y)}}}
|
||||||
elseif Current_drawing_mode == 'line' or Current_drawing_mode == 'manhattan' then
|
elseif Editor_state.current_drawing_mode == 'line' or Editor_state.current_drawing_mode == 'manhattan' then
|
||||||
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y))
|
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y))
|
||||||
drawing.pending = {mode=Current_drawing_mode, p1=j}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, p1=j}
|
||||||
elseif Current_drawing_mode == 'polygon' or Current_drawing_mode == 'rectangle' or Current_drawing_mode == 'square' then
|
elseif Editor_state.current_drawing_mode == 'polygon' or Editor_state.current_drawing_mode == 'rectangle' or Editor_state.current_drawing_mode == 'square' then
|
||||||
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y))
|
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y))
|
||||||
drawing.pending = {mode=Current_drawing_mode, vertices={j}}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, vertices={j}}
|
||||||
elseif Current_drawing_mode == 'circle' then
|
elseif Editor_state.current_drawing_mode == 'circle' then
|
||||||
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y))
|
local j = Drawing.insert_point(drawing.points, Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y))
|
||||||
drawing.pending = {mode=Current_drawing_mode, center=j}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, center=j}
|
||||||
elseif Current_drawing_mode == 'move' then
|
elseif Editor_state.current_drawing_mode == 'move' then
|
||||||
-- all the action is in mouse_released
|
-- all the action is in mouse_released
|
||||||
elseif Current_drawing_mode == 'name' then
|
elseif Editor_state.current_drawing_mode == 'name' then
|
||||||
-- nothing
|
-- nothing
|
||||||
else
|
else
|
||||||
print(Current_drawing_mode)
|
print(Editor_state.current_drawing_mode)
|
||||||
assert(false)
|
assert(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- a couple of operations on drawings need to constantly check the state of the mouse
|
-- a couple of operations on drawings need to constantly check the state of the mouse
|
||||||
function Drawing.update()
|
function Drawing.update()
|
||||||
if Lines.current_drawing == nil then return end
|
if Editor_state.lines.current_drawing == nil then return end
|
||||||
local drawing = Lines.current_drawing
|
local drawing = Editor_state.lines.current_drawing
|
||||||
assert(drawing.mode == 'drawing')
|
assert(drawing.mode == 'drawing')
|
||||||
local x, y = App.mouse_x(), App.mouse_y()
|
local x, y = App.mouse_x(), App.mouse_y()
|
||||||
if App.mouse_down(1) then
|
if App.mouse_down(1) then
|
||||||
if Drawing.in_drawing(drawing, x,y) then
|
if Drawing.in_drawing(drawing, x,y) then
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
table.insert(drawing.pending.points, {x=Drawing.coord(App.mouse_x()-Margin_left), y=Drawing.coord(App.mouse_y()-drawing.y)})
|
table.insert(drawing.pending.points, {x=Drawing.coord(App.mouse_x()-Editor_state.margin_left), y=Drawing.coord(App.mouse_y()-drawing.y)})
|
||||||
elseif drawing.pending.mode == 'move' then
|
elseif drawing.pending.mode == 'move' then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
drawing.pending.target_point.x = mx
|
drawing.pending.target_point.x = mx
|
||||||
drawing.pending.target_point.y = my
|
drawing.pending.target_point.y = my
|
||||||
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
|
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif Current_drawing_mode == 'move' then
|
elseif Editor_state.current_drawing_mode == 'move' then
|
||||||
if Drawing.in_drawing(drawing, x, y) then
|
if Drawing.in_drawing(drawing, x, y) then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
drawing.pending.target_point.x = mx
|
drawing.pending.target_point.x = mx
|
||||||
drawing.pending.target_point.y = my
|
drawing.pending.target_point.y = my
|
||||||
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
|
Drawing.relax_constraints(drawing, drawing.pending.target_point_index)
|
||||||
|
@ -277,15 +277,15 @@ function Drawing.relax_constraints(drawing, p)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.mouse_released(x,y, button)
|
function Drawing.mouse_released(x,y, button)
|
||||||
if Current_drawing_mode == 'move' then
|
if Editor_state.current_drawing_mode == 'move' then
|
||||||
Current_drawing_mode = Previous_drawing_mode
|
Editor_state.current_drawing_mode = Editor_state.previous_drawing_mode
|
||||||
Previous_drawing_mode = nil
|
Editor_state.previous_drawing_mode = nil
|
||||||
if Lines.current_drawing then
|
if Editor_state.lines.current_drawing then
|
||||||
Lines.current_drawing.pending = {}
|
Editor_state.lines.current_drawing.pending = {}
|
||||||
Lines.current_drawing = nil
|
Editor_state.lines.current_drawing = nil
|
||||||
end
|
end
|
||||||
elseif Lines.current_drawing then
|
elseif Editor_state.lines.current_drawing then
|
||||||
local drawing = Lines.current_drawing
|
local drawing = Editor_state.lines.current_drawing
|
||||||
if drawing.pending then
|
if drawing.pending then
|
||||||
if drawing.pending.mode == nil then
|
if drawing.pending.mode == nil then
|
||||||
-- nothing pending
|
-- nothing pending
|
||||||
|
@ -294,14 +294,14 @@ function Drawing.mouse_released(x,y, button)
|
||||||
Drawing.smoothen(drawing.pending)
|
Drawing.smoothen(drawing.pending)
|
||||||
table.insert(drawing.shapes, drawing.pending)
|
table.insert(drawing.shapes, drawing.pending)
|
||||||
elseif drawing.pending.mode == 'line' then
|
elseif drawing.pending.mode == 'line' then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
drawing.pending.p2 = Drawing.insert_point(drawing.points, mx,my)
|
drawing.pending.p2 = Drawing.insert_point(drawing.points, mx,my)
|
||||||
table.insert(drawing.shapes, drawing.pending)
|
table.insert(drawing.shapes, drawing.pending)
|
||||||
end
|
end
|
||||||
elseif drawing.pending.mode == 'manhattan' then
|
elseif drawing.pending.mode == 'manhattan' then
|
||||||
local p1 = drawing.points[drawing.pending.p1]
|
local p1 = drawing.points[drawing.pending.p1]
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
if math.abs(mx-p1.x) > math.abs(my-p1.y) then
|
if math.abs(mx-p1.x) > math.abs(my-p1.y) then
|
||||||
drawing.pending.p2 = Drawing.insert_point(drawing.points, mx, p1.y)
|
drawing.pending.p2 = Drawing.insert_point(drawing.points, mx, p1.y)
|
||||||
|
@ -309,11 +309,11 @@ function Drawing.mouse_released(x,y, button)
|
||||||
drawing.pending.p2 = Drawing.insert_point(drawing.points, p1.x, my)
|
drawing.pending.p2 = Drawing.insert_point(drawing.points, p1.x, my)
|
||||||
end
|
end
|
||||||
local p2 = drawing.points[drawing.pending.p2]
|
local p2 = drawing.points[drawing.pending.p2]
|
||||||
App.mouse_move(Margin_left+Drawing.pixels(p2.x), drawing.y+Drawing.pixels(p2.y))
|
App.mouse_move(Editor_state.margin_left+Drawing.pixels(p2.x), drawing.y+Drawing.pixels(p2.y))
|
||||||
table.insert(drawing.shapes, drawing.pending)
|
table.insert(drawing.shapes, drawing.pending)
|
||||||
end
|
end
|
||||||
elseif drawing.pending.mode == 'polygon' then
|
elseif drawing.pending.mode == 'polygon' then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
table.insert(drawing.pending.vertices, Drawing.insert_point(drawing.points, mx,my))
|
table.insert(drawing.pending.vertices, Drawing.insert_point(drawing.points, mx,my))
|
||||||
table.insert(drawing.shapes, drawing.pending)
|
table.insert(drawing.shapes, drawing.pending)
|
||||||
|
@ -321,7 +321,7 @@ function Drawing.mouse_released(x,y, button)
|
||||||
elseif drawing.pending.mode == 'rectangle' then
|
elseif drawing.pending.mode == 'rectangle' then
|
||||||
assert(#drawing.pending.vertices <= 2)
|
assert(#drawing.pending.vertices <= 2)
|
||||||
if #drawing.pending.vertices == 2 then
|
if #drawing.pending.vertices == 2 then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
local first = drawing.points[drawing.pending.vertices[1]]
|
local first = drawing.points[drawing.pending.vertices[1]]
|
||||||
local second = drawing.points[drawing.pending.vertices[2]]
|
local second = drawing.points[drawing.pending.vertices[2]]
|
||||||
|
@ -336,7 +336,7 @@ function Drawing.mouse_released(x,y, button)
|
||||||
elseif drawing.pending.mode == 'square' then
|
elseif drawing.pending.mode == 'square' then
|
||||||
assert(#drawing.pending.vertices <= 2)
|
assert(#drawing.pending.vertices <= 2)
|
||||||
if #drawing.pending.vertices == 2 then
|
if #drawing.pending.vertices == 2 then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
local first = drawing.points[drawing.pending.vertices[1]]
|
local first = drawing.points[drawing.pending.vertices[1]]
|
||||||
local second = drawing.points[drawing.pending.vertices[2]]
|
local second = drawing.points[drawing.pending.vertices[2]]
|
||||||
|
@ -347,14 +347,14 @@ function Drawing.mouse_released(x,y, button)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif drawing.pending.mode == 'circle' then
|
elseif drawing.pending.mode == 'circle' then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
local center = drawing.points[drawing.pending.center]
|
local center = drawing.points[drawing.pending.center]
|
||||||
drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
|
drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
|
||||||
table.insert(drawing.shapes, drawing.pending)
|
table.insert(drawing.shapes, drawing.pending)
|
||||||
end
|
end
|
||||||
elseif drawing.pending.mode == 'arc' then
|
elseif drawing.pending.mode == 'arc' then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then
|
||||||
local center = drawing.points[drawing.pending.center]
|
local center = drawing.points[drawing.pending.center]
|
||||||
drawing.pending.end_angle = geom.angle_with_hint(center.x,center.y, mx,my, drawing.pending.end_angle)
|
drawing.pending.end_angle = geom.angle_with_hint(center.x,center.y, mx,my, drawing.pending.end_angle)
|
||||||
|
@ -366,17 +366,17 @@ function Drawing.mouse_released(x,y, button)
|
||||||
print(drawing.pending.mode)
|
print(drawing.pending.mode)
|
||||||
assert(false)
|
assert(false)
|
||||||
end
|
end
|
||||||
Lines.current_drawing.pending = {}
|
Editor_state.lines.current_drawing.pending = {}
|
||||||
Lines.current_drawing = nil
|
Editor_state.lines.current_drawing = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.keychord_pressed(chord)
|
function Drawing.keychord_pressed(chord)
|
||||||
if chord == 'C-p' and not App.mouse_down(1) then
|
if chord == 'C-p' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'freehand'
|
Editor_state.current_drawing_mode = 'freehand'
|
||||||
elseif App.mouse_down(1) and chord == 'l' then
|
elseif App.mouse_down(1) and chord == 'l' then
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
||||||
|
@ -387,9 +387,9 @@ function Drawing.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
drawing.pending.mode = 'line'
|
drawing.pending.mode = 'line'
|
||||||
elseif chord == 'C-l' and not App.mouse_down(1) then
|
elseif chord == 'C-l' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
elseif App.mouse_down(1) and chord == 'm' then
|
elseif App.mouse_down(1) and chord == 'm' then
|
||||||
Current_drawing_mode = 'manhattan'
|
Editor_state.current_drawing_mode = 'manhattan'
|
||||||
local drawing = Drawing.select_drawing_at_mouse()
|
local drawing = Drawing.select_drawing_at_mouse()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
drawing.pending.p1 = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
||||||
|
@ -402,11 +402,11 @@ function Drawing.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
drawing.pending.mode = 'manhattan'
|
drawing.pending.mode = 'manhattan'
|
||||||
elseif chord == 'C-m' and not App.mouse_down(1) then
|
elseif chord == 'C-m' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'manhattan'
|
Editor_state.current_drawing_mode = 'manhattan'
|
||||||
elseif chord == 'C-g' and not App.mouse_down(1) then
|
elseif chord == 'C-g' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'polygon'
|
Editor_state.current_drawing_mode = 'polygon'
|
||||||
elseif App.mouse_down(1) and chord == 'g' then
|
elseif App.mouse_down(1) and chord == 'g' then
|
||||||
Current_drawing_mode = 'polygon'
|
Editor_state.current_drawing_mode = 'polygon'
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
||||||
|
@ -421,9 +421,9 @@ function Drawing.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
drawing.pending.mode = 'polygon'
|
drawing.pending.mode = 'polygon'
|
||||||
elseif chord == 'C-r' and not App.mouse_down(1) then
|
elseif chord == 'C-r' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'rectangle'
|
Editor_state.current_drawing_mode = 'rectangle'
|
||||||
elseif App.mouse_down(1) and chord == 'r' then
|
elseif App.mouse_down(1) and chord == 'r' then
|
||||||
Current_drawing_mode = 'rectangle'
|
Editor_state.current_drawing_mode = 'rectangle'
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
||||||
|
@ -438,9 +438,9 @@ function Drawing.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
drawing.pending.mode = 'rectangle'
|
drawing.pending.mode = 'rectangle'
|
||||||
elseif chord == 'C-s' and not App.mouse_down(1) then
|
elseif chord == 'C-s' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'square'
|
Editor_state.current_drawing_mode = 'square'
|
||||||
elseif App.mouse_down(1) and chord == 's' then
|
elseif App.mouse_down(1) and chord == 's' then
|
||||||
Current_drawing_mode = 'square'
|
Editor_state.current_drawing_mode = 'square'
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
drawing.pending.vertices = {Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)}
|
||||||
|
@ -458,30 +458,30 @@ function Drawing.keychord_pressed(chord)
|
||||||
drawing.pending.vertices = {drawing.pending.center}
|
drawing.pending.vertices = {drawing.pending.center}
|
||||||
end
|
end
|
||||||
drawing.pending.mode = 'square'
|
drawing.pending.mode = 'square'
|
||||||
elseif App.mouse_down(1) and chord == 'p' and Current_drawing_mode == 'polygon' then
|
elseif App.mouse_down(1) and chord == 'p' and Editor_state.current_drawing_mode == 'polygon' then
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
local mx,my = Drawing.coord(App.mouse_x()-Margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
local mx,my = Drawing.coord(App.mouse_x()-Editor_state.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
||||||
local j = Drawing.insert_point(drawing.points, mx,my)
|
local j = Drawing.insert_point(drawing.points, mx,my)
|
||||||
table.insert(drawing.pending.vertices, j)
|
table.insert(drawing.pending.vertices, j)
|
||||||
elseif App.mouse_down(1) and chord == 'p' and (Current_drawing_mode == 'rectangle' or Current_drawing_mode == 'square') then
|
elseif App.mouse_down(1) and chord == 'p' and (Editor_state.current_drawing_mode == 'rectangle' or Editor_state.current_drawing_mode == 'square') then
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
local mx,my = Drawing.coord(App.mouse_x()-Margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
local mx,my = Drawing.coord(App.mouse_x()-Editor_state.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
||||||
local j = Drawing.insert_point(drawing.points, mx,my)
|
local j = Drawing.insert_point(drawing.points, mx,my)
|
||||||
while #drawing.pending.vertices >= 2 do
|
while #drawing.pending.vertices >= 2 do
|
||||||
table.remove(drawing.pending.vertices)
|
table.remove(drawing.pending.vertices)
|
||||||
end
|
end
|
||||||
table.insert(drawing.pending.vertices, j)
|
table.insert(drawing.pending.vertices, j)
|
||||||
elseif chord == 'C-o' and not App.mouse_down(1) then
|
elseif chord == 'C-o' and not App.mouse_down(1) then
|
||||||
Current_drawing_mode = 'circle'
|
Editor_state.current_drawing_mode = 'circle'
|
||||||
elseif App.mouse_down(1) and chord == 'a' and Current_drawing_mode == 'circle' then
|
elseif App.mouse_down(1) and chord == 'a' and Editor_state.current_drawing_mode == 'circle' then
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
drawing.pending.mode = 'arc'
|
drawing.pending.mode = 'arc'
|
||||||
local mx,my = Drawing.coord(App.mouse_x()-Margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
local mx,my = Drawing.coord(App.mouse_x()-Editor_state.margin_left), Drawing.coord(App.mouse_y()-drawing.y)
|
||||||
local center = drawing.points[drawing.pending.center]
|
local center = drawing.points[drawing.pending.center]
|
||||||
drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
|
drawing.pending.radius = geom.dist(center.x,center.y, mx,my)
|
||||||
drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
|
drawing.pending.start_angle = geom.angle(center.x,center.y, mx,my)
|
||||||
elseif App.mouse_down(1) and chord == 'o' then
|
elseif App.mouse_down(1) and chord == 'o' then
|
||||||
Current_drawing_mode = 'circle'
|
Editor_state.current_drawing_mode = 'circle'
|
||||||
local _,drawing = Drawing.current_drawing()
|
local _,drawing = Drawing.current_drawing()
|
||||||
if drawing.pending.mode == 'freehand' then
|
if drawing.pending.mode == 'freehand' then
|
||||||
drawing.pending.center = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
drawing.pending.center = Drawing.insert_point(drawing.points, drawing.pending.points[1].x, drawing.pending.points[1].y)
|
||||||
|
@ -494,26 +494,26 @@ function Drawing.keychord_pressed(chord)
|
||||||
elseif chord == 'C-u' and not App.mouse_down(1) then
|
elseif chord == 'C-u' and not App.mouse_down(1) then
|
||||||
local drawing_index,drawing,i,p = Drawing.select_point_at_mouse()
|
local drawing_index,drawing,i,p = Drawing.select_point_at_mouse()
|
||||||
if drawing then
|
if drawing then
|
||||||
if Previous_drawing_mode == nil then
|
if Editor_state.previous_drawing_mode == nil then
|
||||||
Previous_drawing_mode = Current_drawing_mode
|
Editor_state.previous_drawing_mode = Editor_state.current_drawing_mode
|
||||||
end
|
end
|
||||||
Current_drawing_mode = 'move'
|
Editor_state.current_drawing_mode = 'move'
|
||||||
drawing.pending = {mode=Current_drawing_mode, target_point=p, target_point_index=i}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, target_point=p, target_point_index=i}
|
||||||
Lines.current_drawing_index = drawing_index
|
Editor_state.lines.current_drawing_index = drawing_index
|
||||||
Lines.current_drawing = drawing
|
Editor_state.lines.current_drawing = drawing
|
||||||
end
|
end
|
||||||
elseif chord == 'C-n' and not App.mouse_down(1) then
|
elseif chord == 'C-n' and not App.mouse_down(1) then
|
||||||
local drawing_index,drawing,point_index,p = Drawing.select_point_at_mouse()
|
local drawing_index,drawing,point_index,p = Drawing.select_point_at_mouse()
|
||||||
if drawing then
|
if drawing then
|
||||||
if Previous_drawing_mode == nil then
|
if Editor_state.previous_drawing_mode == nil then
|
||||||
-- don't clobber
|
-- don't clobber
|
||||||
Previous_drawing_mode = Current_drawing_mode
|
Editor_state.previous_drawing_mode = Editor_state.current_drawing_mode
|
||||||
end
|
end
|
||||||
Current_drawing_mode = 'name'
|
Editor_state.current_drawing_mode = 'name'
|
||||||
p.name = ''
|
p.name = ''
|
||||||
drawing.pending = {mode=Current_drawing_mode, target_point=point_index}
|
drawing.pending = {mode=Editor_state.current_drawing_mode, target_point=point_index}
|
||||||
Lines.current_drawing_index = drawing_index
|
Editor_state.lines.current_drawing_index = drawing_index
|
||||||
Lines.current_drawing = drawing
|
Editor_state.lines.current_drawing = drawing
|
||||||
end
|
end
|
||||||
elseif chord == 'C-d' and not App.mouse_down(1) then
|
elseif chord == 'C-d' and not App.mouse_down(1) then
|
||||||
local _,drawing,i,p = Drawing.select_point_at_mouse()
|
local _,drawing,i,p = Drawing.select_point_at_mouse()
|
||||||
|
@ -599,7 +599,7 @@ end
|
||||||
|
|
||||||
function Drawing.current_drawing()
|
function Drawing.current_drawing()
|
||||||
local x, y = App.mouse_x(), App.mouse_y()
|
local x, y = App.mouse_x(), App.mouse_y()
|
||||||
for drawing_index,drawing in ipairs(Lines) do
|
for drawing_index,drawing in ipairs(Editor_state.lines) do
|
||||||
if drawing.mode == 'drawing' then
|
if drawing.mode == 'drawing' then
|
||||||
if Drawing.in_drawing(drawing, x,y) then
|
if Drawing.in_drawing(drawing, x,y) then
|
||||||
return drawing_index,drawing
|
return drawing_index,drawing
|
||||||
|
@ -610,11 +610,11 @@ function Drawing.current_drawing()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.select_shape_at_mouse()
|
function Drawing.select_shape_at_mouse()
|
||||||
for _,drawing in ipairs(Lines) do
|
for _,drawing in ipairs(Editor_state.lines) do
|
||||||
if drawing.mode == 'drawing' then
|
if drawing.mode == 'drawing' then
|
||||||
local x, y = App.mouse_x(), App.mouse_y()
|
local x, y = App.mouse_x(), App.mouse_y()
|
||||||
if Drawing.in_drawing(drawing, x,y) then
|
if Drawing.in_drawing(drawing, x,y) then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
for i,shape in ipairs(drawing.shapes) do
|
for i,shape in ipairs(drawing.shapes) do
|
||||||
assert(shape)
|
assert(shape)
|
||||||
if geom.on_shape(mx,my, drawing, shape) then
|
if geom.on_shape(mx,my, drawing, shape) then
|
||||||
|
@ -627,11 +627,11 @@ function Drawing.select_shape_at_mouse()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.select_point_at_mouse()
|
function Drawing.select_point_at_mouse()
|
||||||
for drawing_index,drawing in ipairs(Lines) do
|
for drawing_index,drawing in ipairs(Editor_state.lines) do
|
||||||
if drawing.mode == 'drawing' then
|
if drawing.mode == 'drawing' then
|
||||||
local x, y = App.mouse_x(), App.mouse_y()
|
local x, y = App.mouse_x(), App.mouse_y()
|
||||||
if Drawing.in_drawing(drawing, x,y) then
|
if Drawing.in_drawing(drawing, x,y) then
|
||||||
local mx,my = Drawing.coord(x-Margin_left), Drawing.coord(y-drawing.y)
|
local mx,my = Drawing.coord(x-Editor_state.margin_left), Drawing.coord(y-drawing.y)
|
||||||
for i,point in ipairs(drawing.points) do
|
for i,point in ipairs(drawing.points) do
|
||||||
assert(point)
|
assert(point)
|
||||||
if Drawing.near(point, mx,my) then
|
if Drawing.near(point, mx,my) then
|
||||||
|
@ -644,7 +644,7 @@ function Drawing.select_point_at_mouse()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.select_drawing_at_mouse()
|
function Drawing.select_drawing_at_mouse()
|
||||||
for _,drawing in ipairs(Lines) do
|
for _,drawing in ipairs(Editor_state.lines) do
|
||||||
if drawing.mode == 'drawing' then
|
if drawing.mode == 'drawing' then
|
||||||
local x, y = App.mouse_x(), App.mouse_y()
|
local x, y = App.mouse_x(), App.mouse_y()
|
||||||
if Drawing.in_drawing(drawing, x,y) then
|
if Drawing.in_drawing(drawing, x,y) then
|
||||||
|
@ -700,14 +700,14 @@ end
|
||||||
function Drawing.near(point, x,y)
|
function Drawing.near(point, x,y)
|
||||||
local px,py = Drawing.pixels(x),Drawing.pixels(y)
|
local px,py = Drawing.pixels(x),Drawing.pixels(y)
|
||||||
local cx,cy = Drawing.pixels(point.x), Drawing.pixels(point.y)
|
local cx,cy = Drawing.pixels(point.x), Drawing.pixels(point.y)
|
||||||
return (cx-px)*(cx-px) + (cy-py)*(cy-py) < Margin_left
|
return (cx-px)*(cx-px) + (cy-py)*(cy-py) < Editor_state.margin_left
|
||||||
end
|
end
|
||||||
|
|
||||||
function Drawing.pixels(n) -- parts to pixels
|
function Drawing.pixels(n) -- parts to pixels
|
||||||
return math.floor(n*(App.screen.width-Margin_width)/256)
|
return math.floor(n*(App.screen.width-Editor_state.margin_width)/256)
|
||||||
end
|
end
|
||||||
function Drawing.coord(n) -- pixels to parts
|
function Drawing.coord(n) -- pixels to parts
|
||||||
return math.floor(n*256/(App.screen.width-Margin_width))
|
return math.floor(n*256/(App.screen.width-Editor_state.margin_width))
|
||||||
end
|
end
|
||||||
|
|
||||||
function table.find(h, x)
|
function table.find(h, x)
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
function test_creating_drawing_saves()
|
function test_creating_drawing_saves()
|
||||||
io.write('\ntest_creating_drawing_saves')
|
io.write('\ntest_creating_drawing_saves')
|
||||||
App.screen.init{width=120, height=60}
|
App.screen.init{width=120, height=60}
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
Lines = load_array{}
|
Editor_state.lines = load_array{}
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- click on button to create drawing
|
-- click on button to create drawing
|
||||||
App.run_after_mouse_click(8,Margin_top+8, 1)
|
App.run_after_mouse_click(8,Editor_state.margin_top+8, 1)
|
||||||
-- file not immediately saved
|
-- file not immediately saved
|
||||||
App.update(0.01)
|
App.update(0.01)
|
||||||
check_nil(App.filesystem['foo'], 'F - test_creating_drawing_saves/early')
|
check_nil(App.filesystem['foo'], 'F - test_creating_drawing_saves/early')
|
||||||
|
@ -23,20 +23,20 @@ end
|
||||||
function test_draw_line()
|
function test_draw_line()
|
||||||
io.write('\ntest_draw_line')
|
io.write('\ntest_draw_line')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_draw_line/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_line/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_line/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_line/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_line/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_line/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_line/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_line/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_line/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_line/baseline/#shapes')
|
||||||
-- draw a line
|
-- draw a line
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_line/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_line/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_draw_line/#points')
|
check_eq(#drawing.points, 2, 'F - test_draw_line/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_draw_line/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_draw_line/shape:1')
|
||||||
|
@ -51,8 +51,8 @@ function test_draw_line()
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- The format on disk isn't perfectly stable. Table fields can be reordered.
|
-- The format on disk isn't perfectly stable. Table fields can be reordered.
|
||||||
-- So just reload from disk to verify.
|
-- So just reload from disk to verify.
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_line/save/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_line/save/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_draw_line/save/#points')
|
check_eq(#drawing.points, 2, 'F - test_draw_line/save/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_draw_line/save/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_draw_line/save/shape:1')
|
||||||
|
@ -67,19 +67,19 @@ end
|
||||||
function test_draw_horizontal_line()
|
function test_draw_horizontal_line()
|
||||||
io.write('\ntest_draw_horizontal_line')
|
io.write('\ntest_draw_horizontal_line')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'manhattan'
|
Editor_state.current_drawing_mode = 'manhattan'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_draw_horizontal_line/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_horizontal_line/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_horizontal_line/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_horizontal_line/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_horizontal_line/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_horizontal_line/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_horizontal_line/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_horizontal_line/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_horizontal_line/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_horizontal_line/baseline/#shapes')
|
||||||
-- draw a line that is more horizontal than vertical
|
-- draw a line that is more horizontal than vertical
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_horizontal_line/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_horizontal_line/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_draw_horizontal_line/#points')
|
check_eq(#drawing.points, 2, 'F - test_draw_horizontal_line/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'manhattan', 'F - test_draw_horizontal_line/shape_mode')
|
check_eq(drawing.shapes[1].mode, 'manhattan', 'F - test_draw_horizontal_line/shape_mode')
|
||||||
|
@ -94,21 +94,21 @@ end
|
||||||
function test_draw_circle()
|
function test_draw_circle()
|
||||||
io.write('\ntest_draw_circle')
|
io.write('\ntest_draw_circle')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_draw_circle/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_circle/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_circle/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_circle/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_circle/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_circle/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_circle/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_circle/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_circle/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_circle/baseline/#shapes')
|
||||||
-- draw a circle
|
-- draw a circle
|
||||||
App.mouse_move(Margin_left+4, Margin_top+Drawing_padding_top+4) -- hover on drawing
|
App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4) -- hover on drawing
|
||||||
App.run_after_keychord('C-o')
|
App.run_after_keychord('C-o')
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35+30, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_circle/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_circle/#shapes')
|
||||||
check_eq(#drawing.points, 1, 'F - test_draw_circle/#points')
|
check_eq(#drawing.points, 1, 'F - test_draw_circle/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'circle', 'F - test_draw_horizontal_line/shape_mode')
|
check_eq(drawing.shapes[1].mode, 'circle', 'F - test_draw_horizontal_line/shape_mode')
|
||||||
|
@ -121,58 +121,58 @@ end
|
||||||
function test_cancel_stroke()
|
function test_cancel_stroke()
|
||||||
io.write('\ntest_cancel_stroke')
|
io.write('\ntest_cancel_stroke')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_cancel_stroke/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_cancel_stroke/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_cancel_stroke/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_cancel_stroke/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_cancel_stroke/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_cancel_stroke/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_cancel_stroke/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_cancel_stroke/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_cancel_stroke/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_cancel_stroke/baseline/#shapes')
|
||||||
-- start drawing a line
|
-- start drawing a line
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
-- cancel
|
-- cancel
|
||||||
App.run_after_keychord('escape')
|
App.run_after_keychord('escape')
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 0, 'F - test_cancel_stroke/#shapes')
|
check_eq(#drawing.shapes, 0, 'F - test_cancel_stroke/#shapes')
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_keys_do_not_affect_shape_when_mouse_up()
|
function test_keys_do_not_affect_shape_when_mouse_up()
|
||||||
io.write('\ntest_keys_do_not_affect_shape_when_mouse_up')
|
io.write('\ntest_keys_do_not_affect_shape_when_mouse_up')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- hover over drawing and press 'o' without holding mouse
|
-- hover over drawing and press 'o' without holding mouse
|
||||||
App.mouse_move(Margin_left+4, Margin_top+Drawing_padding_top+4) -- hover on drawing
|
App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4) -- hover on drawing
|
||||||
App.run_after_keychord('o')
|
App.run_after_keychord('o')
|
||||||
-- no change to drawing mode
|
-- no change to drawing mode
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_keys_do_not_affect_shape_when_mouse_up/drawing_mode')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_keys_do_not_affect_shape_when_mouse_up/drawing_mode')
|
||||||
-- no change to text either because we didn't run the textinput event
|
-- no change to text either because we didn't run the textinput event
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_draw_circle_mid_stroke()
|
function test_draw_circle_mid_stroke()
|
||||||
io.write('\ntest_draw_circle_mid_stroke')
|
io.write('\ntest_draw_circle_mid_stroke')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_draw_circle_mid_stroke/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_circle_mid_stroke/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_circle_mid_stroke/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_circle_mid_stroke/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_circle_mid_stroke/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_circle_mid_stroke/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_circle_mid_stroke/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_circle_mid_stroke/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_circle_mid_stroke/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_circle_mid_stroke/baseline/#shapes')
|
||||||
-- draw a circle
|
-- draw a circle
|
||||||
App.mouse_move(Margin_left+4, Margin_top+Drawing_padding_top+4) -- hover on drawing
|
App.mouse_move(Editor_state.margin_left+4, Editor_state.margin_top+Editor_state.drawing_padding_top+4) -- hover on drawing
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_keychord('o')
|
App.run_after_keychord('o')
|
||||||
App.run_after_mouse_release(Margin_left+35+30, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_circle_mid_stroke/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_circle_mid_stroke/#shapes')
|
||||||
check_eq(#drawing.points, 1, 'F - test_draw_circle_mid_stroke/#points')
|
check_eq(#drawing.points, 1, 'F - test_draw_circle_mid_stroke/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'circle', 'F - test_draw_horizontal_line/shape_mode')
|
check_eq(drawing.shapes[1].mode, 'circle', 'F - test_draw_horizontal_line/shape_mode')
|
||||||
|
@ -185,21 +185,21 @@ end
|
||||||
function test_draw_arc()
|
function test_draw_arc()
|
||||||
io.write('\ntest_draw_arc')
|
io.write('\ntest_draw_arc')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'circle'
|
Editor_state.current_drawing_mode = 'circle'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(#Lines, 2, 'F - test_draw_arc/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_arc/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_arc/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_arc/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_arc/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_arc/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_arc/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_arc/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_arc/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_arc/baseline/#shapes')
|
||||||
-- draw an arc
|
-- draw an arc
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.mouse_move(Margin_left+35+30, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+35+30, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('a') -- arc mode
|
App.run_after_keychord('a') -- arc mode
|
||||||
App.run_after_mouse_release(Margin_left+35+50, Margin_top+Drawing_padding_top+36+50, 1) -- 45°
|
App.run_after_mouse_release(Editor_state.margin_left+35+50, Editor_state.margin_top+Editor_state.drawing_padding_top+36+50, 1) -- 45°
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_arc/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_arc/#shapes')
|
||||||
check_eq(#drawing.points, 1, 'F - test_draw_arc/#points')
|
check_eq(#drawing.points, 1, 'F - test_draw_arc/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'arc', 'F - test_draw_horizontal_line/shape_mode')
|
check_eq(drawing.shapes[1].mode, 'arc', 'F - test_draw_horizontal_line/shape_mode')
|
||||||
|
@ -215,24 +215,24 @@ end
|
||||||
function test_draw_polygon()
|
function test_draw_polygon()
|
||||||
io.write('\ntest_draw_polygon')
|
io.write('\ntest_draw_polygon')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_draw_polygon/baseline/drawing_mode')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_polygon/baseline/drawing_mode')
|
||||||
check_eq(#Lines, 2, 'F - test_draw_polygon/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_polygon/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_polygon/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_polygon/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_polygon/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_polygon/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_polygon/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_polygon/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_polygon/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_polygon/baseline/#shapes')
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_keychord('g') -- polygon mode
|
App.run_after_keychord('g') -- polygon mode
|
||||||
-- second point
|
-- second point
|
||||||
App.mouse_move(Margin_left+65, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('p') -- add point
|
App.run_after_keychord('p') -- add point
|
||||||
-- final point
|
-- final point
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_polygon/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_polygon/#shapes')
|
||||||
check_eq(#drawing.points, 3, 'F - test_draw_polygon/vertices')
|
check_eq(#drawing.points, 3, 'F - test_draw_polygon/vertices')
|
||||||
local shape = drawing.shapes[1]
|
local shape = drawing.shapes[1]
|
||||||
|
@ -252,27 +252,27 @@ end
|
||||||
function test_draw_rectangle()
|
function test_draw_rectangle()
|
||||||
io.write('\ntest_draw_rectangle')
|
io.write('\ntest_draw_rectangle')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_draw_rectangle/baseline/drawing_mode')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_rectangle/baseline/drawing_mode')
|
||||||
check_eq(#Lines, 2, 'F - test_draw_rectangle/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_rectangle/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_rectangle/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_rectangle/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_rectangle/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_rectangle/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_rectangle/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_rectangle/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_rectangle/baseline/#shapes')
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_keychord('r') -- rectangle mode
|
App.run_after_keychord('r') -- rectangle mode
|
||||||
-- second point/first edge
|
-- second point/first edge
|
||||||
App.mouse_move(Margin_left+42, Margin_top+Drawing_padding_top+45)
|
App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
-- override second point/first edge
|
-- override second point/first edge
|
||||||
App.mouse_move(Margin_left+75, Margin_top+Drawing_padding_top+76)
|
App.mouse_move(Editor_state.margin_left+75, Editor_state.margin_top+Editor_state.drawing_padding_top+76)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
-- release (decides 'thickness' of rectangle perpendicular to first edge)
|
-- release (decides 'thickness' of rectangle perpendicular to first edge)
|
||||||
App.run_after_mouse_release(Margin_left+15, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+15, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_rectangle/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_rectangle/#shapes')
|
||||||
check_eq(#drawing.points, 5, 'F - test_draw_rectangle/#points') -- currently includes every point added
|
check_eq(#drawing.points, 5, 'F - test_draw_rectangle/#points') -- currently includes every point added
|
||||||
local shape = drawing.shapes[1]
|
local shape = drawing.shapes[1]
|
||||||
|
@ -295,25 +295,25 @@ end
|
||||||
function test_draw_rectangle_intermediate()
|
function test_draw_rectangle_intermediate()
|
||||||
io.write('\ntest_draw_rectangle_intermediate')
|
io.write('\ntest_draw_rectangle_intermediate')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_draw_rectangle_intermediate/baseline/drawing_mode')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_rectangle_intermediate/baseline/drawing_mode')
|
||||||
check_eq(#Lines, 2, 'F - test_draw_rectangle_intermediate/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_rectangle_intermediate/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_rectangle_intermediate/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_rectangle_intermediate/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_rectangle_intermediate/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_rectangle_intermediate/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_rectangle_intermediate/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_rectangle_intermediate/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_rectangle_intermediate/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_rectangle_intermediate/baseline/#shapes')
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_keychord('r') -- rectangle mode
|
App.run_after_keychord('r') -- rectangle mode
|
||||||
-- second point/first edge
|
-- second point/first edge
|
||||||
App.mouse_move(Margin_left+42, Margin_top+Drawing_padding_top+45)
|
App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
-- override second point/first edge
|
-- override second point/first edge
|
||||||
App.mouse_move(Margin_left+75, Margin_top+Drawing_padding_top+76)
|
App.mouse_move(Editor_state.margin_left+75, Editor_state.margin_top+Editor_state.drawing_padding_top+76)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.points, 3, 'F - test_draw_rectangle_intermediate/#points') -- currently includes every point added
|
check_eq(#drawing.points, 3, 'F - test_draw_rectangle_intermediate/#points') -- currently includes every point added
|
||||||
local pending = drawing.pending
|
local pending = drawing.pending
|
||||||
check_eq(pending.mode, 'rectangle', 'F - test_draw_rectangle_intermediate/shape_mode')
|
check_eq(pending.mode, 'rectangle', 'F - test_draw_rectangle_intermediate/shape_mode')
|
||||||
|
@ -330,27 +330,27 @@ end
|
||||||
function test_draw_square()
|
function test_draw_square()
|
||||||
io.write('\ntest_draw_square')
|
io.write('\ntest_draw_square')
|
||||||
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
-- display a drawing followed by a line of text (you shouldn't ever have a drawing right at the end)
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
edit.draw()
|
edit.draw()
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_draw_square/baseline/drawing_mode')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_draw_square/baseline/drawing_mode')
|
||||||
check_eq(#Lines, 2, 'F - test_draw_square/baseline/#lines')
|
check_eq(#Editor_state.lines, 2, 'F - test_draw_square/baseline/#lines')
|
||||||
check_eq(Lines[1].mode, 'drawing', 'F - test_draw_square/baseline/mode')
|
check_eq(Editor_state.lines[1].mode, 'drawing', 'F - test_draw_square/baseline/mode')
|
||||||
check_eq(Lines[1].y, Margin_top+Drawing_padding_top, 'F - test_draw_square/baseline/y')
|
check_eq(Editor_state.lines[1].y, Editor_state.margin_top+Editor_state.drawing_padding_top, 'F - test_draw_square/baseline/y')
|
||||||
check_eq(Lines[1].h, 128, 'F - test_draw_square/baseline/y')
|
check_eq(Editor_state.lines[1].h, 128, 'F - test_draw_square/baseline/y')
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_draw_square/baseline/#shapes')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_draw_square/baseline/#shapes')
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_keychord('s') -- square mode
|
App.run_after_keychord('s') -- square mode
|
||||||
-- second point/first edge
|
-- second point/first edge
|
||||||
App.mouse_move(Margin_left+42, Margin_top+Drawing_padding_top+45)
|
App.mouse_move(Editor_state.margin_left+42, Editor_state.margin_top+Editor_state.drawing_padding_top+45)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
-- override second point/first edge
|
-- override second point/first edge
|
||||||
App.mouse_move(Margin_left+65, Margin_top+Drawing_padding_top+66)
|
App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+66)
|
||||||
App.run_after_keychord('p')
|
App.run_after_keychord('p')
|
||||||
-- release (decides which side of first edge to draw square on)
|
-- release (decides which side of first edge to draw square on)
|
||||||
App.run_after_mouse_release(Margin_left+15, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+15, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_draw_square/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_draw_square/#shapes')
|
||||||
check_eq(#drawing.points, 5, 'F - test_draw_square/#points') -- currently includes every point added
|
check_eq(#drawing.points, 5, 'F - test_draw_square/#points') -- currently includes every point added
|
||||||
check_eq(drawing.shapes[1].mode, 'square', 'F - test_draw_square/shape_mode')
|
check_eq(drawing.shapes[1].mode, 'square', 'F - test_draw_square/shape_mode')
|
||||||
|
@ -372,15 +372,15 @@ end
|
||||||
function test_name_point()
|
function test_name_point()
|
||||||
io.write('\ntest_name_point')
|
io.write('\ntest_name_point')
|
||||||
-- create a drawing with a line
|
-- create a drawing with a line
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- draw a line
|
-- draw a line
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_name_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_name_point/baseline/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_name_point/baseline/#points')
|
check_eq(#drawing.points, 2, 'F - test_name_point/baseline/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_name_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_name_point/baseline/shape:1')
|
||||||
|
@ -393,35 +393,35 @@ function test_name_point()
|
||||||
check_nil(p2.name, 'F - test_name_point/baseline/p2:name')
|
check_nil(p2.name, 'F - test_name_point/baseline/p2:name')
|
||||||
-- enter 'name' mode without moving the mouse
|
-- enter 'name' mode without moving the mouse
|
||||||
App.run_after_keychord('C-n')
|
App.run_after_keychord('C-n')
|
||||||
check_eq(Current_drawing_mode, 'name', 'F - test_name_point/mode:1')
|
check_eq(Editor_state.current_drawing_mode, 'name', 'F - test_name_point/mode:1')
|
||||||
App.run_after_textinput('A')
|
App.run_after_textinput('A')
|
||||||
check_eq(p2.name, 'A', 'F - test_name_point')
|
check_eq(p2.name, 'A', 'F - test_name_point')
|
||||||
-- still in 'name' mode
|
-- still in 'name' mode
|
||||||
check_eq(Current_drawing_mode, 'name', 'F - test_name_point/mode:2')
|
check_eq(Editor_state.current_drawing_mode, 'name', 'F - test_name_point/mode:2')
|
||||||
-- exit 'name' mode
|
-- exit 'name' mode
|
||||||
App.run_after_keychord('return')
|
App.run_after_keychord('return')
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_name_point/mode:3')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_name_point/mode:3')
|
||||||
check_eq(p2.name, 'A', 'F - test_name_point')
|
check_eq(p2.name, 'A', 'F - test_name_point')
|
||||||
-- wait until save
|
-- wait until save
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- change is saved
|
-- change is saved
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local p2 = Lines[1].points[drawing.shapes[1].p2]
|
local p2 = Editor_state.lines[1].points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.name, 'A', 'F - test_name_point/save')
|
check_eq(p2.name, 'A', 'F - test_name_point/save')
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_move_point()
|
function test_move_point()
|
||||||
io.write('\ntest_move_point')
|
io.write('\ntest_move_point')
|
||||||
-- create a drawing with a line
|
-- create a drawing with a line
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_move_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_move_point/baseline/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_move_point/baseline/#points')
|
check_eq(#drawing.points, 2, 'F - test_move_point/baseline/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_move_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_move_point/baseline/shape:1')
|
||||||
|
@ -435,34 +435,34 @@ function test_move_point()
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- line is saved to disk
|
-- line is saved to disk
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
local p2 = Lines[1].points[drawing.shapes[1].p2]
|
local p2 = Editor_state.lines[1].points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.x, 35, 'F - test_move_point/save/x')
|
check_eq(p2.x, 35, 'F - test_move_point/save/x')
|
||||||
check_eq(p2.y, 36, 'F - test_move_point/save/y')
|
check_eq(p2.y, 36, 'F - test_move_point/save/y')
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- enter 'move' mode without moving the mouse
|
-- enter 'move' mode without moving the mouse
|
||||||
App.run_after_keychord('C-u')
|
App.run_after_keychord('C-u')
|
||||||
check_eq(Current_drawing_mode, 'move', 'F - test_move_point/mode:1')
|
check_eq(Editor_state.current_drawing_mode, 'move', 'F - test_move_point/mode:1')
|
||||||
-- point is lifted
|
-- point is lifted
|
||||||
check_eq(drawing.pending.mode, 'move', 'F - test_move_point/mode:2')
|
check_eq(drawing.pending.mode, 'move', 'F - test_move_point/mode:2')
|
||||||
check_eq(drawing.pending.target_point, p2, 'F - test_move_point/target')
|
check_eq(drawing.pending.target_point, p2, 'F - test_move_point/target')
|
||||||
-- move point
|
-- move point
|
||||||
App.mouse_move(Margin_left+26, Margin_top+Drawing_padding_top+44)
|
App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
|
||||||
App.update(0.05)
|
App.update(0.05)
|
||||||
local p2 = drawing.points[drawing.shapes[1].p2]
|
local p2 = drawing.points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.x, 26, 'F - test_move_point/x')
|
check_eq(p2.x, 26, 'F - test_move_point/x')
|
||||||
check_eq(p2.y, 44, 'F - test_move_point/y')
|
check_eq(p2.y, 44, 'F - test_move_point/y')
|
||||||
-- exit 'move' mode
|
-- exit 'move' mode
|
||||||
App.run_after_mouse_click(Margin_left+26, Margin_top+Drawing_padding_top+44, 1)
|
App.run_after_mouse_click(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44, 1)
|
||||||
check_eq(Current_drawing_mode, 'line', 'F - test_move_point/mode:3')
|
check_eq(Editor_state.current_drawing_mode, 'line', 'F - test_move_point/mode:3')
|
||||||
check_eq(drawing.pending, {}, 'F - test_move_point/pending')
|
check_eq(drawing.pending, {}, 'F - test_move_point/pending')
|
||||||
-- wait until save
|
-- wait until save
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- change is saved
|
-- change is saved
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local p2 = Lines[1].points[drawing.shapes[1].p2]
|
local p2 = Editor_state.lines[1].points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.x, 26, 'F - test_move_point/save/x')
|
check_eq(p2.x, 26, 'F - test_move_point/save/x')
|
||||||
check_eq(p2.y, 44, 'F - test_move_point/save/y')
|
check_eq(p2.y, 44, 'F - test_move_point/save/y')
|
||||||
end
|
end
|
||||||
|
@ -470,23 +470,23 @@ end
|
||||||
function test_move_point_on_manhattan_line()
|
function test_move_point_on_manhattan_line()
|
||||||
io.write('\ntest_move_point_on_manhattan_line')
|
io.write('\ntest_move_point_on_manhattan_line')
|
||||||
-- create a drawing with a manhattan line
|
-- create a drawing with a manhattan line
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'manhattan'
|
Editor_state.current_drawing_mode = 'manhattan'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+46, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+46, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_move_point_on_manhattan_line/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_move_point_on_manhattan_line/baseline/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_move_point_on_manhattan_line/baseline/#points')
|
check_eq(#drawing.points, 2, 'F - test_move_point_on_manhattan_line/baseline/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'manhattan', 'F - test_move_point_on_manhattan_line/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'manhattan', 'F - test_move_point_on_manhattan_line/baseline/shape:1')
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- enter 'move' mode
|
-- enter 'move' mode
|
||||||
App.run_after_keychord('C-u')
|
App.run_after_keychord('C-u')
|
||||||
check_eq(Current_drawing_mode, 'move', 'F - test_move_point_on_manhattan_line/mode:1')
|
check_eq(Editor_state.current_drawing_mode, 'move', 'F - test_move_point_on_manhattan_line/mode:1')
|
||||||
-- move point
|
-- move point
|
||||||
App.mouse_move(Margin_left+26, Margin_top+Drawing_padding_top+44)
|
App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
|
||||||
App.update(0.05)
|
App.update(0.05)
|
||||||
-- line is no longer manhattan
|
-- line is no longer manhattan
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_move_point_on_manhattan_line/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_move_point_on_manhattan_line/baseline/shape:1')
|
||||||
|
@ -495,21 +495,21 @@ end
|
||||||
function test_delete_lines_at_point()
|
function test_delete_lines_at_point()
|
||||||
io.write('\ntest_delete_lines_at_point')
|
io.write('\ntest_delete_lines_at_point')
|
||||||
-- create a drawing with two lines connected at a point
|
-- create a drawing with two lines connected at a point
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_release(Margin_left+55, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 2, 'F - test_delete_lines_at_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 2, 'F - test_delete_lines_at_point/baseline/#shapes')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:2')
|
check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_lines_at_point/baseline/shape:2')
|
||||||
-- hover on the common point and delete
|
-- hover on the common point and delete
|
||||||
App.mouse_move(Margin_left+35, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('C-d')
|
App.run_after_keychord('C-d')
|
||||||
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_lines_at_point/shape:1')
|
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_lines_at_point/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_delete_lines_at_point/shape:2')
|
check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_delete_lines_at_point/shape:2')
|
||||||
|
@ -517,27 +517,27 @@ function test_delete_lines_at_point()
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- deleted points disappear after file is reloaded
|
-- deleted points disappear after file is reloaded
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
check_eq(#Lines[1].shapes, 0, 'F - test_delete_lines_at_point/save')
|
check_eq(#Editor_state.lines[1].shapes, 0, 'F - test_delete_lines_at_point/save')
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_delete_line_under_mouse_pointer()
|
function test_delete_line_under_mouse_pointer()
|
||||||
io.write('\ntest_delete_line_under_mouse_pointer')
|
io.write('\ntest_delete_line_under_mouse_pointer')
|
||||||
-- create a drawing with two lines connected at a point
|
-- create a drawing with two lines connected at a point
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_release(Margin_left+55, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 2, 'F - test_delete_line_under_mouse_pointer/baseline/#shapes')
|
check_eq(#drawing.shapes, 2, 'F - test_delete_line_under_mouse_pointer/baseline/#shapes')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:2')
|
check_eq(drawing.shapes[2].mode, 'line', 'F - test_delete_line_under_mouse_pointer/baseline/shape:2')
|
||||||
-- hover on one of the lines and delete
|
-- hover on one of the lines and delete
|
||||||
App.mouse_move(Margin_left+25, Margin_top+Drawing_padding_top+26)
|
App.mouse_move(Editor_state.margin_left+25, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
|
||||||
App.run_after_keychord('C-d')
|
App.run_after_keychord('C-d')
|
||||||
-- only that line is deleted
|
-- only that line is deleted
|
||||||
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_line_under_mouse_pointer/shape:1')
|
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_line_under_mouse_pointer/shape:1')
|
||||||
|
@ -547,27 +547,27 @@ end
|
||||||
function test_delete_point_from_polygon()
|
function test_delete_point_from_polygon()
|
||||||
io.write('\ntest_delete_point_from_polygon')
|
io.write('\ntest_delete_point_from_polygon')
|
||||||
-- create a drawing with two lines connected at a point
|
-- create a drawing with two lines connected at a point
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_keychord('g') -- polygon mode
|
App.run_after_keychord('g') -- polygon mode
|
||||||
-- second point
|
-- second point
|
||||||
App.mouse_move(Margin_left+65, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('p') -- add point
|
App.run_after_keychord('p') -- add point
|
||||||
-- third point
|
-- third point
|
||||||
App.mouse_move(Margin_left+35, Margin_top+Drawing_padding_top+26)
|
App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
|
||||||
App.run_after_keychord('p') -- add point
|
App.run_after_keychord('p') -- add point
|
||||||
-- fourth point
|
-- fourth point
|
||||||
App.run_after_mouse_release(Margin_left+14, Margin_top+Drawing_padding_top+16, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+14, Editor_state.margin_top+Editor_state.drawing_padding_top+16, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
|
||||||
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
|
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
|
||||||
check_eq(#drawing.shapes[1].vertices, 4, 'F - test_delete_point_from_polygon/baseline/vertices')
|
check_eq(#drawing.shapes[1].vertices, 4, 'F - test_delete_point_from_polygon/baseline/vertices')
|
||||||
-- hover on a point and delete
|
-- hover on a point and delete
|
||||||
App.mouse_move(Margin_left+35, Margin_top+Drawing_padding_top+26)
|
App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+26)
|
||||||
App.run_after_keychord('C-d')
|
App.run_after_keychord('C-d')
|
||||||
-- just the one point is deleted
|
-- just the one point is deleted
|
||||||
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/shape')
|
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/shape')
|
||||||
|
@ -577,24 +577,24 @@ end
|
||||||
function test_delete_point_from_polygon()
|
function test_delete_point_from_polygon()
|
||||||
io.write('\ntest_delete_point_from_polygon')
|
io.write('\ntest_delete_point_from_polygon')
|
||||||
-- create a drawing with two lines connected at a point
|
-- create a drawing with two lines connected at a point
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- first point
|
-- first point
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_keychord('g') -- polygon mode
|
App.run_after_keychord('g') -- polygon mode
|
||||||
-- second point
|
-- second point
|
||||||
App.mouse_move(Margin_left+65, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('p') -- add point
|
App.run_after_keychord('p') -- add point
|
||||||
-- third point
|
-- third point
|
||||||
App.run_after_mouse_release(Margin_left+14, Margin_top+Drawing_padding_top+16, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+14, Editor_state.margin_top+Editor_state.drawing_padding_top+16, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_delete_point_from_polygon/baseline/#shapes')
|
||||||
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
|
check_eq(drawing.shapes[1].mode, 'polygon', 'F - test_delete_point_from_polygon/baseline/mode')
|
||||||
check_eq(#drawing.shapes[1].vertices, 3, 'F - test_delete_point_from_polygon/baseline/vertices')
|
check_eq(#drawing.shapes[1].vertices, 3, 'F - test_delete_point_from_polygon/baseline/vertices')
|
||||||
-- hover on a point and delete
|
-- hover on a point and delete
|
||||||
App.mouse_move(Margin_left+65, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+65, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('C-d')
|
App.run_after_keychord('C-d')
|
||||||
-- there's < 3 points left, so the whole polygon is deleted
|
-- there's < 3 points left, so the whole polygon is deleted
|
||||||
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_point_from_polygon')
|
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_delete_point_from_polygon')
|
||||||
|
@ -603,15 +603,15 @@ end
|
||||||
function test_undo_name_point()
|
function test_undo_name_point()
|
||||||
io.write('\ntest_undo_name_point')
|
io.write('\ntest_undo_name_point')
|
||||||
-- create a drawing with a line
|
-- create a drawing with a line
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
-- draw a line
|
-- draw a line
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_undo_name_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_undo_name_point/baseline/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_undo_name_point/baseline/#points')
|
check_eq(#drawing.points, 2, 'F - test_undo_name_point/baseline/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_name_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_name_point/baseline/shape:1')
|
||||||
|
@ -622,40 +622,40 @@ function test_undo_name_point()
|
||||||
check_eq(p2.x, 35, 'F - test_undo_name_point/baseline/p2:x')
|
check_eq(p2.x, 35, 'F - test_undo_name_point/baseline/p2:x')
|
||||||
check_eq(p2.y, 36, 'F - test_undo_name_point/baseline/p2:y')
|
check_eq(p2.y, 36, 'F - test_undo_name_point/baseline/p2:y')
|
||||||
check_nil(p2.name, 'F - test_undo_name_point/baseline/p2:name')
|
check_nil(p2.name, 'F - test_undo_name_point/baseline/p2:name')
|
||||||
check_eq(#History, 1, 'F - test_undo_name_point/baseline/history:1')
|
check_eq(#Editor_state.history, 1, 'F - test_undo_name_point/baseline/history:1')
|
||||||
-- enter 'name' mode without moving the mouse
|
-- enter 'name' mode without moving the mouse
|
||||||
App.run_after_keychord('C-n')
|
App.run_after_keychord('C-n')
|
||||||
App.run_after_textinput('A')
|
App.run_after_textinput('A')
|
||||||
App.run_after_keychord('return')
|
App.run_after_keychord('return')
|
||||||
check_eq(p2.name, 'A', 'F - test_undo_name_point/baseline')
|
check_eq(p2.name, 'A', 'F - test_undo_name_point/baseline')
|
||||||
check_eq(#History, 3, 'F - test_undo_name_point/baseline/history:2')
|
check_eq(#Editor_state.history, 3, 'F - test_undo_name_point/baseline/history:2')
|
||||||
check_eq(Next_history, 4, 'F - test_undo_name_point/baseline/next_history')
|
check_eq(Editor_state.next_history, 4, 'F - test_undo_name_point/baseline/next_history')
|
||||||
-- undo
|
-- undo
|
||||||
App.run_after_keychord('C-z')
|
App.run_after_keychord('C-z')
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
local p2 = drawing.points[drawing.shapes[1].p2]
|
local p2 = drawing.points[drawing.shapes[1].p2]
|
||||||
check_eq(Next_history, 3, 'F - test_undo_name_point/next_history')
|
check_eq(Editor_state.next_history, 3, 'F - test_undo_name_point/next_history')
|
||||||
check_eq(p2.name, '', 'F - test_undo_name_point') -- not quite what it was before, but close enough
|
check_eq(p2.name, '', 'F - test_undo_name_point') -- not quite what it was before, but close enough
|
||||||
-- wait until save
|
-- wait until save
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- undo is saved
|
-- undo is saved
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local p2 = Lines[1].points[drawing.shapes[1].p2]
|
local p2 = Editor_state.lines[1].points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.name, '', 'F - test_undo_name_point/save')
|
check_eq(p2.name, '', 'F - test_undo_name_point/save')
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_undo_move_point()
|
function test_undo_move_point()
|
||||||
io.write('\ntest_undo_move_point')
|
io.write('\ntest_undo_move_point')
|
||||||
-- create a drawing with a line
|
-- create a drawing with a line
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 1, 'F - test_undo_move_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 1, 'F - test_undo_move_point/baseline/#shapes')
|
||||||
check_eq(#drawing.points, 2, 'F - test_undo_move_point/baseline/#points')
|
check_eq(#drawing.points, 2, 'F - test_undo_move_point/baseline/#points')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_move_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_move_point/baseline/shape:1')
|
||||||
|
@ -668,28 +668,28 @@ function test_undo_move_point()
|
||||||
check_nil(p2.name, 'F - test_undo_move_point/baseline/p2:name')
|
check_nil(p2.name, 'F - test_undo_move_point/baseline/p2:name')
|
||||||
-- move p2
|
-- move p2
|
||||||
App.run_after_keychord('C-u')
|
App.run_after_keychord('C-u')
|
||||||
App.mouse_move(Margin_left+26, Margin_top+Drawing_padding_top+44)
|
App.mouse_move(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44)
|
||||||
App.update(0.05)
|
App.update(0.05)
|
||||||
local p2 = drawing.points[drawing.shapes[1].p2]
|
local p2 = drawing.points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.x, 26, 'F - test_undo_move_point/x')
|
check_eq(p2.x, 26, 'F - test_undo_move_point/x')
|
||||||
check_eq(p2.y, 44, 'F - test_undo_move_point/y')
|
check_eq(p2.y, 44, 'F - test_undo_move_point/y')
|
||||||
-- exit 'move' mode
|
-- exit 'move' mode
|
||||||
App.run_after_mouse_click(Margin_left+26, Margin_top+Drawing_padding_top+44, 1)
|
App.run_after_mouse_click(Editor_state.margin_left+26, Editor_state.margin_top+Editor_state.drawing_padding_top+44, 1)
|
||||||
check_eq(Next_history, 4, 'F - test_undo_move_point/next_history')
|
check_eq(Editor_state.next_history, 4, 'F - test_undo_move_point/next_history')
|
||||||
-- undo
|
-- undo
|
||||||
App.run_after_keychord('C-z')
|
App.run_after_keychord('C-z')
|
||||||
App.run_after_keychord('C-z') -- bug: need to undo twice
|
App.run_after_keychord('C-z') -- bug: need to undo twice
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
local p2 = drawing.points[drawing.shapes[1].p2]
|
local p2 = drawing.points[drawing.shapes[1].p2]
|
||||||
check_eq(Next_history, 2, 'F - test_undo_move_point/next_history')
|
check_eq(Editor_state.next_history, 2, 'F - test_undo_move_point/next_history')
|
||||||
check_eq(p2.x, 35, 'F - test_undo_move_point/x')
|
check_eq(p2.x, 35, 'F - test_undo_move_point/x')
|
||||||
check_eq(p2.y, 36, 'F - test_undo_move_point/y')
|
check_eq(p2.y, 36, 'F - test_undo_move_point/y')
|
||||||
-- wait until save
|
-- wait until save
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- undo is saved
|
-- undo is saved
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
local p2 = Lines[1].points[drawing.shapes[1].p2]
|
local p2 = Editor_state.lines[1].points[drawing.shapes[1].p2]
|
||||||
check_eq(p2.x, 35, 'F - test_undo_move_point/save/x')
|
check_eq(p2.x, 35, 'F - test_undo_move_point/save/x')
|
||||||
check_eq(p2.y, 36, 'F - test_undo_move_point/save/y')
|
check_eq(p2.y, 36, 'F - test_undo_move_point/save/y')
|
||||||
end
|
end
|
||||||
|
@ -697,35 +697,35 @@ end
|
||||||
function test_undo_delete_point()
|
function test_undo_delete_point()
|
||||||
io.write('\ntest_undo_delete_point')
|
io.write('\ntest_undo_delete_point')
|
||||||
-- create a drawing with two lines connected at a point
|
-- create a drawing with two lines connected at a point
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
App.screen.init{width=Editor_state.margin_width+256, height=300} -- drawing coordinates 1:1 with pixels
|
||||||
Lines = load_array{'```lines', '```', ''}
|
Editor_state.lines = load_array{'```lines', '```', ''}
|
||||||
Current_drawing_mode = 'line'
|
Editor_state.current_drawing_mode = 'line'
|
||||||
edit.draw()
|
edit.draw()
|
||||||
App.run_after_mouse_press(Margin_left+5, Margin_top+Drawing_padding_top+6, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+5, Editor_state.margin_top+Editor_state.drawing_padding_top+6, 1)
|
||||||
App.run_after_mouse_release(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_press(Margin_left+35, Margin_top+Drawing_padding_top+36, 1)
|
App.run_after_mouse_press(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36, 1)
|
||||||
App.run_after_mouse_release(Margin_left+55, Margin_top+Drawing_padding_top+26, 1)
|
App.run_after_mouse_release(Editor_state.margin_left+55, Editor_state.margin_top+Editor_state.drawing_padding_top+26, 1)
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
check_eq(#drawing.shapes, 2, 'F - test_undo_delete_point/baseline/#shapes')
|
check_eq(#drawing.shapes, 2, 'F - test_undo_delete_point/baseline/#shapes')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_delete_point/baseline/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_delete_point/baseline/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'line', 'F - test_undo_delete_point/baseline/shape:2')
|
check_eq(drawing.shapes[2].mode, 'line', 'F - test_undo_delete_point/baseline/shape:2')
|
||||||
-- hover on the common point and delete
|
-- hover on the common point and delete
|
||||||
App.mouse_move(Margin_left+35, Margin_top+Drawing_padding_top+36)
|
App.mouse_move(Editor_state.margin_left+35, Editor_state.margin_top+Editor_state.drawing_padding_top+36)
|
||||||
App.run_after_keychord('C-d')
|
App.run_after_keychord('C-d')
|
||||||
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_undo_delete_point/shape:1')
|
check_eq(drawing.shapes[1].mode, 'deleted', 'F - test_undo_delete_point/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_undo_delete_point/shape:2')
|
check_eq(drawing.shapes[2].mode, 'deleted', 'F - test_undo_delete_point/shape:2')
|
||||||
-- undo
|
-- undo
|
||||||
App.run_after_keychord('C-z')
|
App.run_after_keychord('C-z')
|
||||||
local drawing = Lines[1]
|
local drawing = Editor_state.lines[1]
|
||||||
local p2 = drawing.points[drawing.shapes[1].p2]
|
local p2 = drawing.points[drawing.shapes[1].p2]
|
||||||
check_eq(Next_history, 3, 'F - test_undo_move_point/next_history')
|
check_eq(Editor_state.next_history, 3, 'F - test_undo_move_point/next_history')
|
||||||
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_delete_point/shape:1')
|
check_eq(drawing.shapes[1].mode, 'line', 'F - test_undo_delete_point/shape:1')
|
||||||
check_eq(drawing.shapes[2].mode, 'line', 'F - test_undo_delete_point/shape:2')
|
check_eq(drawing.shapes[2].mode, 'line', 'F - test_undo_delete_point/shape:2')
|
||||||
-- wait until save
|
-- wait until save
|
||||||
App.wait_fake_time(3.1)
|
App.wait_fake_time(3.1)
|
||||||
App.update(0)
|
App.update(0)
|
||||||
-- undo is saved
|
-- undo is saved
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
check_eq(#Lines[1].shapes, 2, 'F - test_undo_delete_point/save')
|
check_eq(#Editor_state.lines[1].shapes, 2, 'F - test_undo_delete_point/save')
|
||||||
end
|
end
|
||||||
|
|
306
edit.lua
306
edit.lua
|
@ -22,7 +22,8 @@ require 'icons'
|
||||||
edit = {}
|
edit = {}
|
||||||
|
|
||||||
-- run in both tests and a real run
|
-- run in both tests and a real run
|
||||||
function edit.initialize_globals()
|
function edit.initialize_state()
|
||||||
|
local result = {
|
||||||
-- a line is either text or a drawing
|
-- a line is either text or a drawing
|
||||||
-- a text is a table with:
|
-- a text is a table with:
|
||||||
-- mode = 'text',
|
-- mode = 'text',
|
||||||
|
@ -48,7 +49,7 @@ function edit.initialize_globals()
|
||||||
-- Unless otherwise specified, coord fields are normalized; a drawing is always 256 units wide
|
-- 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
|
-- The field names are carefully chosen so that switching modes in midstream
|
||||||
-- remembers previously entered points where that makes sense.
|
-- remembers previously entered points where that makes sense.
|
||||||
Lines = {{mode='text', data=''}}
|
lines = {{mode='text', data=''}},
|
||||||
|
|
||||||
-- Lines can be too long to fit on screen, in which case they _wrap_ into
|
-- Lines can be too long to fit on screen, in which case they _wrap_ into
|
||||||
-- multiple _screen lines_.
|
-- multiple _screen lines_.
|
||||||
|
@ -62,60 +63,69 @@ Lines = {{mode='text', data=''}}
|
||||||
--
|
--
|
||||||
-- Make sure these coordinates are never aliased, so that changing one causes
|
-- Make sure these coordinates are never aliased, so that changing one causes
|
||||||
-- action at a distance.
|
-- action at a distance.
|
||||||
Screen_top1 = {line=1, pos=1} -- position of start of screen line at top of screen
|
screen_top1 = {line=1, pos=1}, -- position of start of screen line at top of screen
|
||||||
Cursor1 = {line=1, pos=1} -- position of cursor
|
cursor1 = {line=1, pos=1}, -- position of cursor
|
||||||
Screen_bottom1 = {line=1, pos=1} -- position of start of screen line at bottom of screen
|
screen_bottom1 = {line=1, pos=1}, -- position of start of screen line at bottom of screen
|
||||||
|
|
||||||
Selection1 = {}
|
selection1 = {},
|
||||||
Old_cursor1, Old_selection1, Mousepress_shift = nil -- some extra state to compute selection between mouse press and release
|
-- some extra state to compute selection between mouse press and release
|
||||||
Recent_mouse = {} -- when selecting text, avoid recomputing some state on every single frame
|
old_cursor1 = nil,
|
||||||
|
old_selection1 = nil,
|
||||||
|
mousepress_shift = nil,
|
||||||
|
-- when selecting text, avoid recomputing some state on every single frame
|
||||||
|
recent_mouse = {},
|
||||||
|
|
||||||
Cursor_x, Cursor_y = 0, 0 -- in pixels
|
-- cursor coordinates in pixels
|
||||||
|
cursor_x = 0,
|
||||||
|
cursor_y = 0,
|
||||||
|
|
||||||
Current_drawing_mode = 'line'
|
current_drawing_mode = 'line',
|
||||||
Previous_drawing_mode = nil
|
previous_drawing_mode = nil, -- extra state for some ephemeral modes like moving/deleting/naming points
|
||||||
|
|
||||||
-- values for tests
|
-- these default values are important for tests
|
||||||
Font_height = 14
|
font_height = 14,
|
||||||
Line_height = 15
|
line_height = 15,
|
||||||
-- widest possible character width
|
-- widest possible character width
|
||||||
Em = App.newText(love.graphics.getFont(), 'm')
|
em = App.newText(love.graphics.getFont(), 'm'),
|
||||||
|
|
||||||
Margin_top = 15
|
margin_top = 15,
|
||||||
Margin_left = 25
|
margin_left = 25,
|
||||||
Margin_right = 25
|
margin_right = 25,
|
||||||
Margin_width = Margin_left + Margin_right
|
margin_width = nil,
|
||||||
|
|
||||||
Drawing_padding_top = 10
|
drawing_padding_top = 10,
|
||||||
Drawing_padding_bottom = 10
|
drawing_padding_bottom = 10,
|
||||||
Drawing_padding_height = Drawing_padding_top + Drawing_padding_bottom
|
drawing_padding_height = nil,
|
||||||
|
|
||||||
Filename = love.filesystem.getUserDirectory()..'/lines.txt'
|
filename = love.filesystem.getUserDirectory()..'/lines.txt',
|
||||||
Next_save = nil
|
next_save = nil,
|
||||||
|
|
||||||
-- undo
|
-- undo
|
||||||
History = {}
|
history = {},
|
||||||
Next_history = 1
|
next_history = 1,
|
||||||
|
|
||||||
-- search
|
-- search
|
||||||
Search_term = nil
|
search_term = nil,
|
||||||
Search_text = nil
|
search_text = nil,
|
||||||
Search_backup = nil -- stuff to restore when cancelling search
|
search_backup = nil, -- stuff to restore when cancelling search
|
||||||
|
}
|
||||||
end -- App.initialize_globals
|
result.margin_width = result.margin_left + result.margin_right
|
||||||
|
result.drawing_padding_height = result.drawing_padding_top + result.drawing_padding_bottom
|
||||||
|
return result
|
||||||
|
end -- App.initialize_state
|
||||||
|
|
||||||
function edit.draw()
|
function edit.draw()
|
||||||
App.color(Text_color)
|
App.color(Text_color)
|
||||||
--? print(Screen_top1.line, Screen_top1.pos, Cursor1.line, Cursor1.pos)
|
--? print(Editor_state.screen_top1.line, Editor_state.screen_top1.pos, Editor_state.cursor1.line, Editor_state.cursor1.pos)
|
||||||
assert(Text.le1(Screen_top1, Cursor1))
|
assert(Text.le1(Editor_state.screen_top1, Editor_state.cursor1))
|
||||||
Cursor_y = -1
|
Editor_state.cursor_y = -1
|
||||||
local y = Margin_top
|
local y = Editor_state.margin_top
|
||||||
--? print('== draw')
|
--? print('== draw')
|
||||||
for line_index = Screen_top1.line,#Lines do
|
for line_index = Editor_state.screen_top1.line,#Editor_state.lines do
|
||||||
local line = Lines[line_index]
|
local line = Editor_state.lines[line_index]
|
||||||
--? print('draw:', y, line_index, line)
|
--? print('draw:', y, line_index, line)
|
||||||
if y + Line_height > App.screen.height then break end
|
if y + Editor_state.line_height > App.screen.height then break end
|
||||||
Screen_bottom1.line = line_index
|
Editor_state.screen_bottom1.line = line_index
|
||||||
if line.mode == 'text' and line.data == '' then
|
if line.mode == 'text' and line.data == '' then
|
||||||
line.starty = y
|
line.starty = y
|
||||||
line.startpos = 1
|
line.startpos = 1
|
||||||
|
@ -124,76 +134,76 @@ function edit.draw()
|
||||||
icon = icon.insert_drawing,
|
icon = icon.insert_drawing,
|
||||||
onpress1 = function()
|
onpress1 = function()
|
||||||
Drawing.before = snapshot(line_index-1, line_index)
|
Drawing.before = snapshot(line_index-1, line_index)
|
||||||
table.insert(Lines, line_index, {mode='drawing', y=y, h=256/2, points={}, shapes={}, pending={}})
|
table.insert(Editor_state.lines, line_index, {mode='drawing', y=y, h=256/2, points={}, shapes={}, pending={}})
|
||||||
if Cursor1.line >= line_index then
|
if Editor_state.cursor1.line >= line_index then
|
||||||
Cursor1.line = Cursor1.line+1
|
Editor_state.cursor1.line = Editor_state.cursor1.line+1
|
||||||
end
|
end
|
||||||
schedule_save()
|
schedule_save()
|
||||||
record_undo_event({before=Drawing.before, after=snapshot(line_index-1, line_index+1)})
|
record_undo_event({before=Drawing.before, after=snapshot(line_index-1, line_index+1)})
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
if Search_term == nil then
|
if Editor_state.search_term == nil then
|
||||||
if line_index == Cursor1.line then
|
if line_index == Editor_state.cursor1.line then
|
||||||
Text.draw_cursor(Margin_left, y)
|
Text.draw_cursor(Editor_state.margin_left, y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Screen_bottom1.pos = Screen_top1.pos
|
Editor_state.screen_bottom1.pos = Editor_state.screen_top1.pos
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
elseif line.mode == 'drawing' then
|
elseif line.mode == 'drawing' then
|
||||||
y = y+Drawing_padding_top
|
y = y+Editor_state.drawing_padding_top
|
||||||
line.y = y
|
line.y = y
|
||||||
Drawing.draw(line)
|
Drawing.draw(line)
|
||||||
y = y + Drawing.pixels(line.h) + Drawing_padding_bottom
|
y = y + Drawing.pixels(line.h) + Editor_state.drawing_padding_bottom
|
||||||
else
|
else
|
||||||
line.starty = y
|
line.starty = y
|
||||||
line.startpos = 1
|
line.startpos = 1
|
||||||
if line_index == Screen_top1.line then
|
if line_index == Editor_state.screen_top1.line then
|
||||||
line.startpos = Screen_top1.pos
|
line.startpos = Editor_state.screen_top1.pos
|
||||||
end
|
end
|
||||||
--? print('text.draw', y, line_index)
|
--? print('text.draw', y, line_index)
|
||||||
y, Screen_bottom1.pos = Text.draw(line, line_index, line.starty, Margin_left, App.screen.width-Margin_right)
|
y, Editor_state.screen_bottom1.pos = Text.draw(line, line_index, line.starty, Editor_state.margin_left, App.screen.width-Editor_state.margin_right)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
--? print('=> y', y)
|
--? print('=> y', y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Cursor_y == -1 then
|
if Editor_state.cursor_y == -1 then
|
||||||
Cursor_y = App.screen.height
|
Editor_state.cursor_y = App.screen.height
|
||||||
end
|
end
|
||||||
--? print('screen bottom: '..tostring(Screen_bottom1.pos)..' in '..tostring(Lines[Screen_bottom1.line].data))
|
--? print('screen bottom: '..tostring(Editor_state.screen_bottom1.pos)..' in '..tostring(Editor_state.lines[Editor_state.screen_bottom1.line].data))
|
||||||
if Search_term then
|
if Editor_state.search_term then
|
||||||
Text.draw_search_bar()
|
Text.draw_search_bar()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.update(dt)
|
function edit.update(dt)
|
||||||
Drawing.update(dt)
|
Drawing.update(dt)
|
||||||
if Next_save and Next_save < App.getTime() then
|
if Editor_state.next_save and Editor_state.next_save < App.getTime() then
|
||||||
save_to_disk(Lines, Filename)
|
save_to_disk(Editor_state.lines, Editor_state.filename)
|
||||||
Next_save = nil
|
Editor_state.next_save = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function schedule_save()
|
function schedule_save()
|
||||||
if Next_save == nil then
|
if Editor_state.next_save == nil then
|
||||||
Next_save = App.getTime() + 3 -- short enough that you're likely to still remember what you did
|
Editor_state.next_save = App.getTime() + 3 -- short enough that you're likely to still remember what you did
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.quit()
|
function edit.quit()
|
||||||
-- make sure to save before quitting
|
-- make sure to save before quitting
|
||||||
if Next_save then
|
if Editor_state.next_save then
|
||||||
save_to_disk(Lines, Filename)
|
save_to_disk(Editor_state.lines, Editor_state.filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.mouse_pressed(x,y, mouse_button)
|
function edit.mouse_pressed(x,y, mouse_button)
|
||||||
if Search_term then return end
|
if Editor_state.search_term then return end
|
||||||
--? print('press', Selection1.line, Selection1.pos)
|
--? print('press', Editor_state.selection1.line, Editor_state.selection1.pos)
|
||||||
propagate_to_button_handlers(x,y, mouse_button)
|
propagate_to_button_handlers(x,y, mouse_button)
|
||||||
|
|
||||||
for line_index,line in ipairs(Lines) do
|
for line_index,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
if Text.in_line(line, x,y, Margin_left, App.screen.width-Margin_right) then
|
if Text.in_line(line, x,y, Editor_state.margin_left, App.screen.width-Editor_state.margin_right) then
|
||||||
-- delicate dance between cursor, selection and old cursor/selection
|
-- delicate dance between cursor, selection and old cursor/selection
|
||||||
-- scenarios:
|
-- scenarios:
|
||||||
-- regular press+release: sets cursor, clears selection
|
-- regular press+release: sets cursor, clears selection
|
||||||
|
@ -203,20 +213,20 @@ function edit.mouse_pressed(x,y, mouse_button)
|
||||||
-- press and hold to start a selection: sets selection on press, cursor on release
|
-- press and hold to start a selection: sets selection on press, cursor on release
|
||||||
-- press and hold, then press shift: ignore shift
|
-- press and hold, then press shift: ignore shift
|
||||||
-- i.e. mousereleased should never look at shift state
|
-- i.e. mousereleased should never look at shift state
|
||||||
Old_cursor1 = Cursor1
|
Editor_state.old_cursor1 = Editor_state.cursor1
|
||||||
Old_selection1 = Selection1
|
Editor_state.old_selection1 = Editor_state.selection1
|
||||||
Mousepress_shift = App.shift_down()
|
Editor_state.mousepress_shift = App.shift_down()
|
||||||
Selection1 = {
|
Editor_state.selection1 = {
|
||||||
line=line_index,
|
line=line_index,
|
||||||
pos=Text.to_pos_on_line(line, x, y, Margin_left, App.screen.width-Margin_right),
|
pos=Text.to_pos_on_line(line, x, y, Editor_state.margin_left, App.screen.width-Editor_state.margin_right),
|
||||||
}
|
}
|
||||||
--? print('selection', Selection1.line, Selection1.pos)
|
--? print('selection', Editor_state.selection1.line, Editor_state.selection1.pos)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
elseif line.mode == 'drawing' then
|
elseif line.mode == 'drawing' then
|
||||||
if Drawing.in_drawing(line, x, y) then
|
if Drawing.in_drawing(line, x, y) then
|
||||||
Lines.current_drawing_index = line_index
|
Editor_state.lines.current_drawing_index = line_index
|
||||||
Lines.current_drawing = line
|
Editor_state.lines.current_drawing = line
|
||||||
Drawing.before = snapshot(line_index)
|
Drawing.before = snapshot(line_index)
|
||||||
Drawing.mouse_pressed(line, x,y, mouse_button)
|
Drawing.mouse_pressed(line, x,y, mouse_button)
|
||||||
break
|
break
|
||||||
|
@ -226,56 +236,56 @@ function edit.mouse_pressed(x,y, mouse_button)
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.mouse_released(x,y, mouse_button)
|
function edit.mouse_released(x,y, mouse_button)
|
||||||
if Search_term then return end
|
if Editor_state.search_term then return end
|
||||||
--? print('release')
|
--? print('release')
|
||||||
if Lines.current_drawing then
|
if Editor_state.lines.current_drawing then
|
||||||
Drawing.mouse_released(x,y, mouse_button)
|
Drawing.mouse_released(x,y, mouse_button)
|
||||||
schedule_save()
|
schedule_save()
|
||||||
if Drawing.before then
|
if Drawing.before then
|
||||||
record_undo_event({before=Drawing.before, after=snapshot(Lines.current_drawing_index)})
|
record_undo_event({before=Drawing.before, after=snapshot(Editor_state.lines.current_drawing_index)})
|
||||||
Drawing.before = nil
|
Drawing.before = nil
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for line_index,line in ipairs(Lines) do
|
for line_index,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
if Text.in_line(line, x,y, Margin_left, App.screen.width-Margin_right) then
|
if Text.in_line(line, x,y, Editor_state.margin_left, App.screen.width-Editor_state.margin_right) then
|
||||||
--? print('reset selection')
|
--? print('reset selection')
|
||||||
Cursor1 = {
|
Editor_state.cursor1 = {
|
||||||
line=line_index,
|
line=line_index,
|
||||||
pos=Text.to_pos_on_line(line, x, y, Margin_left, App.screen.width-Margin_right),
|
pos=Text.to_pos_on_line(line, x, y, Editor_state.margin_left, App.screen.width-Editor_state.margin_right),
|
||||||
}
|
}
|
||||||
--? print('cursor', Cursor1.line, Cursor1.pos)
|
--? print('cursor', Editor_state.cursor1.line, Editor_state.cursor1.pos)
|
||||||
if Mousepress_shift then
|
if Editor_state.mousepress_shift then
|
||||||
if Old_selection1.line == nil then
|
if Editor_state.old_selection1.line == nil then
|
||||||
Selection1 = Old_cursor1
|
Editor_state.selection1 = Editor_state.old_cursor1
|
||||||
else
|
else
|
||||||
Selection1 = Old_selection1
|
Editor_state.selection1 = Editor_state.old_selection1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Old_cursor1, Old_selection1, Mousepress_shift = nil
|
Editor_state.old_cursor1, Editor_state.old_selection1, Editor_state.mousepress_shift = nil
|
||||||
if eq(Cursor1, Selection1) then
|
if eq(Editor_state.cursor1, Editor_state.selection1) then
|
||||||
Selection1 = {}
|
Editor_state.selection1 = {}
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--? print('selection:', Selection1.line, Selection1.pos)
|
--? print('selection:', Editor_state.selection1.line, Editor_state.selection1.pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.textinput(t)
|
function edit.textinput(t)
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
if Search_term then
|
if Editor_state.search_term then
|
||||||
Search_term = Search_term..t
|
Editor_state.search_term = Editor_state.search_term..t
|
||||||
Search_text = nil
|
Editor_state.search_text = nil
|
||||||
Text.search_next()
|
Text.search_next()
|
||||||
elseif Current_drawing_mode == 'name' then
|
elseif Editor_state.current_drawing_mode == 'name' then
|
||||||
local before = snapshot(Lines.current_drawing_index)
|
local before = snapshot(Editor_state.lines.current_drawing_index)
|
||||||
local drawing = Lines.current_drawing
|
local drawing = Editor_state.lines.current_drawing
|
||||||
local p = drawing.points[drawing.pending.target_point]
|
local p = drawing.points[drawing.pending.target_point]
|
||||||
p.name = p.name..t
|
p.name = p.name..t
|
||||||
record_undo_event({before=before, after=snapshot(Lines.current_drawing_index)})
|
record_undo_event({before=before, after=snapshot(Editor_state.lines.current_drawing_index)})
|
||||||
else
|
else
|
||||||
Text.textinput(t)
|
Text.textinput(t)
|
||||||
end
|
end
|
||||||
|
@ -283,94 +293,94 @@ function edit.textinput(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
function edit.keychord_pressed(chord, key)
|
function edit.keychord_pressed(chord, key)
|
||||||
if Selection1.line and
|
if Editor_state.selection1.line and
|
||||||
not Lines.current_drawing and
|
not Editor_state.lines.current_drawing and
|
||||||
-- printable character created using shift key => delete selection
|
-- printable character created using shift key => delete selection
|
||||||
-- (we're not creating any ctrl-shift- or alt-shift- combinations using regular/printable keys)
|
-- (we're not creating any ctrl-shift- or alt-shift- combinations using regular/printable keys)
|
||||||
(not App.shift_down() or utf8.len(key) == 1) and
|
(not App.shift_down() or utf8.len(key) == 1) and
|
||||||
chord ~= 'C-c' and chord ~= 'C-x' and chord ~= 'backspace' and backspace ~= 'delete' and not App.is_cursor_movement(chord) then
|
chord ~= 'C-c' and chord ~= 'C-x' and chord ~= 'backspace' and backspace ~= 'delete' and not App.is_cursor_movement(chord) then
|
||||||
Text.delete_selection(Margin_left, App.screen.width-Margin_right)
|
Text.delete_selection(Editor_state.margin_left, App.screen.width-Editor_state.margin_right)
|
||||||
end
|
end
|
||||||
if Search_term then
|
if Editor_state.search_term then
|
||||||
if chord == 'escape' then
|
if chord == 'escape' then
|
||||||
Search_term = nil
|
Editor_state.search_term = nil
|
||||||
Search_text = nil
|
Editor_state.search_text = nil
|
||||||
Cursor1 = Search_backup.cursor
|
Editor_state.cursor1 = Editor_state.search_backup.cursor
|
||||||
Screen_top1 = Search_backup.screen_top
|
Editor_state.screen_top1 = Editor_state.search_backup.screen_top
|
||||||
Search_backup = nil
|
Editor_state.search_backup = nil
|
||||||
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
||||||
elseif chord == 'return' then
|
elseif chord == 'return' then
|
||||||
Search_term = nil
|
Editor_state.search_term = nil
|
||||||
Search_text = nil
|
Editor_state.search_text = nil
|
||||||
Search_backup = nil
|
Editor_state.search_backup = nil
|
||||||
elseif chord == 'backspace' then
|
elseif chord == 'backspace' then
|
||||||
local len = utf8.len(Search_term)
|
local len = utf8.len(Editor_state.search_term)
|
||||||
local byte_offset = Text.offset(Search_term, len)
|
local byte_offset = Text.offset(Editor_state.search_term, len)
|
||||||
Search_term = string.sub(Search_term, 1, byte_offset-1)
|
Editor_state.search_term = string.sub(Editor_state.search_term, 1, byte_offset-1)
|
||||||
Search_text = nil
|
Editor_state.search_text = nil
|
||||||
elseif chord == 'down' then
|
elseif chord == 'down' then
|
||||||
Cursor1.pos = Cursor1.pos+1
|
Editor_state.cursor1.pos = Editor_state.cursor1.pos+1
|
||||||
Text.search_next()
|
Text.search_next()
|
||||||
elseif chord == 'up' then
|
elseif chord == 'up' then
|
||||||
Text.search_previous()
|
Text.search_previous()
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
elseif chord == 'C-f' then
|
elseif chord == 'C-f' then
|
||||||
Search_term = ''
|
Editor_state.search_term = ''
|
||||||
Search_backup = {cursor={line=Cursor1.line, pos=Cursor1.pos}, screen_top={line=Screen_top1.line, pos=Screen_top1.pos}}
|
Editor_state.search_backup = {cursor={line=Editor_state.cursor1.line, pos=Editor_state.cursor1.pos}, screen_top={line=Editor_state.screen_top1.line, pos=Editor_state.screen_top1.pos}}
|
||||||
assert(Search_text == nil)
|
assert(Editor_state.search_text == nil)
|
||||||
elseif chord == 'C-=' then
|
elseif chord == 'C-=' then
|
||||||
initialize_font_settings(Font_height+2)
|
initialize_font_settings(Editor_state.font_height+2)
|
||||||
Text.redraw_all()
|
Text.redraw_all()
|
||||||
elseif chord == 'C--' then
|
elseif chord == 'C--' then
|
||||||
initialize_font_settings(Font_height-2)
|
initialize_font_settings(Editor_state.font_height-2)
|
||||||
Text.redraw_all()
|
Text.redraw_all()
|
||||||
elseif chord == 'C-0' then
|
elseif chord == 'C-0' then
|
||||||
initialize_font_settings(20)
|
initialize_font_settings(20)
|
||||||
Text.redraw_all()
|
Text.redraw_all()
|
||||||
elseif chord == 'C-z' then
|
elseif chord == 'C-z' then
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
local event = undo_event()
|
local event = undo_event()
|
||||||
if event then
|
if event then
|
||||||
local src = event.before
|
local src = event.before
|
||||||
Screen_top1 = deepcopy(src.screen_top)
|
Editor_state.screen_top1 = deepcopy(src.screen_top)
|
||||||
Cursor1 = deepcopy(src.cursor)
|
Editor_state.cursor1 = deepcopy(src.cursor)
|
||||||
Selection1 = deepcopy(src.selection)
|
Editor_state.selection1 = deepcopy(src.selection)
|
||||||
patch(Lines, event.after, event.before)
|
patch(Editor_state.lines, event.after, event.before)
|
||||||
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
||||||
schedule_save()
|
schedule_save()
|
||||||
end
|
end
|
||||||
elseif chord == 'C-y' then
|
elseif chord == 'C-y' then
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
local event = redo_event()
|
local event = redo_event()
|
||||||
if event then
|
if event then
|
||||||
local src = event.after
|
local src = event.after
|
||||||
Screen_top1 = deepcopy(src.screen_top)
|
Editor_state.screen_top1 = deepcopy(src.screen_top)
|
||||||
Cursor1 = deepcopy(src.cursor)
|
Editor_state.cursor1 = deepcopy(src.cursor)
|
||||||
Selection1 = deepcopy(src.selection)
|
Editor_state.selection1 = deepcopy(src.selection)
|
||||||
patch(Lines, event.before, event.after)
|
patch(Editor_state.lines, event.before, event.after)
|
||||||
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
Text.redraw_all() -- if we're scrolling, reclaim all fragments to avoid memory leaks
|
||||||
schedule_save()
|
schedule_save()
|
||||||
end
|
end
|
||||||
-- clipboard
|
-- clipboard
|
||||||
elseif chord == 'C-c' then
|
elseif chord == 'C-c' then
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
local s = Text.selection()
|
local s = Text.selection()
|
||||||
if s then
|
if s then
|
||||||
App.setClipboardText(s)
|
App.setClipboardText(s)
|
||||||
end
|
end
|
||||||
elseif chord == 'C-x' then
|
elseif chord == 'C-x' then
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
local s = Text.cut_selection(Margin_left, App.screen.width-Margin_right)
|
local s = Text.cut_selection(Editor_state.margin_left, App.screen.width-Editor_state.margin_right)
|
||||||
if s then
|
if s then
|
||||||
App.setClipboardText(s)
|
App.setClipboardText(s)
|
||||||
end
|
end
|
||||||
schedule_save()
|
schedule_save()
|
||||||
elseif chord == 'C-v' then
|
elseif chord == 'C-v' then
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
-- We don't have a good sense of when to scroll, so we'll be conservative
|
-- We don't have a good sense of when to scroll, so we'll be conservative
|
||||||
-- and sometimes scroll when we didn't quite need to.
|
-- and sometimes scroll when we didn't quite need to.
|
||||||
local before_line = Cursor1.line
|
local before_line = Editor_state.cursor1.line
|
||||||
local before = snapshot(before_line)
|
local before = snapshot(before_line)
|
||||||
local clipboard_data = App.getClipboardText()
|
local clipboard_data = App.getClipboardText()
|
||||||
for _,code in utf8.codes(clipboard_data) do
|
for _,code in utf8.codes(clipboard_data) do
|
||||||
|
@ -382,10 +392,10 @@ function edit.keychord_pressed(chord, key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Text.cursor_past_screen_bottom() then
|
if Text.cursor_past_screen_bottom() then
|
||||||
Text.snap_cursor_to_bottom_of_screen(Margin_left, App.screen.height-Margin_right)
|
Text.snap_cursor_to_bottom_of_screen(Editor_state.margin_left, App.screen.height-Editor_state.margin_right)
|
||||||
end
|
end
|
||||||
schedule_save()
|
schedule_save()
|
||||||
record_undo_event({before=before, after=snapshot(before_line, Cursor1.line)})
|
record_undo_event({before=before, after=snapshot(before_line, Editor_state.cursor1.line)})
|
||||||
-- dispatch to drawing or text
|
-- dispatch to drawing or text
|
||||||
elseif App.mouse_down(1) or chord:sub(1,2) == 'C-' then
|
elseif App.mouse_down(1) or chord:sub(1,2) == 'C-' then
|
||||||
-- DON'T reset line.y here
|
-- DON'T reset line.y here
|
||||||
|
@ -397,33 +407,33 @@ function edit.keychord_pressed(chord, key)
|
||||||
schedule_save()
|
schedule_save()
|
||||||
end
|
end
|
||||||
elseif chord == 'escape' and not App.mouse_down(1) then
|
elseif chord == 'escape' and not App.mouse_down(1) then
|
||||||
for _,line in ipairs(Lines) do
|
for _,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'drawing' then
|
if line.mode == 'drawing' then
|
||||||
line.show_help = false
|
line.show_help = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif Current_drawing_mode == 'name' then
|
elseif Editor_state.current_drawing_mode == 'name' then
|
||||||
if chord == 'return' then
|
if chord == 'return' then
|
||||||
Current_drawing_mode = Previous_drawing_mode
|
Editor_state.current_drawing_mode = Editor_state.previous_drawing_mode
|
||||||
Previous_drawing_mode = nil
|
Editor_state.previous_drawing_mode = nil
|
||||||
else
|
else
|
||||||
local before = snapshot(Lines.current_drawing_index)
|
local before = snapshot(Editor_state.lines.current_drawing_index)
|
||||||
local drawing = Lines.current_drawing
|
local drawing = Editor_state.lines.current_drawing
|
||||||
local p = drawing.points[drawing.pending.target_point]
|
local p = drawing.points[drawing.pending.target_point]
|
||||||
if chord == 'escape' then
|
if chord == 'escape' then
|
||||||
p.name = nil
|
p.name = nil
|
||||||
record_undo_event({before=before, after=snapshot(Lines.current_drawing_index)})
|
record_undo_event({before=before, after=snapshot(Editor_state.lines.current_drawing_index)})
|
||||||
elseif chord == 'backspace' then
|
elseif chord == 'backspace' then
|
||||||
local len = utf8.len(p.name)
|
local len = utf8.len(p.name)
|
||||||
local byte_offset = Text.offset(p.name, len-1)
|
local byte_offset = Text.offset(p.name, len-1)
|
||||||
if len == 1 then byte_offset = 0 end
|
if len == 1 then byte_offset = 0 end
|
||||||
p.name = string.sub(p.name, 1, byte_offset)
|
p.name = string.sub(p.name, 1, byte_offset)
|
||||||
record_undo_event({before=before, after=snapshot(Lines.current_drawing_index)})
|
record_undo_event({before=before, after=snapshot(Editor_state.lines.current_drawing_index)})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
schedule_save()
|
schedule_save()
|
||||||
else
|
else
|
||||||
for _,line in ipairs(Lines) do line.y = nil end -- just in case we scroll
|
for _,line in ipairs(Editor_state.lines) do line.y = nil end -- just in case we scroll
|
||||||
Text.keychord_pressed(chord)
|
Text.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
200
help.lua
200
help.lua
|
@ -1,144 +1,144 @@
|
||||||
function draw_help_without_mouse_pressed(drawing)
|
function draw_help_without_mouse_pressed(drawing)
|
||||||
App.color(Help_color)
|
App.color(Help_color)
|
||||||
local y = drawing.y+10
|
local y = drawing.y+10
|
||||||
love.graphics.print("Things you can do:", Margin_left+30,y)
|
love.graphics.print("Things you can do:", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Press the mouse button to start drawing a "..current_shape(), Margin_left+30,y)
|
love.graphics.print("* Press the mouse button to start drawing a "..current_shape(), Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Hover on a point and press 'ctrl+u' to pick it up and start moving it,", Margin_left+30,y)
|
love.graphics.print("* Hover on a point and press 'ctrl+u' to pick it up and start moving it,", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("then press the mouse button to drop it", Margin_left+30+bullet_indent(),y)
|
love.graphics.print("then press the mouse button to drop it", Editor_state.margin_left+30+bullet_indent(),y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", Margin_left+30,y)
|
love.graphics.print("* Hover on a point and press 'ctrl+n', type a name, then press 'enter'", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", Margin_left+30,y)
|
love.graphics.print("* Hover on a point or shape and press 'ctrl+d' to delete it", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
if Current_drawing_mode ~= 'freehand' then
|
if Editor_state.current_drawing_mode ~= 'freehand' then
|
||||||
love.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+p' to switch to drawing freehand strokes", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'line' then
|
if Editor_state.current_drawing_mode ~= 'line' then
|
||||||
love.graphics.print("* Press 'ctrl+l' to switch to drawing lines", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+l' to switch to drawing lines", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'manhattan' then
|
if Editor_state.current_drawing_mode ~= 'manhattan' then
|
||||||
love.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+m' to switch to drawing horizontal/vertical lines", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'circle' then
|
if Editor_state.current_drawing_mode ~= 'circle' then
|
||||||
love.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+o' to switch to drawing circles/arcs", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'polygon' then
|
if Editor_state.current_drawing_mode ~= 'polygon' then
|
||||||
love.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+g' to switch to drawing polygons", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'rectangle' then
|
if Editor_state.current_drawing_mode ~= 'rectangle' then
|
||||||
love.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+r' to switch to drawing rectangles", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'square' then
|
if Editor_state.current_drawing_mode ~= 'square' then
|
||||||
love.graphics.print("* Press 'ctrl+s' to switch to drawing squares", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+s' to switch to drawing squares", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
love.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", Margin_left+30,y)
|
love.graphics.print("* Press 'ctrl+=' or 'ctrl+-' to zoom in or out, ctrl+0 to reset zoom", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("Press 'esc' now to hide this message", Margin_left+30,y)
|
love.graphics.print("Press 'esc' now to hide this message", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
App.color(Help_background_color)
|
App.color(Help_background_color)
|
||||||
love.graphics.rectangle('fill', Margin_left,drawing.y, App.screen.width-Margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
|
love.graphics.rectangle('fill', Editor_state.margin_left,drawing.y, App.screen.width-Editor_state.margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
|
||||||
end
|
end
|
||||||
|
|
||||||
function draw_help_with_mouse_pressed(drawing)
|
function draw_help_with_mouse_pressed(drawing)
|
||||||
App.color(Help_color)
|
App.color(Help_color)
|
||||||
local y = drawing.y+10
|
local y = drawing.y+10
|
||||||
love.graphics.print("You're currently drawing a "..current_shape(drawing.pending), Margin_left+30,y)
|
love.graphics.print("You're currently drawing a "..current_shape(drawing.pending), Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print('Things you can do now:', Margin_left+30,y)
|
love.graphics.print('Things you can do now:', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
if Current_drawing_mode == 'freehand' then
|
if Editor_state.current_drawing_mode == 'freehand' then
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the stroke', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the stroke', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
elseif Current_drawing_mode == 'line' or Current_drawing_mode == 'manhattan' then
|
elseif Editor_state.current_drawing_mode == 'line' or Editor_state.current_drawing_mode == 'manhattan' then
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the line', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the line', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
elseif Current_drawing_mode == 'circle' then
|
elseif Editor_state.current_drawing_mode == 'circle' then
|
||||||
if drawing.pending.mode == 'circle' then
|
if drawing.pending.mode == 'circle' then
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the circle', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the circle', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Press 'a' to draw just an arc of a circle", Margin_left+30,y)
|
love.graphics.print("* Press 'a' to draw just an arc of a circle", Editor_state.margin_left+30,y)
|
||||||
else
|
else
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the arc', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the arc', Editor_state.margin_left+30,y)
|
||||||
end
|
end
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
elseif Current_drawing_mode == 'polygon' then
|
elseif Editor_state.current_drawing_mode == 'polygon' then
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the polygon', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the polygon', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Press 'p' to add a vertex to the polygon", Margin_left+30,y)
|
love.graphics.print("* Press 'p' to add a vertex to the polygon", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
elseif Current_drawing_mode == 'rectangle' then
|
elseif Editor_state.current_drawing_mode == 'rectangle' then
|
||||||
if #drawing.pending.vertices < 2 then
|
if #drawing.pending.vertices < 2 then
|
||||||
love.graphics.print("* Press 'p' to add a vertex to the rectangle", Margin_left+30,y)
|
love.graphics.print("* Press 'p' to add a vertex to the rectangle", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
else
|
else
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the rectangle', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the rectangle', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Press 'p' to replace the second vertex of the rectangle", Margin_left+30,y)
|
love.graphics.print("* Press 'p' to replace the second vertex of the rectangle", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
elseif Current_drawing_mode == 'square' then
|
elseif Editor_state.current_drawing_mode == 'square' then
|
||||||
if #drawing.pending.vertices < 2 then
|
if #drawing.pending.vertices < 2 then
|
||||||
love.graphics.print("* Press 'p' to add a vertex to the square", Margin_left+30,y)
|
love.graphics.print("* Press 'p' to add a vertex to the square", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
else
|
else
|
||||||
love.graphics.print('* Release the mouse button to finish drawing the square', Margin_left+30,y)
|
love.graphics.print('* Release the mouse button to finish drawing the square', Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
love.graphics.print("* Press 'p' to replace the second vertex of the square", Margin_left+30,y)
|
love.graphics.print("* Press 'p' to replace the second vertex of the square", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
love.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", Margin_left+30,y)
|
love.graphics.print("* Press 'esc' then release the mouse button to cancel the current shape", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
if Current_drawing_mode ~= 'line' then
|
if Editor_state.current_drawing_mode ~= 'line' then
|
||||||
love.graphics.print("* Press 'l' to switch to drawing lines", Margin_left+30,y)
|
love.graphics.print("* Press 'l' to switch to drawing lines", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'manhattan' then
|
if Editor_state.current_drawing_mode ~= 'manhattan' then
|
||||||
love.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", Margin_left+30,y)
|
love.graphics.print("* Press 'm' to switch to drawing horizontal/vertical lines", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'circle' then
|
if Editor_state.current_drawing_mode ~= 'circle' then
|
||||||
love.graphics.print("* Press 'o' to switch to drawing circles/arcs", Margin_left+30,y)
|
love.graphics.print("* Press 'o' to switch to drawing circles/arcs", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'polygon' then
|
if Editor_state.current_drawing_mode ~= 'polygon' then
|
||||||
love.graphics.print("* Press 'g' to switch to drawing polygons", Margin_left+30,y)
|
love.graphics.print("* Press 'g' to switch to drawing polygons", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'rectangle' then
|
if Editor_state.current_drawing_mode ~= 'rectangle' then
|
||||||
love.graphics.print("* Press 'r' to switch to drawing rectangles", Margin_left+30,y)
|
love.graphics.print("* Press 'r' to switch to drawing rectangles", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
if Current_drawing_mode ~= 'square' then
|
if Editor_state.current_drawing_mode ~= 'square' then
|
||||||
love.graphics.print("* Press 's' to switch to drawing squares", Margin_left+30,y)
|
love.graphics.print("* Press 's' to switch to drawing squares", Editor_state.margin_left+30,y)
|
||||||
y = y + Line_height
|
y = y + Editor_state.line_height
|
||||||
end
|
end
|
||||||
App.color(Help_background_color)
|
App.color(Help_background_color)
|
||||||
love.graphics.rectangle('fill', Margin_left,drawing.y, App.screen.width-Margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
|
love.graphics.rectangle('fill', Editor_state.margin_left,drawing.y, App.screen.width-Editor_state.margin_width, math.max(Drawing.pixels(drawing.h),y-drawing.y))
|
||||||
end
|
end
|
||||||
|
|
||||||
function current_shape(shape)
|
function current_shape(shape)
|
||||||
if Current_drawing_mode == 'freehand' then
|
if Editor_state.current_drawing_mode == 'freehand' then
|
||||||
return 'freehand stroke'
|
return 'freehand stroke'
|
||||||
elseif Current_drawing_mode == 'line' then
|
elseif Editor_state.current_drawing_mode == 'line' then
|
||||||
return 'straight line'
|
return 'straight line'
|
||||||
elseif Current_drawing_mode == 'manhattan' then
|
elseif Editor_state.current_drawing_mode == 'manhattan' then
|
||||||
return 'horizontal/vertical line'
|
return 'horizontal/vertical line'
|
||||||
elseif Current_drawing_mode == 'circle' and shape and shape.start_angle then
|
elseif Editor_state.current_drawing_mode == 'circle' and shape and shape.start_angle then
|
||||||
return 'arc'
|
return 'arc'
|
||||||
else
|
else
|
||||||
return Current_drawing_mode
|
return Editor_state.current_drawing_mode
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
64
main.lua
64
main.lua
|
@ -14,7 +14,7 @@ Editor_state = {}
|
||||||
|
|
||||||
-- called both in tests and real run
|
-- called both in tests and real run
|
||||||
function App.initialize_globals()
|
function App.initialize_globals()
|
||||||
edit.initialize_globals()
|
Editor_state = edit.initialize_state()
|
||||||
|
|
||||||
-- resize
|
-- resize
|
||||||
Last_resize_time = nil
|
Last_resize_time = nil
|
||||||
|
@ -37,28 +37,28 @@ function App.initialize(arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
if #arg > 0 then
|
if #arg > 0 then
|
||||||
Filename = arg[1]
|
Editor_state.filename = arg[1]
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
Screen_top1 = {line=1, pos=1}
|
Editor_state.screen_top1 = {line=1, pos=1}
|
||||||
Cursor1 = {line=1, pos=1}
|
Editor_state.cursor1 = {line=1, pos=1}
|
||||||
for i,line in ipairs(Lines) do
|
for i,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Lines = load_from_disk(Filename)
|
Editor_state.lines = load_from_disk(Editor_state.filename)
|
||||||
if Cursor1.line > #Lines or Lines[Cursor1.line].mode ~= 'text' then
|
if Editor_state.cursor1.line > #Editor_state.lines or Editor_state.lines[Editor_state.cursor1.line].mode ~= 'text' then
|
||||||
for i,line in ipairs(Lines) do
|
for i,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
love.window.setTitle('lines.love - '..Filename)
|
love.window.setTitle('lines.love - '..Editor_state.filename)
|
||||||
|
|
||||||
if #arg > 1 then
|
if #arg > 1 then
|
||||||
print('ignoring commandline args after '..arg[1])
|
print('ignoring commandline args after '..arg[1])
|
||||||
|
@ -83,10 +83,10 @@ function load_settings()
|
||||||
App.screen.flags.minheight = math.min(App.screen.width, 200)
|
App.screen.flags.minheight = math.min(App.screen.width, 200)
|
||||||
App.screen.width, App.screen.height = settings.width, settings.height
|
App.screen.width, App.screen.height = settings.width, settings.height
|
||||||
love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
|
love.window.setMode(App.screen.width, App.screen.height, App.screen.flags)
|
||||||
Filename = settings.filename
|
Editor_state.filename = settings.filename
|
||||||
initialize_font_settings(settings.font_height)
|
initialize_font_settings(settings.font_height)
|
||||||
Screen_top1 = settings.screen_top
|
Editor_state.screen_top1 = settings.screen_top
|
||||||
Cursor1 = settings.cursor
|
Editor_state.cursor1 = settings.cursor
|
||||||
end
|
end
|
||||||
|
|
||||||
function load_defaults()
|
function load_defaults()
|
||||||
|
@ -99,7 +99,7 @@ function initialize_window_geometry()
|
||||||
love.window.setMode(0, 0) -- maximize
|
love.window.setMode(0, 0) -- maximize
|
||||||
App.screen.width, App.screen.height, App.screen.flags = love.window.getMode()
|
App.screen.width, App.screen.height, App.screen.flags = love.window.getMode()
|
||||||
-- shrink slightly to account for window decoration
|
-- shrink slightly to account for window decoration
|
||||||
App.screen.width = 40*App.width(Em)
|
App.screen.width = 40*App.width(Editor_state.em)
|
||||||
App.screen.height = App.screen.height-100
|
App.screen.height = App.screen.height-100
|
||||||
App.screen.flags.resizable = true
|
App.screen.flags.resizable = true
|
||||||
App.screen.flags.minwidth = math.min(App.screen.width, 200)
|
App.screen.flags.minwidth = math.min(App.screen.width, 200)
|
||||||
|
@ -111,37 +111,37 @@ function App.resize(w, h)
|
||||||
--? print(("Window resized to width: %d and height: %d."):format(w, h))
|
--? print(("Window resized to width: %d and height: %d."):format(w, h))
|
||||||
App.screen.width, App.screen.height = w, h
|
App.screen.width, App.screen.height = w, h
|
||||||
Text.redraw_all()
|
Text.redraw_all()
|
||||||
Selection1 = {} -- no support for shift drag while we're resizing
|
Editor_state.selection1 = {} -- no support for shift drag while we're resizing
|
||||||
Text.tweak_screen_top_and_cursor(Margin_left, App.screen.height-Margin_right)
|
Text.tweak_screen_top_and_cursor(Editor_state.margin_left, App.screen.height-Editor_state.margin_right)
|
||||||
Last_resize_time = App.getTime()
|
Last_resize_time = App.getTime()
|
||||||
end
|
end
|
||||||
|
|
||||||
function initialize_font_settings(font_height)
|
function initialize_font_settings(font_height)
|
||||||
Font_height = font_height
|
Editor_state.font_height = font_height
|
||||||
love.graphics.setFont(love.graphics.newFont(Font_height))
|
love.graphics.setFont(love.graphics.newFont(Editor_state.font_height))
|
||||||
Line_height = math.floor(font_height*1.3)
|
Editor_state.line_height = math.floor(font_height*1.3)
|
||||||
|
|
||||||
Em = App.newText(love.graphics.getFont(), 'm')
|
Editor_state.em = App.newText(love.graphics.getFont(), 'm')
|
||||||
end
|
end
|
||||||
|
|
||||||
function App.filedropped(file)
|
function App.filedropped(file)
|
||||||
-- first make sure to save edits on any existing file
|
-- first make sure to save edits on any existing file
|
||||||
if Next_save then
|
if Editor_state.next_save then
|
||||||
save_to_disk(Lines, Filename)
|
save_to_disk(Editor_state.lines, Editor_state.filename)
|
||||||
end
|
end
|
||||||
-- clear the slate for the new file
|
-- clear the slate for the new file
|
||||||
App.initialize_globals() -- in particular, forget all undo history
|
App.initialize_globals() -- in particular, forget all undo history
|
||||||
Filename = file:getFilename()
|
Editor_state.filename = file:getFilename()
|
||||||
file:open('r')
|
file:open('r')
|
||||||
Lines = load_from_file(file)
|
Editor_state.lines = load_from_file(file)
|
||||||
file:close()
|
file:close()
|
||||||
for i,line in ipairs(Lines) do
|
for i,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
love.window.setTitle('Text with Lines - '..Filename)
|
love.window.setTitle('Text with Editor_state.lines - '..Editor_state.filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
function App.draw()
|
function App.draw()
|
||||||
|
@ -166,16 +166,16 @@ function love.quit()
|
||||||
edit.quit()
|
edit.quit()
|
||||||
-- save some important settings
|
-- save some important settings
|
||||||
local x,y,displayindex = love.window.getPosition()
|
local x,y,displayindex = love.window.getPosition()
|
||||||
local filename = Filename
|
local filename = Editor_state.filename
|
||||||
if filename:sub(1,1) ~= '/' then
|
if filename:sub(1,1) ~= '/' then
|
||||||
filename = love.filesystem.getWorkingDirectory()..'/'..filename -- '/' should work even on Windows
|
filename = love.filesystem.getWorkingDirectory()..'/'..filename -- '/' should work even on Windows
|
||||||
end
|
end
|
||||||
local settings = {
|
local settings = {
|
||||||
x=x, y=y, displayindex=displayindex,
|
x=x, y=y, displayindex=displayindex,
|
||||||
width=App.screen.width, height=App.screen.height,
|
width=App.screen.width, height=App.screen.height,
|
||||||
font_height=Font_height,
|
font_height=Editor_state.font_height,
|
||||||
filename=filename,
|
filename=filename,
|
||||||
screen_top=Screen_top1, cursor=Cursor1}
|
screen_top=Editor_state.screen_top1, cursor=Editor_state.cursor1}
|
||||||
love.filesystem.write('config', json.encode(settings))
|
love.filesystem.write('config', json.encode(settings))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
function test_resize_window()
|
function test_resize_window()
|
||||||
io.write('\ntest_resize_window')
|
io.write('\ntest_resize_window')
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
App.screen.init{width=Margin_left+300, height=300}
|
App.screen.init{width=Editor_state.margin_left+300, height=300}
|
||||||
check_eq(App.screen.width, Margin_left+300, 'F - test_resize_window/baseline/width')
|
check_eq(App.screen.width, Editor_state.margin_left+300, 'F - test_resize_window/baseline/width')
|
||||||
check_eq(App.screen.height, 300, 'F - test_resize_window/baseline/height')
|
check_eq(App.screen.height, 300, 'F - test_resize_window/baseline/height')
|
||||||
App.resize(200, 400)
|
App.resize(200, 400)
|
||||||
check_eq(App.screen.width, 200, 'F - test_resize_window/width')
|
check_eq(App.screen.width, 200, 'F - test_resize_window/width')
|
||||||
|
@ -12,7 +12,7 @@ end
|
||||||
|
|
||||||
function test_drop_file()
|
function test_drop_file()
|
||||||
io.write('\ntest_drop_file')
|
io.write('\ntest_drop_file')
|
||||||
App.screen.init{width=Margin_left+300, height=300}
|
App.screen.init{width=Editor_state.margin_left+300, height=300}
|
||||||
App.filesystem['foo'] = 'abc\ndef\nghi\n'
|
App.filesystem['foo'] = 'abc\ndef\nghi\n'
|
||||||
local fake_dropped_file = {
|
local fake_dropped_file = {
|
||||||
opened = false,
|
opened = false,
|
||||||
|
@ -31,18 +31,18 @@ function test_drop_file()
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
App.filedropped(fake_dropped_file)
|
App.filedropped(fake_dropped_file)
|
||||||
check_eq(#Lines, 3, 'F - test_drop_file/#lines')
|
check_eq(#Editor_state.lines, 3, 'F - test_drop_file/#lines')
|
||||||
check_eq(Lines[1].data, 'abc', 'F - test_drop_file/lines:1')
|
check_eq(Editor_state.lines[1].data, 'abc', 'F - test_drop_file/lines:1')
|
||||||
check_eq(Lines[2].data, 'def', 'F - test_drop_file/lines:2')
|
check_eq(Editor_state.lines[2].data, 'def', 'F - test_drop_file/lines:2')
|
||||||
check_eq(Lines[3].data, 'ghi', 'F - test_drop_file/lines:3')
|
check_eq(Editor_state.lines[3].data, 'ghi', 'F - test_drop_file/lines:3')
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_drop_file_saves_previous()
|
function test_drop_file_saves_previous()
|
||||||
io.write('\ntest_drop_file_saves_previous')
|
io.write('\ntest_drop_file_saves_previous')
|
||||||
App.screen.init{width=Margin_left+300, height=300}
|
App.screen.init{width=Editor_state.margin_left+300, height=300}
|
||||||
-- initially editing a file called foo that hasn't been saved to filesystem yet
|
-- initially editing a file called foo that hasn't been saved to filesystem yet
|
||||||
Lines = load_array{'abc', 'def'}
|
Editor_state.lines = load_array{'abc', 'def'}
|
||||||
Filename = 'foo'
|
Editor_state.filename = 'foo'
|
||||||
schedule_save()
|
schedule_save()
|
||||||
-- now drag a new file bar from the filesystem
|
-- now drag a new file bar from the filesystem
|
||||||
App.filesystem['bar'] = 'abc\ndef\nghi\n'
|
App.filesystem['bar'] = 'abc\ndef\nghi\n'
|
||||||
|
|
82
search.lua
82
search.lua
|
@ -1,7 +1,7 @@
|
||||||
-- helpers for the search bar (C-f)
|
-- helpers for the search bar (C-f)
|
||||||
|
|
||||||
function Text.draw_search_bar()
|
function Text.draw_search_bar()
|
||||||
local h = Line_height+2
|
local h = Editor_state.line_height+2
|
||||||
local y = App.screen.height-h
|
local y = App.screen.height-h
|
||||||
love.graphics.setColor(0.9,0.9,0.9)
|
love.graphics.setColor(0.9,0.9,0.9)
|
||||||
love.graphics.rectangle('fill', 0, y-10, App.screen.width-1, h+8)
|
love.graphics.rectangle('fill', 0, y-10, App.screen.width-1, h+8)
|
||||||
|
@ -12,92 +12,92 @@ function Text.draw_search_bar()
|
||||||
love.graphics.setColor(0.6,0.6,0.6)
|
love.graphics.setColor(0.6,0.6,0.6)
|
||||||
love.graphics.rectangle('line', 20, y-6, App.screen.width-40, h+2, 2,2)
|
love.graphics.rectangle('line', 20, y-6, App.screen.width-40, h+2, 2,2)
|
||||||
App.color(Text_color)
|
App.color(Text_color)
|
||||||
App.screen.print(Search_term, 25,y-5)
|
App.screen.print(Editor_state.search_term, 25,y-5)
|
||||||
App.color(Cursor_color)
|
App.color(Cursor_color)
|
||||||
if Search_text == nil then
|
if Editor_state.search_text == nil then
|
||||||
Search_text = App.newText(love.graphics.getFont(), Search_term)
|
Editor_state.search_text = App.newText(love.graphics.getFont(), Editor_state.search_term)
|
||||||
end
|
end
|
||||||
love.graphics.circle('fill', 25+App.width(Search_text),y-5+h, 2)
|
love.graphics.circle('fill', 25+App.width(Editor_state.search_text),y-5+h, 2)
|
||||||
App.color(Text_color)
|
App.color(Text_color)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.search_next()
|
function Text.search_next()
|
||||||
-- search current line
|
-- search current line
|
||||||
local pos = Lines[Cursor1.line].data:find(Search_term, Cursor1.pos)
|
local pos = Editor_state.lines[Editor_state.cursor1.line].data:find(Editor_state.search_term, Editor_state.cursor1.pos)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
for i=Cursor1.line+1,#Lines do
|
for i=Editor_state.cursor1.line+1,#Editor_state.lines do
|
||||||
pos = Lines[i].data:find(Search_term)
|
pos = Editor_state.lines[i].data:find(Editor_state.search_term)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
-- wrap around
|
-- wrap around
|
||||||
for i=1,Cursor1.line-1 do
|
for i=1,Editor_state.cursor1.line-1 do
|
||||||
pos = Lines[i].data:find(Search_term)
|
pos = Editor_state.lines[i].data:find(Editor_state.search_term)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
Cursor1.line = Search_backup.cursor.line
|
Editor_state.cursor1.line = Editor_state.search_backup.cursor.line
|
||||||
Cursor1.pos = Search_backup.cursor.pos
|
Editor_state.cursor1.pos = Editor_state.search_backup.cursor.pos
|
||||||
Screen_top1.line = Search_backup.screen_top.line
|
Editor_state.screen_top1.line = Editor_state.search_backup.screen_top.line
|
||||||
Screen_top1.pos = Search_backup.screen_top.pos
|
Editor_state.screen_top1.pos = Editor_state.search_backup.screen_top.pos
|
||||||
end
|
end
|
||||||
if Text.lt1(Cursor1, Screen_top1) or Text.lt1(Screen_bottom1, Cursor1) then
|
if Text.lt1(Editor_state.cursor1, Editor_state.screen_top1) or Text.lt1(Editor_state.screen_bottom1, Editor_state.cursor1) then
|
||||||
Screen_top1.line = Cursor1.line
|
Editor_state.screen_top1.line = Editor_state.cursor1.line
|
||||||
local _, pos = Text.pos_at_start_of_cursor_screen_line(Margin_left, App.screen.width-Margin_right)
|
local _, pos = Text.pos_at_start_of_cursor_screen_line(Editor_state.margin_left, App.screen.width-Editor_state.margin_right)
|
||||||
Screen_top1.pos = pos
|
Editor_state.screen_top1.pos = pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.search_previous()
|
function Text.search_previous()
|
||||||
-- search current line
|
-- search current line
|
||||||
local pos = rfind(Lines[Cursor1.line].data, Search_term, Cursor1.pos)
|
local pos = rfind(Editor_state.lines[Editor_state.cursor1.line].data, Editor_state.search_term, Editor_state.cursor1.pos)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
for i=Cursor1.line-1,1,-1 do
|
for i=Editor_state.cursor1.line-1,1,-1 do
|
||||||
pos = rfind(Lines[i].data, Search_term)
|
pos = rfind(Editor_state.lines[i].data, Editor_state.search_term)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
-- wrap around
|
-- wrap around
|
||||||
for i=#Lines,Cursor1.line+1,-1 do
|
for i=#Editor_state.lines,Editor_state.cursor1.line+1,-1 do
|
||||||
pos = rfind(Lines[i].data, Search_term)
|
pos = rfind(Editor_state.lines[i].data, Editor_state.search_term)
|
||||||
if pos then
|
if pos then
|
||||||
Cursor1.line = i
|
Editor_state.cursor1.line = i
|
||||||
Cursor1.pos = pos
|
Editor_state.cursor1.pos = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
Cursor1.line = Search_backup.cursor.line
|
Editor_state.cursor1.line = Editor_state.search_backup.cursor.line
|
||||||
Cursor1.pos = Search_backup.cursor.pos
|
Editor_state.cursor1.pos = Editor_state.search_backup.cursor.pos
|
||||||
Screen_top1.line = Search_backup.screen_top.line
|
Editor_state.screen_top1.line = Editor_state.search_backup.screen_top.line
|
||||||
Screen_top1.pos = Search_backup.screen_top.pos
|
Editor_state.screen_top1.pos = Editor_state.search_backup.screen_top.pos
|
||||||
end
|
end
|
||||||
if Text.lt1(Cursor1, Screen_top1) or Text.lt1(Screen_bottom1, Cursor1) then
|
if Text.lt1(Editor_state.cursor1, Editor_state.screen_top1) or Text.lt1(Editor_state.screen_bottom1, Editor_state.cursor1) then
|
||||||
Screen_top1.line = Cursor1.line
|
Editor_state.screen_top1.line = Editor_state.cursor1.line
|
||||||
local _, pos = Text.pos_at_start_of_cursor_screen_line(Margin_left, App.screen.width-Margin_right)
|
local _, pos = Text.pos_at_start_of_cursor_screen_line(Editor_state.margin_left, App.screen.width-Editor_state.margin_right)
|
||||||
Screen_top1.pos = pos
|
Editor_state.screen_top1.pos = pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
94
select.lua
94
select.lua
|
@ -1,20 +1,20 @@
|
||||||
-- helpers for selecting portions of text
|
-- helpers for selecting portions of text
|
||||||
|
|
||||||
-- Return any intersection of the region from Selection1 to Cursor1 (or
|
-- Return any intersection of the region from Editor_state.selection1 to Editor_state.cursor1 (or
|
||||||
-- current mouse, if mouse is pressed; or recent mouse if mouse is pressed and
|
-- current mouse, if mouse is pressed; or recent mouse if mouse is pressed and
|
||||||
-- currently over a drawing) with the region between {line=line_index, pos=apos}
|
-- currently over a drawing) with the region between {line=line_index, pos=apos}
|
||||||
-- and {line=line_index, pos=bpos}.
|
-- and {line=line_index, pos=bpos}.
|
||||||
-- apos must be less than bpos. However Selection1 and Cursor1 can be in any order.
|
-- apos must be less than bpos. However Editor_state.selection1 and Editor_state.cursor1 can be in any order.
|
||||||
-- Result: positions spos,epos between apos,bpos.
|
-- Result: positions spos,epos between apos,bpos.
|
||||||
function Text.clip_selection(line_index, apos, bpos, left, right)
|
function Text.clip_selection(line_index, apos, bpos, left, right)
|
||||||
if Selection1.line == nil then return nil,nil end
|
if Editor_state.selection1.line == nil then return nil,nil end
|
||||||
-- min,max = sorted(Selection1,Cursor1)
|
-- min,max = sorted(Editor_state.selection1,Editor_state.cursor1)
|
||||||
local minl,minp = Selection1.line,Selection1.pos
|
local minl,minp = Editor_state.selection1.line,Editor_state.selection1.pos
|
||||||
local maxl,maxp
|
local maxl,maxp
|
||||||
if App.mouse_down(1) then
|
if App.mouse_down(1) then
|
||||||
maxl,maxp = Text.mouse_pos(left, right)
|
maxl,maxp = Text.mouse_pos(left, right)
|
||||||
else
|
else
|
||||||
maxl,maxp = Cursor1.line,Cursor1.pos
|
maxl,maxp = Editor_state.cursor1.line,Editor_state.cursor1.pos
|
||||||
end
|
end
|
||||||
if minl > maxl then
|
if minl > maxl then
|
||||||
minl,maxl = maxl,minl
|
minl,maxl = maxl,minl
|
||||||
|
@ -69,7 +69,7 @@ function Text.draw_highlight(line, x,y, pos, lo,hi)
|
||||||
local text = App.newText(love.graphics.getFont(), s)
|
local text = App.newText(love.graphics.getFont(), s)
|
||||||
local text_width = App.width(text)
|
local text_width = App.width(text)
|
||||||
App.color(Highlight_color)
|
App.color(Highlight_color)
|
||||||
love.graphics.rectangle('fill', x+lo_px,y, text_width,Line_height)
|
love.graphics.rectangle('fill', x+lo_px,y, text_width,Editor_state.line_height)
|
||||||
App.color(Text_color)
|
App.color(Text_color)
|
||||||
return lo_px
|
return lo_px
|
||||||
end
|
end
|
||||||
|
@ -78,20 +78,20 @@ end
|
||||||
-- inefficient for some reason, so don't do it on every frame
|
-- inefficient for some reason, so don't do it on every frame
|
||||||
function Text.mouse_pos(left, right)
|
function Text.mouse_pos(left, right)
|
||||||
local time = love.timer.getTime()
|
local time = love.timer.getTime()
|
||||||
if Recent_mouse.time and Recent_mouse.time > time-0.1 then
|
if Editor_state.recent_mouse.time and Editor_state.recent_mouse.time > time-0.1 then
|
||||||
return Recent_mouse.line, Recent_mouse.pos
|
return Editor_state.recent_mouse.line, Editor_state.recent_mouse.pos
|
||||||
end
|
end
|
||||||
Recent_mouse.time = time
|
Editor_state.recent_mouse.time = time
|
||||||
local line,pos = Text.to_pos(App.mouse_x(), App.mouse_y(), left, right)
|
local line,pos = Text.to_pos(App.mouse_x(), App.mouse_y(), left, right)
|
||||||
if line then
|
if line then
|
||||||
Recent_mouse.line = line
|
Editor_state.recent_mouse.line = line
|
||||||
Recent_mouse.pos = pos
|
Editor_state.recent_mouse.pos = pos
|
||||||
end
|
end
|
||||||
return Recent_mouse.line, Recent_mouse.pos
|
return Editor_state.recent_mouse.line, Editor_state.recent_mouse.pos
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.to_pos(x,y, left, right)
|
function Text.to_pos(x,y, left, right)
|
||||||
for line_index,line in ipairs(Lines) do
|
for line_index,line in ipairs(Editor_state.lines) do
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
if Text.in_line(line, x,y, left, right) then
|
if Text.in_line(line, x,y, left, right) then
|
||||||
return line_index, Text.to_pos_on_line(line, x,y, left, right)
|
return line_index, Text.to_pos_on_line(line, x,y, left, right)
|
||||||
|
@ -101,25 +101,25 @@ function Text.to_pos(x,y, left, right)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.cut_selection(left, right)
|
function Text.cut_selection(left, right)
|
||||||
if Selection1.line == nil then return end
|
if Editor_state.selection1.line == nil then return end
|
||||||
local result = Text.selection()
|
local result = Text.selection()
|
||||||
Text.delete_selection(left, right)
|
Text.delete_selection(left, right)
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.delete_selection(left, right)
|
function Text.delete_selection(left, right)
|
||||||
if Selection1.line == nil then return end
|
if Editor_state.selection1.line == nil then return end
|
||||||
local minl,maxl = minmax(Selection1.line, Cursor1.line)
|
local minl,maxl = minmax(Editor_state.selection1.line, Editor_state.cursor1.line)
|
||||||
local before = snapshot(minl, maxl)
|
local before = snapshot(minl, maxl)
|
||||||
Text.delete_selection_without_undo(left, right)
|
Text.delete_selection_without_undo(left, right)
|
||||||
record_undo_event({before=before, after=snapshot(Cursor1.line)})
|
record_undo_event({before=before, after=snapshot(Editor_state.cursor1.line)})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.delete_selection_without_undo(left, right)
|
function Text.delete_selection_without_undo(left, right)
|
||||||
if Selection1.line == nil then return end
|
if Editor_state.selection1.line == nil then return end
|
||||||
-- min,max = sorted(Selection1,Cursor1)
|
-- min,max = sorted(Editor_state.selection1,Editor_state.cursor1)
|
||||||
local minl,minp = Selection1.line,Selection1.pos
|
local minl,minp = Editor_state.selection1.line,Editor_state.selection1.pos
|
||||||
local maxl,maxp = Cursor1.line,Cursor1.pos
|
local maxl,maxp = Editor_state.cursor1.line,Editor_state.cursor1.pos
|
||||||
if minl > maxl then
|
if minl > maxl then
|
||||||
minl,maxl = maxl,minl
|
minl,maxl = maxl,minl
|
||||||
minp,maxp = maxp,minp
|
minp,maxp = maxp,minp
|
||||||
|
@ -128,36 +128,36 @@ function Text.delete_selection_without_undo(left, right)
|
||||||
minp,maxp = maxp,minp
|
minp,maxp = maxp,minp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- update Cursor1 and Selection1
|
-- update Editor_state.cursor1 and Editor_state.selection1
|
||||||
Cursor1.line = minl
|
Editor_state.cursor1.line = minl
|
||||||
Cursor1.pos = minp
|
Editor_state.cursor1.pos = minp
|
||||||
if Text.lt1(Cursor1, Screen_top1) then
|
if Text.lt1(Editor_state.cursor1, Editor_state.screen_top1) then
|
||||||
Screen_top1.line = Cursor1.line
|
Editor_state.screen_top1.line = Editor_state.cursor1.line
|
||||||
_,Screen_top1.pos = Text.pos_at_start_of_cursor_screen_line(left, right)
|
_,Editor_state.screen_top1.pos = Text.pos_at_start_of_cursor_screen_line(left, right)
|
||||||
end
|
end
|
||||||
Selection1 = {}
|
Editor_state.selection1 = {}
|
||||||
-- delete everything between min (inclusive) and max (exclusive)
|
-- delete everything between min (inclusive) and max (exclusive)
|
||||||
Text.clear_cache(Lines[minl])
|
Text.clear_cache(Editor_state.lines[minl])
|
||||||
local min_offset = Text.offset(Lines[minl].data, minp)
|
local min_offset = Text.offset(Editor_state.lines[minl].data, minp)
|
||||||
local max_offset = Text.offset(Lines[maxl].data, maxp)
|
local max_offset = Text.offset(Editor_state.lines[maxl].data, maxp)
|
||||||
if minl == maxl then
|
if minl == maxl then
|
||||||
--? print('minl == maxl')
|
--? print('minl == maxl')
|
||||||
Lines[minl].data = Lines[minl].data:sub(1, min_offset-1)..Lines[minl].data:sub(max_offset)
|
Editor_state.lines[minl].data = Editor_state.lines[minl].data:sub(1, min_offset-1)..Editor_state.lines[minl].data:sub(max_offset)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
assert(minl < maxl)
|
assert(minl < maxl)
|
||||||
local rhs = Lines[maxl].data:sub(max_offset)
|
local rhs = Editor_state.lines[maxl].data:sub(max_offset)
|
||||||
for i=maxl,minl+1,-1 do
|
for i=maxl,minl+1,-1 do
|
||||||
table.remove(Lines, i)
|
table.remove(Editor_state.lines, i)
|
||||||
end
|
end
|
||||||
Lines[minl].data = Lines[minl].data:sub(1, min_offset-1)..rhs
|
Editor_state.lines[minl].data = Editor_state.lines[minl].data:sub(1, min_offset-1)..rhs
|
||||||
end
|
end
|
||||||
|
|
||||||
function Text.selection()
|
function Text.selection()
|
||||||
if Selection1.line == nil then return end
|
if Editor_state.selection1.line == nil then return end
|
||||||
-- min,max = sorted(Selection1,Cursor1)
|
-- min,max = sorted(Editor_state.selection1,Editor_state.cursor1)
|
||||||
local minl,minp = Selection1.line,Selection1.pos
|
local minl,minp = Editor_state.selection1.line,Editor_state.selection1.pos
|
||||||
local maxl,maxp = Cursor1.line,Cursor1.pos
|
local maxl,maxp = Editor_state.cursor1.line,Editor_state.cursor1.pos
|
||||||
if minl > maxl then
|
if minl > maxl then
|
||||||
minl,maxl = maxl,minl
|
minl,maxl = maxl,minl
|
||||||
minp,maxp = maxp,minp
|
minp,maxp = maxp,minp
|
||||||
|
@ -166,18 +166,18 @@ function Text.selection()
|
||||||
minp,maxp = maxp,minp
|
minp,maxp = maxp,minp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local min_offset = Text.offset(Lines[minl].data, minp)
|
local min_offset = Text.offset(Editor_state.lines[minl].data, minp)
|
||||||
local max_offset = Text.offset(Lines[maxl].data, maxp)
|
local max_offset = Text.offset(Editor_state.lines[maxl].data, maxp)
|
||||||
if minl == maxl then
|
if minl == maxl then
|
||||||
return Lines[minl].data:sub(min_offset, max_offset-1)
|
return Editor_state.lines[minl].data:sub(min_offset, max_offset-1)
|
||||||
end
|
end
|
||||||
assert(minl < maxl)
|
assert(minl < maxl)
|
||||||
local result = {Lines[minl].data:sub(min_offset)}
|
local result = {Editor_state.lines[minl].data:sub(min_offset)}
|
||||||
for i=minl+1,maxl-1 do
|
for i=minl+1,maxl-1 do
|
||||||
if Lines[i].mode == 'text' then
|
if Editor_state.lines[i].mode == 'text' then
|
||||||
table.insert(result, Lines[i].data)
|
table.insert(result, Editor_state.lines[i].data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.insert(result, Lines[maxl].data:sub(1, max_offset-1))
|
table.insert(result, Editor_state.lines[maxl].data:sub(1, max_offset-1))
|
||||||
return table.concat(result, '\n')
|
return table.concat(result, '\n')
|
||||||
end
|
end
|
||||||
|
|
1726
text_tests.lua
1726
text_tests.lua
File diff suppressed because it is too large
Load Diff
40
undo.lua
40
undo.lua
|
@ -7,27 +7,27 @@
|
||||||
-- TODO: coalesce multiple similar operations
|
-- TODO: coalesce multiple similar operations
|
||||||
|
|
||||||
function record_undo_event(data)
|
function record_undo_event(data)
|
||||||
History[Next_history] = data
|
Editor_state.history[Editor_state.next_history] = data
|
||||||
Next_history = Next_history+1
|
Editor_state.next_history = Editor_state.next_history+1
|
||||||
for i=Next_history,#History do
|
for i=Editor_state.next_history,#Editor_state.history do
|
||||||
History[i] = nil
|
Editor_state.history[i] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function undo_event()
|
function undo_event()
|
||||||
if Next_history > 1 then
|
if Editor_state.next_history > 1 then
|
||||||
--? print('moving to history', Next_history-1)
|
--? print('moving to history', Editor_state.next_history-1)
|
||||||
Next_history = Next_history-1
|
Editor_state.next_history = Editor_state.next_history-1
|
||||||
local result = History[Next_history]
|
local result = Editor_state.history[Editor_state.next_history]
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function redo_event()
|
function redo_event()
|
||||||
if Next_history <= #History then
|
if Editor_state.next_history <= #Editor_state.history then
|
||||||
--? print('restoring history', Next_history+1)
|
--? print('restoring history', Editor_state.next_history+1)
|
||||||
local result = History[Next_history]
|
local result = Editor_state.history[Editor_state.next_history]
|
||||||
Next_history = Next_history+1
|
Editor_state.next_history = Editor_state.next_history+1
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -40,18 +40,18 @@ function snapshot(s,e)
|
||||||
if e == nil then
|
if e == nil then
|
||||||
e = s
|
e = s
|
||||||
end
|
end
|
||||||
assert(#Lines > 0)
|
assert(#Editor_state.lines > 0)
|
||||||
if s < 1 then s = 1 end
|
if s < 1 then s = 1 end
|
||||||
if s > #Lines then s = #Lines end
|
if s > #Editor_state.lines then s = #Editor_state.lines end
|
||||||
if e < 1 then e = 1 end
|
if e < 1 then e = 1 end
|
||||||
if e > #Lines then e = #Lines end
|
if e > #Editor_state.lines then e = #Editor_state.lines end
|
||||||
-- compare with App.initialize_globals
|
-- compare with App.initialize_globals
|
||||||
local event = {
|
local event = {
|
||||||
screen_top=deepcopy(Screen_top1),
|
screen_top=deepcopy(Editor_state.screen_top1),
|
||||||
selection=deepcopy(Selection1),
|
selection=deepcopy(Editor_state.selection1),
|
||||||
cursor=deepcopy(Cursor1),
|
cursor=deepcopy(Editor_state.cursor1),
|
||||||
current_drawing_mode=Drawing_mode,
|
current_drawing_mode=Drawing_mode,
|
||||||
previous_drawing_mode=Previous_drawing_mode,
|
previous_drawing_mode=Editor_state.previous_drawing_mode,
|
||||||
lines={},
|
lines={},
|
||||||
start_line=s,
|
start_line=s,
|
||||||
end_line=e,
|
end_line=e,
|
||||||
|
@ -59,7 +59,7 @@ function snapshot(s,e)
|
||||||
}
|
}
|
||||||
-- deep copy lines without cached stuff like text fragments
|
-- deep copy lines without cached stuff like text fragments
|
||||||
for i=s,e do
|
for i=s,e do
|
||||||
local line = Lines[i]
|
local line = Editor_state.lines[i]
|
||||||
if line.mode == 'text' then
|
if line.mode == 'text' then
|
||||||
table.insert(event.lines, {mode='text', data=line.data})
|
table.insert(event.lines, {mode='text', data=line.data})
|
||||||
elseif line.mode == 'drawing' then
|
elseif line.mode == 'drawing' then
|
||||||
|
|
Loading…
Reference in New Issue
Block a user