Skip to content

Instantly share code, notes, and snippets.

@loopspace
Created August 28, 2013 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loopspace/6369757 to your computer and use it in GitHub Desktop.
Save loopspace/6369757 to your computer and use it in GitHub Desktop.
Beamer Release v1.0 -A prototype of a beamer display program.
Beamer Tab Order Version: 1.0
------------------------------
This file should not be included in the Codea project.
#Main
#Layout
#ImageCache
--[==[
ImageCache = class()
function ImageCache:init()
self.imagesByName = {}
self.imagesByTime = {}
self.num = 0
self.snum = 0
self.time = ElapsedTime
self.wait = 1
self.size = 0
self.imagesToSave = {}
self.imagesInUse = {}
debug:log({name = "Image Cache", message = function() return self.num end})
debug:log({name = "Images To Save", message = function() return self.snum end})
debug:log({name = "Images In Cache", message = function() return table.concat(self.imagesByTime,", ") end})
end
function ImageCache:getImage(n)
self.imagesInUse[n] = true
if self.imagesByName[n] then
local l
for k,v in ipairs(self.imagesByTime) do
if v == n then
l = k
break
end
end
table.insert(self.imagesByTime,
table.remove(self.imagesByTime,l))
return self.imagesByName[n]
end
local im = readImage(n)
if im then
self.imagesByName[n] = im
table.insert(self.imagesByTime,n)
self.num = self.num + 1
end
return im
end
function ImageCache:addImage(n,im)
self.imagesByName[n] = im
self.imagesInUse[n] = true
table.insert(self.imagesByTime,n)
self.num = self.num + 1
return im
end
function ImageCache:draw()
if ElapsedTime - self.time > self.wait then
for _,s in ipairs(self.imagesByTime) do
if self.imagesToSave[s] then
saveImage(s,self.imagesByName[s])
self.imagesToSave[s] = nil
self.snum = self.snum - 1
break
end
end
if self.num > self.size then
local r = {}
for k,s in ipairs(self.imagesByTime) do
if not self.imagesInUse[s]
and not self.imagesToSave[s] then
table.insert(r,1,k)
self.imagesByName[s] = nil
self.num = self.num - 1
if self.num == self.size then
break
end
end
end
for _,v in ipairs(r) do
table.remove(self.imagesByTime,v)
end
end
self.time = ElapsedTime
end
end
function ImageCache:setImageSaveable(n,ts)
if ts ~= nil and n ~= nil then
self.imagesToSave[n] = ts
if ts then
self.snum = self.snum + 1
end
end
end
function ImageCache:setImageInUse(n,ts)
if ts ~= nil and n ~= nil then
self.imagesInUse[n] = ts
end
end
function ImageCache:close()
for _,s in ipairs(self.imagesByTime) do
if self.imagesToSave[s] then
saveImage(s,self.imagesByName[s])
end
self.imagesByName[s] = nil
self.num = self.num - 1
end
end
return ImageCache
--]==]
--[==[
Layout = class()
local Rectangle = cimport "Rectangle"
function Layout:init(t)
self.blocks = {}
self.touchHandler = t
self.touches = t:pushHandlers()
self.touchables = {}
end
function Layout:draw()
if not self.active then
return
end
for _,v in ipairs(self.blocks) do
v:draw()
end
end
function Layout:addBlock(t)
local b = Block(t)
table.insert(self.blocks,b)
local th = self.touchHandler:registerHandler(b)
table.insert(self.touchables,1,th)
return b
end
function Layout:activate()
for k,v in ipairs(self.touchables) do
table.insert(self.touches,v)
end
self.active = true
end
function Layout:deactivate()
for k,_ in ipairs(self.touches) do
self.touches[k] = nil
end
self.active = false
end
Block = class()
function Block:init(t)
local rt = {}
rt[t.anchor] = t.position
local a
self.orientation = t.orientation or CurrentOrientation
if self.orientation == LANDSCAPE_LEFT
or self.orientation == LANDSCAPE_RIGHT then
a = 3/4
else
a = 4/3
end
local s
if t.width then
s = vec2(1,a)*t.width
elseif t.height then
s = vec2(1/a,1)*t.height
else
s = vec2(1,a)*WIDTH
end
rt.size = s
local r = Rectangle(rt)
self.rectangle = r
self:setContents(t.contents)
self.size = size
local o = USOrientation(self.orientation,vec2(0,0))
local x = USOrientation(self.orientation,vec2(1,0)) - o
local y = USOrientation(self.orientation,vec2(0,1)) - o
local w,h = RectAnchorOf(Portrait,"size")
local oo = r.ll + vec2(s.x*o.x,s.y*o.y)
local xx = vec2(s.x*x.x,s.y*x.y)/w
local yy = vec2(s.x*y.x,s.y*y.y)/h
self.matrix = matrix(
xx.x,xx.y,0,0,
yy.x,yy.y,0,0,
0,0,1,0,
oo.x,oo.y,0,1
)
self.touchTransform = function(v)
v = TransformTouch(PORTRAIT,v)
v = vec2(v.x,v.y) - oo
v = v.x * vec2(yy.y,-xx.y) + v.y * vec2(-yy.x,xx.x)
v = v / (xx.x*yy.y - xx.y*yy.x)
return v
end
end
function Block:draw()
pushMatrix()
applyMatrix(self.matrix)
local cOrientation = {CurrentOrientation,WIDTH,HEIGHT}
CurrentOrientation, WIDTH,HEIGHT = PORTRAIT, RectAnchorOf(Portrait,"size")
self.contents:draw()
CurrentOrientation, WIDTH,HEIGHT = unpack(cOrientation)
popMatrix()
end
function Block:isTouchedBy(touch)
local v = self.rectangle:anchor("south west")
if touch.x < v.x then
return false
end
if touch.y < v.y then
return false
end
v = self.rectangle:anchor("north east")
if touch.x > v.x then
return false
end
if touch.y > v.y then
return false
end
return true
end
function Block:processTouches(g)
self.action(g)
end
function Block:passTouchesTo(v)
if type(v) == "table" then
if type(v.isTouchedBy) == "function" then
local f = v.isTouchedBy
local w,h = RectAnchorOf(Portrait,"size")
self.isTouchedBy = function(s,t)
t = TransformTouch(self.touchTransform,t)
if t.x < 0 then
return false
end
if t.x > w then
return false
end
if t.y < 0 then
return false
end
if t.y > h then
return false
end
return f(v,t)
end
self.isTouchedBySave = self.isTouchedBy
local ff = v.processTouches
self.processTouches = function(s,g)
g:transformTouches(self.touchTransform)
return ff(v,g)
end
end
end
end
function Block:ignoreTouches()
self.isTouchedBy = function() return false end
end
function Block:noticeTouches()
self.isTouchedBy = self.isTouchedBySave
end
function Block:anchor(a)
return self.rectangle:anchor(a)
end
function Block:setContents(c)
if c then
self.contents = c
self:passTouchesTo(self.contents)
end
end
PDFPage = class()
function PDFPage:init(t)
self.page = mesh()
self.orientation = t.orientation or PORTRAIT
local w,h = RectAnchorOf(Portrait,"size")
self.page:addRect(w/2,h/2,w,h)
local cnrs = {
USOrientation(self.orientation,vec2(0,0)),
USOrientation(self.orientation,vec2(1,0)),
USOrientation(self.orientation,vec2(0,1)),
USOrientation(self.orientation,vec2(1,1))
}
local tc = {}
for _,v in ipairs({3,1,2,3,2,4}) do
table.insert(tc,cnrs[v])
end
self.page.texCoords = tc
self.width = t.width
if t.texture and t.width then
self:setPage(t.texture,t.width)
end
if t.action then
self.action = t.action
end
end
function PDFPage:setPage(t,w)
w = w or self.width
self.width = w
self.page.texture = readImage(t,w)
end
function PDFPage:draw()
self.page:draw()
end
function PDFPage:isTouchedBy(touch)
if self.action then
return true
end
return false
end
function PDFPage:processTouches(g)
if g.updated and g.type.ended then
self.action()
g:reset()
end
g:noted()
end
return {Layout, Block, PDFPage}
--]==]
-- Beamer
displayMode(FULLSCREEN_NO_BUTTONS)
VERSION = "1.0"
function setup()
autoGist = AutoGist("Beamer","A prototype of a beamer display program.",VERSION,false)
autoGist:backup(true)
cmodule "Beamer"
cmodule.path("Harmony CModule", "Library Base", "Library UI", "Library Utilities", "Library Graphics", "Library Maths")
local Touches = cimport "Touch"
local UI = cimport "UI"
local Debug = cimport "Debug"
local Canvas = cimport "Canvas"
local Font,_,Textarea = unpack(cimport "Font")
local Colour = unpack(cimport "Colour")
cimport "MathsUtilities"
local ImageCache = cimport "ImageCache"
local Layout,Block,PDFPage = unpack(cimport "Layout")
name = "Dropbox:smocally_%02d"
document = {
{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}
}
duration = .1
--
touches = Touches()
ui = UI(touches)
debug = Debug({ui = ui})
debug:activate()
debug:log({name = "Memory", message = gcinfo})
ui:systemmenu()
icache = ImageCache()
ui.mainMenu.opos = function()
return RectAnchorOf(Screen,"north west")
end
local cw,ch = RectAnchorOf(Portrait,"size")
local sep = 10
slides = 0
frames = 0
duration = duration * 60
for _,v in ipairs(document) do
for _,u in ipairs(v) do
slides = slides + 1
end
frames = frames + 1
end
current = {1,1}
slideText = Textarea({
font = Font({name = "Futura-Medium", size = 256}),
width = WIDTH,
height = HEIGHT,
colour = Colour.transparent,
textColour = Colour.svg.White,
pos = function() return WIDTH/2,HEIGHT/2 end,
anchor = "centre",
fit = true
})
frameText = Textarea({
font = Font({name = "Futura-Medium", size = 256}),
width = WIDTH,
height = HEIGHT,
colour = Colour.transparent,
textColour = Colour.svg.White,
pos = function() return WIDTH/2,HEIGHT/2 end,
anchor = "centre",
fit = true
})
clock = Textarea({
font = Font({name = "Futura-Medium", size = 198}),
width = WIDTH,
height = HEIGHT,
colour = Colour.transparent,
textColour = Colour.svg.White,
pos = function() return WIDTH/2,HEIGHT/2 end,
anchor = "centre",
fit = true
})
slideText:activate()
frameText:activate()
clock:activate()
clock:setLines(string.format("%02d:%02d:%02d",0,0,0))
clock.sep = 50
canvas = Canvas({
ui = ui,
title = "Draw",
brushes = "Simple",
enableText = false,
enablePictures = false,
})
for l,u in ipairs(canvas.bgtcoords) do
canvas.bgtcoords[l] = USRotateCW(u)
end
canvas.bgmesh.texCoords = canvas.bgtcoords
canvas:setStyle({bgcolour = Colour.transparent})
canvas.bgmesh:setColors(Colour.transparent)
canvasFrame = mesh()
canvasSlide = mesh()
canvasHighlight = mesh()
local x,y = RectAnchorOf(Portrait,"centre")
local w,h = RectAnchorOf(Portrait,"size")
canvasFrame:addRect(x,y,w,h)
canvasSlide:addRect(x,y,w,h)
canvasHighlight:addRect(x,y,w,h)
canvasHighlightImage = "Highlighter"
local im = icache:getImage(canvasHighlightImage)
if not im then
im = icache:addImage(canvasHighlightImage,
image(RectAnchorOf(Portrait,"size")))
end
canvasHighlight.texture = im
--[[
local tcds = {}
for l,u in ipairs(canvas.bgtcoords) do
tcds[l] = USRotateCW(u)
end
canvasFrame.texCoords = tcds
canvasSlide.texCoords = tcds
--]]
--scratch = image(RectAnchorOf(Portrait,"size"))
local blrep,blnor,blerr
for k,v in ipairs(BLENDS) do
if v[1] == "Normal" then
blnor = v[2]
end
if v[1] == "Replace" then
blrep = v[2]
end
if v[1] == "Eraser" then
blerr = v[2]
end
end
pointerStyle = {
--drawable = "Simple",
maxthickness = 80,
thickness = 45,
colour = Colour.svg.HotPink,
alpha = 50,
cap = CAPROUND,
blendmode = blrep
}
eraserStyle = {
--drawable = "Simple",
maxthickness = 80,
thickness = 45,
colour = Colour.svg.White,
alpha = 100,
cap = CAPROUND,
blendmode = blerr
}
penStyle = {
--drawable = "Simple",
maxthickness = 15,
thickness = 5,
colour = Colour.svg.Black,
alpha = 100,
cap = CAPROUND,
blendmode = blnor
}
cPen = "Pen"
for _,v in ipairs({
{"Pen", penStyle},
{"Eraser", eraserStyle},
{"Highlighter", pointerStyle}
}) do
canvas.stylemenu:addItem({
title = v[1],
action = function()
canvas:setStyle(v[2])
cPen = v[1]
return true
end,
highlight = function()
return cPen == v[1]
end
})
end
portrait = Layout(touches)
main = portrait:addBlock({
position = vec2(0,ch-40),
orientation = LANDSCAPE_LEFT,
width = cw,
anchor = "north west",
contents = PDFPage({orientation = LANDSCAPE_LEFT, width = cw})
})
maincf = portrait:addBlock({
position = vec2(0,ch-40),
orientation = LANDSCAPE_LEFT,
width = cw,
anchor = "north west",
contents = canvasFrame
})
maincs = portrait:addBlock({
position = vec2(0,ch-40),
orientation = LANDSCAPE_LEFT,
width = cw,
anchor = "north west",
contents = canvasSlide
})
maincs = portrait:addBlock({
position = vec2(0,ch-40),
orientation = LANDSCAPE_LEFT,
width = cw,
anchor = "north west",
contents = canvasHighlight
})
maincp = portrait:addBlock({
position = vec2(0,ch-40),
orientation = LANDSCAPE_LEFT,
width = cw,
anchor = "north west",
contents = canvas
})
local bll = main:anchor("south west")
prevslide = portrait:addBlock({
position = bll - vec2(0,sep),
width = cw/3,
orientation = LANDSCAPE_LEFT,
anchor = "north west",
contents = PDFPage({
orientation = LANDSCAPE_LEFT,
width = cw/3,
action = prevSlide
})
})
bll = main:anchor("south")
stext = portrait:addBlock({
position = bll - vec2(0,sep),
height = cw/4,
orientation = PORTRAIT,
anchor = "north",
contents = slideText
})
bll = stext:anchor("south")
portrait:addBlock({
position = bll - vec2(0,sep),
height = cw/4,
orientation = PORTRAIT,
anchor = "north",
contents = frameText
})
portrait:addBlock({
position = bll - vec2(0,sep/2),
height = cw/4,
orientation = PORTRAIT,
anchor = "centre",
contents = clock
})
bll = prevslide:anchor("south west")
prevframe = portrait:addBlock({
position = bll - vec2(0,sep),
width = cw/3,
orientation = LANDSCAPE_LEFT,
anchor = "north west",
contents = PDFPage({
orientation = LANDSCAPE_LEFT,
width = cw/3,
action = prevFrame
})
})
bll = main:anchor("south east")
nextslide = portrait:addBlock({
position = bll - vec2(0,sep),
width = cw/3,
orientation = LANDSCAPE_LEFT,
anchor = "north east",
contents = PDFPage({
orientation = LANDSCAPE_LEFT,
width = cw/3,
action = nextSlide
})
})
bll = nextslide:anchor("south east")
nextframe = portrait:addBlock({
position = bll - vec2(0,sep),
width = cw/3,
orientation = LANDSCAPE_LEFT,
anchor = "north east",
contents = PDFPage({
orientation = LANDSCAPE_LEFT,
width = cw/3,
action = nextFrame
})
})
--cw,ch = RectAnchorOf(Landscape,"size")
landscape = Layout(touches)
mainl = landscape:addBlock({
position = vec2(0,0),
width = cw,
orientation = PORTRAIT,
anchor = "south west",
contents = PDFPage({
orientation = LANDSCAPE_LEFT,
width = ch,
})
})
mainlf = landscape:addBlock({
position = vec2(0,0),
orientation = PORTRAIT,
width = cw,
anchor = "south west",
contents = canvasFrame
})
mainls = landscape:addBlock({
position = vec2(0,0),
orientation = PORTRAIT,
width = cw,
anchor = "south west",
contents = canvasSlide
})
mainlp = landscape:addBlock({
position = vec2(0,0),
orientation = PORTRAIT,
width = cw,
anchor = "south west",
contents = canvas
})
setSlide(current)
canvas:setStyle(penStyle) -- gets changed in orientation
orientationChanged = _orientationChanged
orientationChanged(CurrentOrientation)
cTime = 0
pTime = 0
paused = true
end
function draw()
touches:draw()
background(40, 40, 50)
slideText:setLines(document[current[1]][current[2]] .. "/" .. slides)
frameText:setLines(current[1] .. "/" .. frames)
if not paused then
clock:setLines(string.format("%02d:%02d:%02d",
math.floor((ElapsedTime - cTime)/(24*60)),
(math.floor((ElapsedTime - cTime)/60)%60),
((ElapsedTime - cTime)%60)
))
if ElapsedTime - cTime > duration then
clock.colour = Colour.svg.Red
end
end
TransformOrientation(PORTRAIT)
portrait:draw()
landscape:draw()
icache:draw()
ui:draw()
debug:draw()
end
function touched(touch)
touches:addTouch(touch)
end
function _orientationChanged(o)
ui:orientationChanged(o)
if o == PORTRAIT or o == PORTRAIT_UPSIDE_DOWN then
portrait:activate()
landscape:deactivate()
setActiveCanvas(canvasHighlightImage)
penStyle = canvas:saveStyle()
canvas:setStyle(pointerStyle)
cPen = "Highlighter"
else
landscape:activate()
portrait:deactivate()
setActiveCanvas(canvasSlideImage)
pointerStyle = canvas:saveStyle()
canvas:setStyle(penStyle)
cPen = "Pen"
end
end
function setSlide(c)
canvas:drawcanvas()
icache:setImageInUse(canvasSlideImage,false)
icache:setImageInUse(canvasFrameImage,false)
local n = document[c[1]][c[2]]
local sname = string.format(name,n)
main.contents:setPage(sname)
mainl.contents:setPage(sname)
canvasSlideImage = sname .. "_Slide"
canvasFrameImage = string.format(name,c[1]) .. "_Frame"
local im = icache:getImage(canvasSlideImage)
if not im then
im = icache:addImage(canvasSlideImage,
image(RectAnchorOf(Portrait,"size")))
end
canvasSlide.texture = im
im = icache:getImage(canvasFrameImage)
if not im then
im = icache:addImage(canvasFrameImage,
image(RectAnchorOf(Portrait,"size")))
end
canvasFrame.texture = im
if document[c[1]][c[2] + 1] then
n = document[c[1]][c[2]+1]
elseif document[c[1]+1] then
n = document[c[1]+1][1]
end
nextslide.contents:setPage(string.format(name,n))
if document[c[1]+1] then
n = document[c[1]+1][1]
else
n = document[c[1]][#document[c[1]]]
end
nextframe.contents:setPage(string.format(name,n))
if document[c[1]][c[2] - 1] then
n = document[c[1]][c[2]-1]
elseif document[c[1]-1] then
n = document[c[1]-1][#document[c[1]-1]]
else
n = document[c[1]][c[2]]
end
prevslide.contents:setPage(string.format(name,n))
if c[2] == 1 then
if document[c[1]-1] then
n = document[c[1]-1][1]
else
n = document[c[1]][1]
end
else
n = document[c[1]][1]
end
prevframe.contents:setPage(string.format(name,n))
end
--[[
function saveAnnotations()
local c = current
local n = document[c[1] ] [c[2] ]
canvas:drawcanvas()
icache:setImageSaveable(string.format(name,n) .. "_Slide",true)
icache:setImageSaveable(string.format(name,c[1]) .. "_Frame",true)
canvas:clear()
end
--]]
function nextSlide()
if document[current[1]][current[2]+1] then
current[2] = current[2] + 1
setSlide(current)
return
end
if document[current[1]+1] then
current[1] = current[1] + 1
current[2] = 1
setSlide(current)
return
end
end
function nextFrame()
if document[current[1]+1] then
current[1] = current[1] + 1
current[2] = 1
setSlide(current)
return
end
current[2] = #document[current[1]]
setSlide(current)
end
function prevSlide()
if document[current[1]][current[2]-1] then
current[2] = current[2] - 1
setSlide(current)
return
end
if document[current[1]-1] then
current[1] = current[1] - 1
current[2] = #document[current[1]]
setSlide(current)
return
end
end
function prevFrame()
if current[2] > 1 then
current[2] = 1
setSlide(current)
return
end
if document[current[1]-1] then
current[1] = current[1] - 1
current[2] = 1
setSlide(current)
return
end
current[2] = 1
setSlide(current)
end
function pause()
paused = not paused
if paused then
pTime = ElapsedTime - cTime
else
cTime = ElapsedTime - pTime
end
end
function setActiveCanvas(im)
canvas:drawcanvas()
if currentCanvas then
if canvas.drawnon then
icache:setImageSaveable(currentCanvas,true)
end
end
if im then
canvas.canvas = icache:getImage(im)
currentCanvas = im
else
canvas.canvas = scratch
currentCanvas = nil
end
end
_close = close
function close()
icache:close()
_close()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment