2014-10-14 02:43:17 +00:00
|
|
|
function tostr(t)
|
|
|
|
local str = ""
|
|
|
|
for k, v in next, t do
|
|
|
|
if #str > 0 then
|
|
|
|
str = str .. ", "
|
|
|
|
end
|
|
|
|
if type(k) == "number" then
|
|
|
|
str = str .. "[" .. k .. "] = "
|
|
|
|
else
|
|
|
|
str = str .. tostring(k) .. " = "
|
|
|
|
end
|
|
|
|
if type(v) == "table" then
|
|
|
|
str = str .. "{ " .. tostr(v) .. " }"
|
|
|
|
elseif type(v) == "string" then
|
|
|
|
str = str .. '"' .. v .. '"'
|
|
|
|
else
|
|
|
|
str = str .. tostring(v)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return str
|
|
|
|
end
|
2014-10-11 18:28:07 +00:00
|
|
|
|
2014-10-14 02:43:17 +00:00
|
|
|
|
|
|
|
function trim_ws(s)
|
|
|
|
return s:match("^%s*(.*)")
|
|
|
|
end
|
|
|
|
|
|
|
|
function count_hypens(s)
|
|
|
|
local leftover = s:match("^-*(.*)")
|
|
|
|
return string.len(s) - string.len(leftover)
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
|
|
|
|
2014-10-14 02:43:17 +00:00
|
|
|
function parse_file(file)
|
|
|
|
local slides = {}
|
|
|
|
local block = {}
|
|
|
|
|
|
|
|
for line in file:lines() do
|
|
|
|
local s = trim_ws(line)
|
|
|
|
if #s == 0 then -- done with a block
|
|
|
|
if #block > 0 then
|
|
|
|
slides[#slides + 1] = block
|
|
|
|
block = {}
|
|
|
|
end
|
|
|
|
else
|
|
|
|
local n = count_hypens(s)
|
|
|
|
block[#block + 1] = {
|
|
|
|
indent = n,
|
|
|
|
text = trim_ws(s:sub(n + 1, -1))
|
|
|
|
}
|
|
|
|
end
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
2014-10-14 02:43:17 +00:00
|
|
|
return slides
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
|
|
|
|
2014-10-14 02:43:17 +00:00
|
|
|
function pretty_print_slide(slide)
|
|
|
|
io.write("{\n")
|
|
|
|
for i = 1, #slide do
|
|
|
|
local node = slide[i]
|
|
|
|
for j = 0, node.indent do
|
|
|
|
io.write(" ")
|
|
|
|
end
|
|
|
|
io.write("{ ")
|
|
|
|
io.write(tostr(node))
|
|
|
|
io.write(" },\n")
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
2014-10-14 02:43:17 +00:00
|
|
|
io.write("},\n")
|
|
|
|
end
|
|
|
|
|
|
|
|
function pretty_print_slides(slides)
|
|
|
|
io.write("gSlides = {\n")
|
|
|
|
for i = 1, #slides do
|
|
|
|
pretty_print_slide(slides[i])
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
2014-10-14 02:43:17 +00:00
|
|
|
io.write("}\n")
|
|
|
|
end
|
|
|
|
|
|
|
|
gSlides = parse_file(io.open("/skia/trunk/resources/slides_content.lua", "r"))
|
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
function make_rect(l, t, r, b)
|
|
|
|
return { left = l, top = t, right = r, bottom = b }
|
|
|
|
end
|
|
|
|
|
|
|
|
function make_paint(typefacename, stylebits, size, color)
|
2014-10-14 02:43:17 +00:00
|
|
|
local paint = Sk.newPaint();
|
|
|
|
paint:setAntiAlias(true)
|
|
|
|
paint:setSubpixelText(true)
|
2014-10-14 16:34:52 +00:00
|
|
|
paint:setTypeface(Sk.newTypeface(typefacename, stylebits))
|
2014-10-14 02:43:17 +00:00
|
|
|
paint:setTextSize(size)
|
|
|
|
paint:setColor(color)
|
|
|
|
return paint
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
function drawSlide(canvas, slide, template)
|
|
|
|
template = template.slide -- need to sniff the slide to know if we're title or slide
|
|
|
|
|
|
|
|
local x = template.margin_x
|
|
|
|
local y = template.margin_y
|
|
|
|
|
2014-10-14 02:43:17 +00:00
|
|
|
local scale = 1.15
|
|
|
|
for i = 1, #slide do
|
|
|
|
local node = slide[i]
|
2014-10-14 16:34:52 +00:00
|
|
|
local paint = template[node.indent + 1]
|
2014-10-14 02:43:17 +00:00
|
|
|
local fm = paint:getFontMetrics()
|
2014-10-14 16:34:52 +00:00
|
|
|
local x_offset = -fm.ascent * node.indent
|
|
|
|
|
2014-10-14 02:43:17 +00:00
|
|
|
y = y - fm.ascent * scale
|
2014-10-14 16:34:52 +00:00
|
|
|
canvas:drawText(node.text, x + x_offset, y, paint)
|
2014-10-14 02:43:17 +00:00
|
|
|
y = y + fm.descent * scale
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
function slide_transition(prev, next, is_forward)
|
|
|
|
local rec = {
|
|
|
|
proc = function(self, canvas, drawSlideProc)
|
|
|
|
if self:isDone() then
|
|
|
|
drawSlideProc(canvas)
|
|
|
|
return nil
|
|
|
|
end
|
2014-10-13 19:38:04 +00:00
|
|
|
self.prevDrawable:draw(canvas, self.curr_x, 0)
|
|
|
|
self.nextDrawable:draw(canvas, self.curr_x + 640, 0)
|
2014-10-12 19:18:40 +00:00
|
|
|
self.curr_x = self.curr_x + self.step_x
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
}
|
|
|
|
if is_forward then
|
2014-10-13 19:38:04 +00:00
|
|
|
rec.prevDrawable = prev
|
|
|
|
rec.nextDrawable = next
|
2014-10-12 19:18:40 +00:00
|
|
|
rec.curr_x = 0
|
|
|
|
rec.step_x = -15
|
|
|
|
rec.isDone = function (self) return self.curr_x <= -640 end
|
|
|
|
else
|
2014-10-13 19:38:04 +00:00
|
|
|
rec.prevDrawable = next
|
|
|
|
rec.nextDrawable = prev
|
2014-10-12 19:18:40 +00:00
|
|
|
rec.curr_x = -640
|
|
|
|
rec.step_x = 15
|
|
|
|
rec.isDone = function (self) return self.curr_x >= 0 end
|
|
|
|
end
|
|
|
|
return rec
|
|
|
|
end
|
|
|
|
|
2014-10-13 02:05:52 +00:00
|
|
|
function fade_slide_transition(prev, next, is_forward)
|
|
|
|
local rec = {
|
2014-10-13 19:38:04 +00:00
|
|
|
prevDrawable = prev,
|
|
|
|
nextDrawable = next,
|
2014-10-13 02:05:52 +00:00
|
|
|
proc = function(self, canvas, drawSlideProc)
|
|
|
|
if self:isDone() then
|
|
|
|
drawSlideProc(canvas)
|
|
|
|
return nil
|
|
|
|
end
|
2014-10-13 19:38:04 +00:00
|
|
|
self.prevDrawable:draw(canvas, self.prev_x, 0, self.prev_a)
|
|
|
|
self.nextDrawable:draw(canvas, self.next_x, 0, self.next_a)
|
2014-10-13 02:05:52 +00:00
|
|
|
self:step()
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
}
|
|
|
|
if is_forward then
|
|
|
|
rec.prev_x = 0
|
|
|
|
rec.prev_a = 1
|
|
|
|
rec.next_x = 640
|
|
|
|
rec.next_a = 0
|
|
|
|
rec.isDone = function (self) return self.next_x <= 0 end
|
|
|
|
rec.step = function (self)
|
|
|
|
self.next_x = self.next_x - 20
|
|
|
|
self.next_a = (640 - self.next_x) / 640
|
|
|
|
self.prev_a = 1 - self.next_a
|
|
|
|
end
|
|
|
|
else
|
|
|
|
rec.prev_x = 0
|
|
|
|
rec.prev_a = 1
|
|
|
|
rec.next_x = 0
|
|
|
|
rec.next_a = 0
|
|
|
|
rec.isDone = function (self) return self.prev_x >= 640 end
|
|
|
|
rec.step = function (self)
|
|
|
|
self.prev_x = self.prev_x + 20
|
|
|
|
self.prev_a = (640 - self.prev_x) / 640
|
|
|
|
self.next_a = 1 - self.prev_a
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return rec
|
|
|
|
end
|
|
|
|
|
2014-10-11 18:28:07 +00:00
|
|
|
--------------------------------------------------------------------------------------
|
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
function SkiaPoint_make_template()
|
|
|
|
local title = {
|
|
|
|
margin_x = 30,
|
|
|
|
margin_y = 100,
|
|
|
|
}
|
|
|
|
title[1] = make_paint("Arial", 1, 50, { a=1, r=0, g=0, b=0 })
|
|
|
|
title[1]:setTextAlign("center")
|
|
|
|
title[2] = make_paint("Arial", 1, 25, { a=1, r=.3, g=.3, b=.3 })
|
|
|
|
title[2]:setTextAlign("center")
|
|
|
|
|
|
|
|
local slide = {
|
|
|
|
margin_x = 20,
|
|
|
|
margin_y = 30,
|
|
|
|
}
|
|
|
|
slide[1] = make_paint("Arial", 1, 36, { a=1, r=0, g=0, b=0 })
|
|
|
|
slide[2] = make_paint("Arial", 0, 30, { a=1, r=0, g=0, b=0 })
|
|
|
|
slide[3] = make_paint("Arial", 0, 24, { a=1, r=.2, g=.2, b=.2 })
|
2014-10-11 18:28:07 +00:00
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
return {
|
|
|
|
title = title,
|
|
|
|
slide = slide,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
gTemplate = SkiaPoint_make_template()
|
2014-10-11 18:28:07 +00:00
|
|
|
|
|
|
|
gRedPaint = Sk.newPaint()
|
|
|
|
gRedPaint:setAntiAlias(true)
|
|
|
|
gRedPaint:setColor{a=1, r=1, g=0, b=0 }
|
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
-- animation.proc is passed the canvas before drawing.
|
|
|
|
-- The animation.proc returns itself or another animation (which means keep animating)
|
|
|
|
-- or it returns nil, which stops the animation.
|
|
|
|
--
|
|
|
|
local gCurrAnimation
|
2014-10-11 20:13:11 +00:00
|
|
|
|
2014-10-11 18:28:07 +00:00
|
|
|
gSlideIndex = 1
|
|
|
|
|
2014-10-11 20:13:11 +00:00
|
|
|
function next_slide()
|
2014-10-12 19:18:40 +00:00
|
|
|
local prev = gSlides[gSlideIndex]
|
|
|
|
|
2014-10-11 20:13:11 +00:00
|
|
|
gSlideIndex = gSlideIndex + 1
|
|
|
|
if gSlideIndex > #gSlides then
|
|
|
|
gSlideIndex = 1
|
|
|
|
end
|
2014-10-12 19:18:40 +00:00
|
|
|
|
|
|
|
spawn_transition(prev, gSlides[gSlideIndex], true)
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function prev_slide()
|
2014-10-12 19:18:40 +00:00
|
|
|
local prev = gSlides[gSlideIndex]
|
|
|
|
|
2014-10-11 20:13:11 +00:00
|
|
|
gSlideIndex = gSlideIndex - 1
|
|
|
|
if gSlideIndex < 1 then
|
|
|
|
gSlideIndex = #gSlides
|
|
|
|
end
|
2014-10-12 19:18:40 +00:00
|
|
|
|
|
|
|
spawn_transition(prev, gSlides[gSlideIndex], false)
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
|
|
|
|
2014-10-13 19:38:04 +00:00
|
|
|
function new_drawable_picture(pic)
|
|
|
|
return {
|
|
|
|
picture = pic,
|
|
|
|
width = pic:width(),
|
|
|
|
height = pic:height(),
|
|
|
|
draw = function (self, canvas, x, y, paint)
|
|
|
|
canvas:drawPicture(self.picture, x, y, paint)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function new_drawable_image(img)
|
|
|
|
return {
|
|
|
|
image = img,
|
|
|
|
width = img:width(),
|
|
|
|
height = img:height(),
|
|
|
|
draw = function (self, canvas, x, y, paint)
|
|
|
|
canvas:drawImage(self.image, x, y, paint)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
2014-10-11 18:28:07 +00:00
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
function spawn_transition(prevSlide, nextSlide, is_forward)
|
|
|
|
local transition
|
|
|
|
if is_forward then
|
|
|
|
transition = prevSlide.transition
|
|
|
|
else
|
|
|
|
transition = nextSlide.transition
|
|
|
|
end
|
|
|
|
|
|
|
|
if not transition then
|
2014-10-14 02:43:17 +00:00
|
|
|
transition = fade_slide_transition
|
2014-10-12 19:18:40 +00:00
|
|
|
end
|
|
|
|
|
2014-10-13 19:38:04 +00:00
|
|
|
local rec = Sk.newPictureRecorder()
|
2014-10-12 19:18:40 +00:00
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
drawSlide(rec:beginRecording(640, 480), prevSlide, gTemplate)
|
2014-10-13 19:38:04 +00:00
|
|
|
local prevDrawable = new_drawable_picture(rec:endRecording())
|
2014-10-12 19:18:40 +00:00
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
drawSlide(rec:beginRecording(640, 480), nextSlide, gTemplate)
|
2014-10-13 19:38:04 +00:00
|
|
|
local nextDrawable = new_drawable_picture(rec:endRecording())
|
2014-10-12 19:18:40 +00:00
|
|
|
|
2014-10-13 19:38:04 +00:00
|
|
|
gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
|
2014-10-12 19:18:40 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------------
|
2014-10-11 20:13:11 +00:00
|
|
|
|
|
|
|
function spawn_rotate_animation()
|
|
|
|
gCurrAnimation = {
|
|
|
|
angle = 0,
|
|
|
|
angle_delta = 5,
|
|
|
|
pivot_x = 320,
|
|
|
|
pivot_y = 240,
|
2014-10-12 19:18:40 +00:00
|
|
|
proc = function (self, canvas, drawSlideProc)
|
|
|
|
if self.angle >= 360 then
|
|
|
|
drawSlideProc(canvas)
|
2014-10-11 20:13:11 +00:00
|
|
|
return nil
|
|
|
|
end
|
2014-10-12 19:18:40 +00:00
|
|
|
canvas:translate(self.pivot_x, self.pivot_y)
|
|
|
|
canvas:rotate(self.angle)
|
|
|
|
canvas:translate(-self.pivot_x, -self.pivot_y)
|
|
|
|
drawSlideProc(canvas)
|
2014-10-11 20:13:11 +00:00
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
self.angle = self.angle + self.angle_delta
|
|
|
|
return self
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
function spawn_scale_animation()
|
|
|
|
gCurrAnimation = {
|
|
|
|
scale = 1,
|
|
|
|
scale_delta = .95,
|
|
|
|
scale_limit = 0.2,
|
|
|
|
pivot_x = 320,
|
|
|
|
pivot_y = 240,
|
2014-10-12 19:18:40 +00:00
|
|
|
proc = function (self, canvas, drawSlideProc)
|
|
|
|
if self.scale < self.scale_limit then
|
|
|
|
self.scale = self.scale_limit
|
|
|
|
self.scale_delta = 1 / self.scale_delta
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
2014-10-12 19:18:40 +00:00
|
|
|
if self.scale > 1 then
|
|
|
|
drawSlideProc(canvas)
|
2014-10-11 20:13:11 +00:00
|
|
|
return nil
|
|
|
|
end
|
2014-10-12 19:18:40 +00:00
|
|
|
canvas:translate(self.pivot_x, self.pivot_y)
|
|
|
|
canvas:scale(self.scale, self.scale)
|
|
|
|
canvas:translate(-self.pivot_x, -self.pivot_y)
|
|
|
|
drawSlideProc(canvas)
|
2014-10-11 20:13:11 +00:00
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
self.scale = self.scale * self.scale_delta
|
|
|
|
return self
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2014-10-14 16:34:52 +00:00
|
|
|
function onDrawContent(canvas, width, height)
|
|
|
|
local matrix = Sk.newMatrix()
|
|
|
|
matrix:setRectToRect(make_rect(0, 0, 640, 480), make_rect(0, 0, width, height), "center")
|
|
|
|
canvas:concat(matrix)
|
|
|
|
|
2014-10-12 19:18:40 +00:00
|
|
|
local drawSlideProc = function(canvas)
|
2014-10-14 16:34:52 +00:00
|
|
|
drawSlide(canvas, gSlides[gSlideIndex], gTemplate)
|
2014-10-11 20:13:11 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if gCurrAnimation then
|
2014-10-12 19:18:40 +00:00
|
|
|
gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
|
2014-10-11 20:13:11 +00:00
|
|
|
return true
|
|
|
|
else
|
2014-10-12 19:18:40 +00:00
|
|
|
drawSlideProc(canvas)
|
2014-10-11 20:13:11 +00:00
|
|
|
return false
|
|
|
|
end
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function onClickHandler(x, y)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2014-10-11 20:13:11 +00:00
|
|
|
local keyProcs = {
|
|
|
|
n = next_slide,
|
|
|
|
p = prev_slide,
|
|
|
|
r = spawn_rotate_animation,
|
|
|
|
s = spawn_scale_animation,
|
|
|
|
}
|
|
|
|
|
|
|
|
function onCharHandler(uni)
|
|
|
|
local proc = keyProcs[uni]
|
|
|
|
if proc then
|
|
|
|
proc()
|
|
|
|
return true
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|
2014-10-11 20:13:11 +00:00
|
|
|
return false
|
2014-10-11 18:28:07 +00:00
|
|
|
end
|