Created
October 9, 2017 23:49
-
-
Save DolenzSong/c4fabb7bd7f6765e563e527bcec37655 to your computer and use it in GitHub Desktop.
Codea in Codea by Simeon, in one file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Main | |
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() | |
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 pKey = EmButton(vec2(0,0), "A") | |
pKey.action = function() | |
if displayMode() == STANDARD then | |
displayMode(FULLSCREEN_NO_BUTTONS) | |
else displayMode(STANDARD) | |
print(buffer:toString()) end | |
end | |
keys = {closeKey,startKey,leftKey, | |
rightKey,endKey,upKey, | |
downKey,keyKey,pKey} | |
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 | |
--# 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: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 | |
--# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment