about summary refs log tree commit diff stats
path: root/main.lua
blob: c2e6aa634a07f50cad34e4dc83de2144353e07c4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
require 'keychord'
require 'button'
local utf8 = require 'utf8'

lines = {}
width, height, flags = 0, 0, nil
exec_payload = nil

function love.load()
  table.insert(lines, '')
  love.window.setMode(0, 0)  -- maximize
  width, height, flags = love.window.getMode()
  love.keyboard.setTextInput(true)  -- bring up keyboard on touch screen
end

function love.draw()
  button_handlers = {}
  love.graphics.setColor(1, 1, 1)
  love.graphics.rectangle('fill', 1, 1, width-1, height-1)
  love.graphics.setColor(0, 0, 0)
  local text
  local y = 0
  for i, line in ipairs(lines) do
    y = y+25
    text = love.graphics.newText(love.graphics.getFont(), line)
    if line == '' then
      button('draw', {x=4,y=y+4, w=12,h=12, color={1,1,0},
        icon = function(x, y)
                 love.graphics.setColor(0.7,0.7,0.7)
                 love.graphics.rectangle('line', x,y, 12,12)
                 love.graphics.line(4,y+6, 16,y+6)
                 love.graphics.line(10,y, 10,y+12)
                 love.graphics.setColor(0, 0, 0)
               end,
        onpress1 = function()
                     table.insert(lines, i, {y=y, w=400, h=200, pending={}, shapes={}})
                   end})
    elseif type(line) == 'table' then
      -- line drawing
      love.graphics.setColor(0.75,0.75,0.75)
      line.y = y
      love.graphics.rectangle('line', 12,y, line.w,line.h)
      y = y+line.h

      love.graphics.setColor(0,0,0)
      for _,shape in ipairs(line.shapes) do
        prev = nil
        for _,point in ipairs(shape) do
          if prev then
            love.graphics.line(prev.x,prev.y, point.x,point.y)
          end
          prev = point
        end
      end
      prev = nil
      for _,point in ipairs(line.pending) do
        if prev then
          love.graphics.line(prev.x,prev.y, point.x,point.y)
        end
        prev = point
      end
    else
      love.graphics.draw(text, 25,y, 0, 1.5)
    end
  end
  -- cursor
  love.graphics.print('_', 25+text:getWidth()*1.5, y)

  if exec_payload then
    call_gather(exec_payload)
  end
end

function love.update(dt)
  if love.mouse.isDown('1') then
    for i, line in ipairs(lines) do
      if type(line) == 'table' then
        local x, y = love.mouse.getX(), love.mouse.getY()
        if y >= line.y and y < line.y + line.h and x >= 12 and x < 12+line.w then
          lines.current = line
          process_drag(line,love.mouse.getX(),love.mouse.getY())
        end
      end
    end
  end
end

function process_drag(drawing, x,y)
  table.insert(drawing.pending, {x=x, y=y})
end

function love.mousereleased(x,y, button)
  if lines.current then
    if lines.current.pending then
      table.insert(lines.current.shapes, lines.current.pending)
      lines.current.pending = {}
      lines.current = nil
    end
  end
end

function love.textinput(t)
  lines[#lines] = lines[#lines]..t
end

function keychord_pressed(chord)
  -- Don't handle any keys here that would trigger love.textinput above.
  if chord == 'return' then
    table.insert(lines, '')
  elseif chord == 'backspace' then
    if #lines > 1 and lines[#lines] == '' then
      table.remove(lines)
    else
      local byteoffset = utf8.offset(lines[#lines], -1)
      if byteoffset then
        lines[#lines] = string.sub(lines[#lines], 1, byteoffset-1)
      end
    end
  elseif chord == 'C-r' then
    eval(lines[#lines])
--?     lines[#lines+1] = eval(lines[#lines])[1]
--?     lines[#lines+1] = ''
  end
end

function love.keyreleased(key, scancode)
end

function love.mousepressed(x, y, button)
  propagate_to_button_handers(x, y, button)
end

function eval(buf)
  local f = load('return '..buf, 'REPL')
  if f then
    exec_payload = f
    return
--?     return call_gather(f)
  end
  local f, err = load(buf, 'REPL')
  if f then
    exec_payload = f
    return
--?     return call_gather(f)
  else
    return {err}
  end
end

-- based on https://github.com/hoelzro/lua-repl
function call_gather(f)
  local success, results = gather_results(xpcall(f, function(...) return debug.traceback() end))
  return results
end

function gather_results(success, ...)
  local n = select('#', ...)
  return success, { n = n, ... }
end