Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Buffer
- Buffer = class()
- function Buffer:init()
- self.buffer = {}
- self.font = "Inconsolata"
- self.fontSize = 20
- -- x = line, y = pos
- self.cursor = vec2(1,1)
- self.t = 0
- self.cursorBlink = 0
- end
- function Buffer:setStyle()
- textMode(CORNER)
- font( self.font )
- fill(255)
- fontSize( self.fontSize )
- textWrapWidth(10000)
- end
- function Buffer:cursorToScreen(c)
- -- Get a subset of the buffer
- local lines = table_slice( self.buffer, 1, c.x )
- local l = self.buffer[c.x]
- local upToStr = self:bufferToString(lines)
- local lstr = nil
- if l then
- lstr = table.concat(l)
- end
- pushStyle()
- self:setStyle()
- local lw = 0
- local _,lh = textSize("A")
- local emptyLine = true
- if lstr and lstr ~= "" then
- lw,lh = textSize(string.sub(lstr,1,c.y - 1))
- emptyLine = false
- end
- local pw,ph = textSize(upToStr)
- if emptyLine then
- ph = ph + lh
- end
- popStyle()
- return lw,(ph - lh/2)
- end
- function Buffer:bufferToString(b)
- local bstrings = {}
- for k,v in pairs(b) do
- table.insert(bstrings, table.concat( b[k] ) )
- end
- return table.concat( bstrings, "\n" )
- end
- function Buffer:moveCursor(o)
- self.cursor = self.cursor + o
- self.cursor.x = math.max(1, math.min(self.cursor.x, #self.buffer))
- local l = self.buffer[self.cursor.x]
- local y = self.cursor.y
- y = math.max(1, math.min(y, #l + 1))
- self.cursor.y = y
- end
- function Buffer:insertCharacter(c)
- local l = self.buffer[self.cursor.x]
- if l == nil then
- l = {}
- self.buffer[self.cursor.x] = l
- end
- if c == "\n" then
- local start = table_slice(l,1,self.cursor.y)
- local tail = table_slice(l,self.cursor.y+1,#l)
- table[self.cursor.x] = start
- table.insert(self.buffer, self.cursor.x+1, tail)
- self.cursor = vec2( self.cursor.x + 1, 1 )
- elseif c == BACKSPACE then
- if self.cursor.y == 1 then
- -- delete line
- local prevLine = self.buffer[self.cursor.x - 1]
- table.remove(self.buffer, self.cursor.x)
- if prevLine then
- self.cursor = vec2(self.cursor.x - 1, #prevLine + 1)
- table_append( prevLine, l )
- end
- else
- -- delete character
- table.remove(l, self.cursor.y - 1 )
- self.cursor = vec2(self.cursor.x, self.cursor.y - 1 )
- end
- else
- table.insert(l, self.cursor.y, c)
- self.cursor = vec2( self.cursor.x, self.cursor.y + 1 )
- end
- end
- function Buffer:draw()
- self.t = self.t + 8 * DeltaTime
- self.cursorBlink = (math.sin(self.t) + 1) * 128
- pushStyle()
- self:setStyle()
- local str = self:toString()
- local w,h = textSize(str)
- pushMatrix()
- translate( 40, -40 )
- text(str, 0, HEIGHT - h)
- -- Draw cursor
- -- Cursor pos x,y
- local cpx,cpy = self:cursorToScreen(self.cursor)
- fill(0, 87, 255, self.cursorBlink)
- rectMode(CENTER)
- rect(cpx,HEIGHT - cpy,5,22)
- popMatrix()
- popStyle()
- end
- function Buffer:clear()
- self.cursor = vec2(1,1)
- self.buffer = {}
- end
- function Buffer:load(code)
- self:clear()
- local i
- for i = 1,string.len(code) do
- self:insertCharacter(string.sub(code,i,i))
- end
- end
- function Buffer:toString()
- return self:bufferToString(self.buffer)
- end
- function Buffer:toStringWithoutActiveLine()
- local bstrings = {}
- for k,v in pairs(self.buffer) do
- if k ~= self.cursor.x then
- table.insert(bstrings, table.concat( self.buffer[k] ) )
- end
- end
- return table.concat( bstrings, "\n" )
- end
- --# Embutton
- -- Emoji Button
- EmButton = class()
- function EmButton:init(pos,txt)
- -- you can accept and set parameters here
- self.pos = pos
- self.text = txt
- self.action = nil
- self.highlight = false
- self.color = color(255,255,255,255)
- end
- function EmButton:size()
- pushStyle()
- self:setStyle()
- local w,h = textSize(self.text)
- popStyle()
- return w,h
- end
- function EmButton:hitTest(lp)
- local w,h = self:size()
- local left,right = self.pos.x - w/2, self.pos.x + w/2
- local top,bottom = self.pos.y + h/2, self.pos.y - h/2
- if lp.x > left and lp.x < right and
- lp.y > bottom and lp.y < top then
- return true
- end
- return false
- end
- function EmButton:setStyle()
- fill(self.color)
- noStroke()
- textMode(CENTER)
- fontSize(50)
- font("AppleColorEmoji")
- end
- function EmButton:draw()
- pushMatrix()
- translate(self.pos.x,self.pos.y)
- pushStyle()
- self:setStyle()
- text(self.text,0,0)
- popStyle()
- popMatrix()
- end
- function EmButton:touched(touch)
- if touch.state == ENDED then
- -- Tapped
- if self:hitTest( vec2(touch.x,touch.y) ) then
- if self.action then self.action() end
- end
- end
- end
- --# Main
- supportedOrientations(PORTRAIT)
- function keyHeight()
- if CurrentOrientation == LANDSCAPE_LEFT or
- CurrentOrientation == LANDSCAPE_RIGHT then
- return 350
- else
- return 260
- end
- end
- function layoutAndDrawKeys()
- local start = WIDTH
- local keySz = 30
- local height = keyHeight()
- for i = #keys,1,-1 do
- local k = keys[i]
- k.pos = vec2( start - keySz, height + keySz )
- start = start - 2*keySz
- k:draw()
- end
- trash.pos = vec2(WIDTH - keySz - 10, HEIGHT - keySz - 20)
- trash:draw()
- end
- function setup()
- showKeyboard()
- displayMode(FULLSCREEN_NO_BUTTONS)
- buffer = Buffer()
- s = Samples()
- local closeKey = EmButton(vec2(0,0), "◀")
- closeKey.color = color(255,100,50,255)
- closeKey.action = function() close() end
- local startKey = EmButton(vec2(0,0), "⏪")
- startKey.action = function() buffer:moveCursor(vec2(0,-1000)) end
- local endKey = EmButton(vec2(0,0), "⏩")
- endKey.action = function() buffer:moveCursor(vec2(0,1000)) end
- local leftKey = EmButton(vec2(0,0), "⬅")
- leftKey.action = function() buffer:moveCursor(vec2(0,-1)) end
- local rightKey = EmButton(vec2(0,0), "➡")
- rightKey.action = function() buffer:moveCursor(vec2(0,1)) end
- local upKey = EmButton(vec2(0,0), "⬆")
- upKey.action = function() buffer:moveCursor(vec2(-1,0)) end
- local downKey = EmButton(vec2(0,0), "⬇")
- downKey.action = function() buffer:moveCursor(vec2(1,0)) end
- local keyKey = EmButton(vec2(0,0), "📝")
- keyKey.action = function() showKeyboard() end
- local prevKey = EmButton(vec2(0,0), "◀")
- prevKey.color = color(50,255,100,255)
- prevKey.action = function() buffer:load(s:prev()) end
- local nextKey = EmButton(vec2(0,0), "▶")
- nextKey.color = color(50,255,100,255)
- nextKey.action = function() buffer:load(s:next()) end
- keys = {closeKey,startKey,leftKey,
- rightKey,endKey,upKey,
- downKey,keyKey,prevKey,nextKey}
- trash = EmButton(vec2(0,0), "❌")
- trash.action = function() buffer:clear() end
- end
- function keyboard(key)
- buffer:insertCharacter(key)
- end
- function touched(touch)
- for k,v in pairs(keys) do
- v:touched(touch)
- end
- trash:touched(touch)
- end
- -- This function gets called once every frame
- function draw()
- -- This sets a dark background color
- background(40, 40, 50)
- resetStyle()
- local str = buffer:toString()
- local chunk = loadstring(str)
- if chunk then
- chunk()
- else
- str = buffer:toStringWithoutActiveLine()
- chunk = loadstring(str)
- if chunk then chunk() end
- end
- resetStyle()
- fill(0,0,0,50)
- rectMode(CORNER)
- rect(0,0,WIDTH,HEIGHT)
- -- Do your drawing here
- buffer:draw()
- layoutAndDrawKeys()
- end
- --# Samples
- Samples = class()
- function Samples:init()
- self.ex = {}
- self.i = 0
- local nl = "\n"
- self.ex[1] = "text(\"Hello World\",300,500)"
- self.ex[2] = "fill(255,0,0)" .. nl
- self.ex[2] = self.ex[2] .. "ellipse(300,500,100,100)"
- self.max = 2
- end
- function Samples:next()
- if self.i ~= self.max then self.i = self.i + 1 end
- return self.ex[self.i]
- end
- function Samples:prev()
- if self.i ~= 1 then self.i = self.i - 1 end
- return self.ex[self.i]
- end
- --# Util
- function table_append (t1, t2)
- local t1s = #t1
- for k,v in pairs(t2) do t1[k + t1s] = v end
- end
- function table_slice (values,i1,i2)
- local res = {}
- local n = #values
- -- default values for range
- i1 = i1 or 1
- i2 = i2 or n
- if i2 < 0 then
- i2 = n + i2 + 1
- elseif i2 > n then
- i2 = n
- end
- if i1 < 1 or i1 > n then
- return {}
- end
- local k = 1
- for i = i1,i2 do
- res[k] = values[i]
- k = k + 1
- end
- return res
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement