blob: 29ca8d13add98cdf279ef13ad3c03ca38becbe31 [file] [log] [blame]
reed18ea7772014-10-11 11:28:07 -07001
2function make_paint(size, color)
3 local paint = Sk.newPaint();
4 paint:setAntiAlias(true)
reed09a1d672014-10-11 13:13:11 -07005 paint:setSubpixelText(true)
reed18ea7772014-10-11 11:28:07 -07006 paint:setTextSize(size)
7 paint:setColor(color)
8 return paint
9end
10
11function find_paint(paints, style)
12 if not style then
13 style = "child"
14 end
15 local paint = paints[style]
16 return paint
17end
18
19function draw_node(canvas, node, x, y, paints)
20 if node.text then
21 local paint = find_paint(paints, node.style)
22 canvas:drawText(node.text, x, y, paint)
23 end
24 if node.draw then
25 node.draw(canvas)
26 end
27end
28
29function drawSlide(canvas, slide, template, paints)
30 draw_node(canvas, slide, template.title.x, template.title.y, paints)
31
32 if slide.children then
33 local x = template.child.x
34 local y = template.child.y
35 local dy = template.child.dy
36 for i = 1, #slide.children do
37 draw_node(canvas, slide.children[i], x, y, paints)
38 y = y + dy
39 end
40 end
41end
42
reedf355df52014-10-12 12:18:40 -070043function slide_transition(prev, next, is_forward)
44 local rec = {
45 proc = function(self, canvas, drawSlideProc)
46 if self:isDone() then
47 drawSlideProc(canvas)
48 return nil
49 end
reed96affcd2014-10-13 12:38:04 -070050 self.prevDrawable:draw(canvas, self.curr_x, 0)
51 self.nextDrawable:draw(canvas, self.curr_x + 640, 0)
reedf355df52014-10-12 12:18:40 -070052 self.curr_x = self.curr_x + self.step_x
53 return self
54 end
55 }
56 if is_forward then
reed96affcd2014-10-13 12:38:04 -070057 rec.prevDrawable = prev
58 rec.nextDrawable = next
reedf355df52014-10-12 12:18:40 -070059 rec.curr_x = 0
60 rec.step_x = -15
61 rec.isDone = function (self) return self.curr_x <= -640 end
62 else
reed96affcd2014-10-13 12:38:04 -070063 rec.prevDrawable = next
64 rec.nextDrawable = prev
reedf355df52014-10-12 12:18:40 -070065 rec.curr_x = -640
66 rec.step_x = 15
67 rec.isDone = function (self) return self.curr_x >= 0 end
68 end
69 return rec
70end
71
reed0d76b952014-10-12 19:05:52 -070072function fade_slide_transition(prev, next, is_forward)
73 local rec = {
reed96affcd2014-10-13 12:38:04 -070074 prevDrawable = prev,
75 nextDrawable = next,
reed0d76b952014-10-12 19:05:52 -070076 proc = function(self, canvas, drawSlideProc)
77 if self:isDone() then
78 drawSlideProc(canvas)
79 return nil
80 end
reed96affcd2014-10-13 12:38:04 -070081 self.prevDrawable:draw(canvas, self.prev_x, 0, self.prev_a)
82 self.nextDrawable:draw(canvas, self.next_x, 0, self.next_a)
reed0d76b952014-10-12 19:05:52 -070083 self:step()
84 return self
85 end
86 }
87 if is_forward then
88 rec.prev_x = 0
89 rec.prev_a = 1
90 rec.next_x = 640
91 rec.next_a = 0
92 rec.isDone = function (self) return self.next_x <= 0 end
93 rec.step = function (self)
94 self.next_x = self.next_x - 20
95 self.next_a = (640 - self.next_x) / 640
96 self.prev_a = 1 - self.next_a
97 end
98 else
99 rec.prev_x = 0
100 rec.prev_a = 1
101 rec.next_x = 0
102 rec.next_a = 0
103 rec.isDone = function (self) return self.prev_x >= 640 end
104 rec.step = function (self)
105 self.prev_x = self.prev_x + 20
106 self.prev_a = (640 - self.prev_x) / 640
107 self.next_a = 1 - self.prev_a
108 end
109 end
110 return rec
111end
112
reed18ea7772014-10-11 11:28:07 -0700113--------------------------------------------------------------------------------------
114
115gTemplate = {
116 title = { x = 10, y = 64, textSize = 64 },
117 child = { x = 40, y = 120, dy = 50, textSize = 40 },
118}
119
120gPaints = {}
121gPaints.title = make_paint(gTemplate.title.textSize, { a=1, r=0, g=0, b=0 } )
122gPaints.child = make_paint(gTemplate.child.textSize, { a=.75, r=0, g=0, b=0 } )
123
124gRedPaint = Sk.newPaint()
125gRedPaint:setAntiAlias(true)
126gRedPaint:setColor{a=1, r=1, g=0, b=0 }
127
128gSlides = {
129 { text = "Title1", style="title", color = { a=1, r=1, g=0, b=0 },
130 children = {
131 { text = "bullet 1", style = "child" },
132 { text = "bullet 2", style = "child" },
133 { text = "bullet 3", style = "child" },
134 { draw = function (canvas)
135 canvas:drawOval({left=300, top=300, right=400, bottom=400}, gRedPaint)
136 end },
137 },
reed0d76b952014-10-12 19:05:52 -0700138 transition = fade_slide_transition
reed18ea7772014-10-11 11:28:07 -0700139 },
140 { text = "Title2", style="title", color = { a=1, r=0, g=1, b=0 },
141 children = {
142 { text = "bullet uno", style = "child" },
143 { text = "bullet 2", style = "child" },
144 { text = "bullet tres", style = "child" },
reedf355df52014-10-12 12:18:40 -0700145 },
reed0d76b952014-10-12 19:05:52 -0700146 transition = slide_transition
reed18ea7772014-10-11 11:28:07 -0700147 },
148 { text = "Title3", style="title",
149 children = {
150 { text = "bullet 1", style = "child", },
151 { text = "bullet 2", style = "child", color = { r=0, g=0, b=1 } },
152 { text = "bullet 3", style = "child" },
153 }
154 }
155}
156
reed18ea7772014-10-11 11:28:07 -0700157--------------------------------------------------------------------------------------
reedf355df52014-10-12 12:18:40 -0700158function tostr(t)
159 local str = ""
160 for k, v in next, t do
161 if #str > 0 then
162 str = str .. ", "
163 end
164 if type(k) == "number" then
165 str = str .. "[" .. k .. "] = "
166 else
167 str = str .. tostring(k) .. " = "
168 end
169 if type(v) == "table" then
170 str = str .. "{ " .. tostr(v) .. " }"
171 else
172 str = str .. tostring(v)
173 end
reed18ea7772014-10-11 11:28:07 -0700174 end
reedf355df52014-10-12 12:18:40 -0700175 return str
reed18ea7772014-10-11 11:28:07 -0700176end
177
reed09a1d672014-10-11 13:13:11 -0700178-- animation.proc is passed the canvas before drawing.
179-- The animation.proc returns itself or another animation (which means keep animating)
180-- or it returns nil, which stops the animation.
181--
182local gCurrAnimation
183
reedf355df52014-10-12 12:18:40 -0700184gSlideIndex = 1
185
186function next_slide()
187 local prev = gSlides[gSlideIndex]
188
189 gSlideIndex = gSlideIndex + 1
190 if gSlideIndex > #gSlides then
191 gSlideIndex = 1
192 end
193
194 spawn_transition(prev, gSlides[gSlideIndex], true)
195end
196
197function prev_slide()
198 local prev = gSlides[gSlideIndex]
199
200 gSlideIndex = gSlideIndex - 1
201 if gSlideIndex < 1 then
202 gSlideIndex = #gSlides
203 end
204
205 spawn_transition(prev, gSlides[gSlideIndex], false)
206end
207
reed96affcd2014-10-13 12:38:04 -0700208function new_drawable_picture(pic)
209 return {
210 picture = pic,
211 width = pic:width(),
212 height = pic:height(),
213 draw = function (self, canvas, x, y, paint)
214 canvas:drawPicture(self.picture, x, y, paint)
215 end
216 }
217end
218
219function new_drawable_image(img)
220 return {
221 image = img,
222 width = img:width(),
223 height = img:height(),
224 draw = function (self, canvas, x, y, paint)
225 canvas:drawImage(self.image, x, y, paint)
226 end
227 }
228end
reedf355df52014-10-12 12:18:40 -0700229
230function spawn_transition(prevSlide, nextSlide, is_forward)
231 local transition
232 if is_forward then
233 transition = prevSlide.transition
234 else
235 transition = nextSlide.transition
236 end
237
238 if not transition then
239 return
240 end
241
reed96affcd2014-10-13 12:38:04 -0700242 local rec = Sk.newPictureRecorder()
reedf355df52014-10-12 12:18:40 -0700243
reed96affcd2014-10-13 12:38:04 -0700244 drawSlide(rec:beginRecording(640, 480), prevSlide, gTemplate, gPaints)
245 local prevDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700246
reed96affcd2014-10-13 12:38:04 -0700247 drawSlide(rec:beginRecording(640, 480), nextSlide, gTemplate, gPaints)
248 local nextDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700249
reed96affcd2014-10-13 12:38:04 -0700250 gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
reedf355df52014-10-12 12:18:40 -0700251end
252
253--------------------------------------------------------------------------------------
254
reed09a1d672014-10-11 13:13:11 -0700255function spawn_rotate_animation()
256 gCurrAnimation = {
257 angle = 0,
258 angle_delta = 5,
259 pivot_x = 320,
260 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700261 proc = function (self, canvas, drawSlideProc)
262 if self.angle >= 360 then
263 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700264 return nil
265 end
reedf355df52014-10-12 12:18:40 -0700266 canvas:translate(self.pivot_x, self.pivot_y)
267 canvas:rotate(self.angle)
268 canvas:translate(-self.pivot_x, -self.pivot_y)
269 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700270
reedf355df52014-10-12 12:18:40 -0700271 self.angle = self.angle + self.angle_delta
272 return self
reed09a1d672014-10-11 13:13:11 -0700273 end
274 }
275end
276
277function spawn_scale_animation()
278 gCurrAnimation = {
279 scale = 1,
280 scale_delta = .95,
281 scale_limit = 0.2,
282 pivot_x = 320,
283 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700284 proc = function (self, canvas, drawSlideProc)
285 if self.scale < self.scale_limit then
286 self.scale = self.scale_limit
287 self.scale_delta = 1 / self.scale_delta
reed09a1d672014-10-11 13:13:11 -0700288 end
reedf355df52014-10-12 12:18:40 -0700289 if self.scale > 1 then
290 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700291 return nil
292 end
reedf355df52014-10-12 12:18:40 -0700293 canvas:translate(self.pivot_x, self.pivot_y)
294 canvas:scale(self.scale, self.scale)
295 canvas:translate(-self.pivot_x, -self.pivot_y)
296 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700297
reedf355df52014-10-12 12:18:40 -0700298 self.scale = self.scale * self.scale_delta
299 return self
reed09a1d672014-10-11 13:13:11 -0700300 end
301 }
302end
303
304function onDrawContent(canvas)
reedf355df52014-10-12 12:18:40 -0700305 local drawSlideProc = function(canvas)
306 drawSlide(canvas, gSlides[gSlideIndex], gTemplate, gPaints)
reed09a1d672014-10-11 13:13:11 -0700307 end
308
reed09a1d672014-10-11 13:13:11 -0700309 if gCurrAnimation then
reedf355df52014-10-12 12:18:40 -0700310 gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
reed09a1d672014-10-11 13:13:11 -0700311 return true
312 else
reedf355df52014-10-12 12:18:40 -0700313 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700314 return false
315 end
316end
317
318function onClickHandler(x, y)
319 return false
320end
321
322local keyProcs = {
323 n = next_slide,
324 p = prev_slide,
325 r = spawn_rotate_animation,
326 s = spawn_scale_animation,
327}
328
329function onCharHandler(uni)
330 local proc = keyProcs[uni]
331 if proc then
332 proc()
333 return true
334 end
335 return false
336end