blob: bae5206ac221e3e1406a5c8334df220cc4ec460a [file] [log] [blame]
reedd2e7dfb2014-10-13 19:43:17 -07001function tostr(t)
2 local str = ""
3 for k, v in next, t do
4 if #str > 0 then
5 str = str .. ", "
6 end
7 if type(k) == "number" then
8 str = str .. "[" .. k .. "] = "
9 else
10 str = str .. tostring(k) .. " = "
11 end
12 if type(v) == "table" then
13 str = str .. "{ " .. tostr(v) .. " }"
14 elseif type(v) == "string" then
15 str = str .. '"' .. v .. '"'
16 else
17 str = str .. tostring(v)
18 end
19 end
20 return str
21end
22
23
24function trim_ws(s)
25 return s:match("^%s*(.*)")
26end
27
28function count_hypens(s)
29 local leftover = s:match("^-*(.*)")
30 return string.len(s) - string.len(leftover)
31end
32
33function parse_file(file)
34 local slides = {}
35 local block = {}
36
37 for line in file:lines() do
38 local s = trim_ws(line)
39 if #s == 0 then -- done with a block
40 if #block > 0 then
41 slides[#slides + 1] = block
42 block = {}
43 end
44 else
45 local n = count_hypens(s)
46 block[#block + 1] = {
47 indent = n,
48 text = trim_ws(s:sub(n + 1, -1))
49 }
50 end
51 end
52 return slides
53end
54
55function pretty_print_slide(slide)
56 io.write("{\n")
57 for i = 1, #slide do
58 local node = slide[i]
59 for j = 0, node.indent do
60 io.write(" ")
61 end
62 io.write("{ ")
63 io.write(tostr(node))
64 io.write(" },\n")
65 end
66 io.write("},\n")
67end
68
69function pretty_print_slides(slides)
70 io.write("gSlides = {\n")
71 for i = 1, #slides do
72 pretty_print_slide(slides[i])
73 end
74 io.write("}\n")
75end
76
77gSlides = parse_file(io.open("/skia/trunk/resources/slides_content.lua", "r"))
reed18ea7772014-10-11 11:28:07 -070078
79function make_paint(size, color)
80 local paint = Sk.newPaint();
81 paint:setAntiAlias(true)
reed09a1d672014-10-11 13:13:11 -070082 paint:setSubpixelText(true)
reed18ea7772014-10-11 11:28:07 -070083 paint:setTextSize(size)
84 paint:setColor(color)
85 return paint
86end
87
reed18ea7772014-10-11 11:28:07 -070088function drawSlide(canvas, slide, template, paints)
reedd2e7dfb2014-10-13 19:43:17 -070089 local scale = 1.15
90 local y = 0
91 for i = 1, #slide do
92 local node = slide[i]
93 local temp = template[node.indent + 1]
94 local paint = paints[node.indent + 1]
95 local fm = paint:getFontMetrics()
96 y = y - fm.ascent * scale
97 canvas:drawText(node.text, temp.x, y, paint)
98 y = y + fm.descent * scale
reed18ea7772014-10-11 11:28:07 -070099 end
100end
101
reedf355df52014-10-12 12:18:40 -0700102function slide_transition(prev, next, is_forward)
103 local rec = {
104 proc = function(self, canvas, drawSlideProc)
105 if self:isDone() then
106 drawSlideProc(canvas)
107 return nil
108 end
reed96affcd2014-10-13 12:38:04 -0700109 self.prevDrawable:draw(canvas, self.curr_x, 0)
110 self.nextDrawable:draw(canvas, self.curr_x + 640, 0)
reedf355df52014-10-12 12:18:40 -0700111 self.curr_x = self.curr_x + self.step_x
112 return self
113 end
114 }
115 if is_forward then
reed96affcd2014-10-13 12:38:04 -0700116 rec.prevDrawable = prev
117 rec.nextDrawable = next
reedf355df52014-10-12 12:18:40 -0700118 rec.curr_x = 0
119 rec.step_x = -15
120 rec.isDone = function (self) return self.curr_x <= -640 end
121 else
reed96affcd2014-10-13 12:38:04 -0700122 rec.prevDrawable = next
123 rec.nextDrawable = prev
reedf355df52014-10-12 12:18:40 -0700124 rec.curr_x = -640
125 rec.step_x = 15
126 rec.isDone = function (self) return self.curr_x >= 0 end
127 end
128 return rec
129end
130
reed0d76b952014-10-12 19:05:52 -0700131function fade_slide_transition(prev, next, is_forward)
132 local rec = {
reed96affcd2014-10-13 12:38:04 -0700133 prevDrawable = prev,
134 nextDrawable = next,
reed0d76b952014-10-12 19:05:52 -0700135 proc = function(self, canvas, drawSlideProc)
136 if self:isDone() then
137 drawSlideProc(canvas)
138 return nil
139 end
reed96affcd2014-10-13 12:38:04 -0700140 self.prevDrawable:draw(canvas, self.prev_x, 0, self.prev_a)
141 self.nextDrawable:draw(canvas, self.next_x, 0, self.next_a)
reed0d76b952014-10-12 19:05:52 -0700142 self:step()
143 return self
144 end
145 }
146 if is_forward then
147 rec.prev_x = 0
148 rec.prev_a = 1
149 rec.next_x = 640
150 rec.next_a = 0
151 rec.isDone = function (self) return self.next_x <= 0 end
152 rec.step = function (self)
153 self.next_x = self.next_x - 20
154 self.next_a = (640 - self.next_x) / 640
155 self.prev_a = 1 - self.next_a
156 end
157 else
158 rec.prev_x = 0
159 rec.prev_a = 1
160 rec.next_x = 0
161 rec.next_a = 0
162 rec.isDone = function (self) return self.prev_x >= 640 end
163 rec.step = function (self)
164 self.prev_x = self.prev_x + 20
165 self.prev_a = (640 - self.prev_x) / 640
166 self.next_a = 1 - self.prev_a
167 end
168 end
169 return rec
170end
171
reed18ea7772014-10-11 11:28:07 -0700172--------------------------------------------------------------------------------------
173
174gTemplate = {
reedd2e7dfb2014-10-13 19:43:17 -0700175 { x = 10, textSize = 40, bullet = "" },
176 { x = 40, textSize = 30, bullet = "\xE2\x80\xA2" },
177 { x = 70, textSize = 20, bullet = "\xE2\x97\xA6" },
reed18ea7772014-10-11 11:28:07 -0700178}
179
reedd2e7dfb2014-10-13 19:43:17 -0700180gPaints = {
181 make_paint(gTemplate[1].textSize, { a=1, r=0, g=0, b=0 } ),
182 make_paint(gTemplate[2].textSize, { a=1, r=1, g=0, b=0 } ),
183 make_paint(gTemplate[3].textSize, { a=1, r=0, g=1, b=0 } ),
184}
reed18ea7772014-10-11 11:28:07 -0700185
186gRedPaint = Sk.newPaint()
187gRedPaint:setAntiAlias(true)
188gRedPaint:setColor{a=1, r=1, g=0, b=0 }
189
reed09a1d672014-10-11 13:13:11 -0700190-- animation.proc is passed the canvas before drawing.
191-- The animation.proc returns itself or another animation (which means keep animating)
192-- or it returns nil, which stops the animation.
193--
194local gCurrAnimation
195
reedf355df52014-10-12 12:18:40 -0700196gSlideIndex = 1
197
198function next_slide()
199 local prev = gSlides[gSlideIndex]
200
201 gSlideIndex = gSlideIndex + 1
202 if gSlideIndex > #gSlides then
203 gSlideIndex = 1
204 end
205
206 spawn_transition(prev, gSlides[gSlideIndex], true)
207end
208
209function prev_slide()
210 local prev = gSlides[gSlideIndex]
211
212 gSlideIndex = gSlideIndex - 1
213 if gSlideIndex < 1 then
214 gSlideIndex = #gSlides
215 end
216
217 spawn_transition(prev, gSlides[gSlideIndex], false)
218end
219
reed96affcd2014-10-13 12:38:04 -0700220function new_drawable_picture(pic)
221 return {
222 picture = pic,
223 width = pic:width(),
224 height = pic:height(),
225 draw = function (self, canvas, x, y, paint)
226 canvas:drawPicture(self.picture, x, y, paint)
227 end
228 }
229end
230
231function new_drawable_image(img)
232 return {
233 image = img,
234 width = img:width(),
235 height = img:height(),
236 draw = function (self, canvas, x, y, paint)
237 canvas:drawImage(self.image, x, y, paint)
238 end
239 }
240end
reedf355df52014-10-12 12:18:40 -0700241
242function spawn_transition(prevSlide, nextSlide, is_forward)
243 local transition
244 if is_forward then
245 transition = prevSlide.transition
246 else
247 transition = nextSlide.transition
248 end
249
250 if not transition then
reedd2e7dfb2014-10-13 19:43:17 -0700251 transition = fade_slide_transition
reedf355df52014-10-12 12:18:40 -0700252 end
253
reed96affcd2014-10-13 12:38:04 -0700254 local rec = Sk.newPictureRecorder()
reedf355df52014-10-12 12:18:40 -0700255
reed96affcd2014-10-13 12:38:04 -0700256 drawSlide(rec:beginRecording(640, 480), prevSlide, gTemplate, gPaints)
257 local prevDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700258
reed96affcd2014-10-13 12:38:04 -0700259 drawSlide(rec:beginRecording(640, 480), nextSlide, gTemplate, gPaints)
260 local nextDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700261
reed96affcd2014-10-13 12:38:04 -0700262 gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
reedf355df52014-10-12 12:18:40 -0700263end
264
265--------------------------------------------------------------------------------------
266
reed09a1d672014-10-11 13:13:11 -0700267function spawn_rotate_animation()
268 gCurrAnimation = {
269 angle = 0,
270 angle_delta = 5,
271 pivot_x = 320,
272 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700273 proc = function (self, canvas, drawSlideProc)
274 if self.angle >= 360 then
275 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700276 return nil
277 end
reedf355df52014-10-12 12:18:40 -0700278 canvas:translate(self.pivot_x, self.pivot_y)
279 canvas:rotate(self.angle)
280 canvas:translate(-self.pivot_x, -self.pivot_y)
281 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700282
reedf355df52014-10-12 12:18:40 -0700283 self.angle = self.angle + self.angle_delta
284 return self
reed09a1d672014-10-11 13:13:11 -0700285 end
286 }
287end
288
289function spawn_scale_animation()
290 gCurrAnimation = {
291 scale = 1,
292 scale_delta = .95,
293 scale_limit = 0.2,
294 pivot_x = 320,
295 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700296 proc = function (self, canvas, drawSlideProc)
297 if self.scale < self.scale_limit then
298 self.scale = self.scale_limit
299 self.scale_delta = 1 / self.scale_delta
reed09a1d672014-10-11 13:13:11 -0700300 end
reedf355df52014-10-12 12:18:40 -0700301 if self.scale > 1 then
302 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700303 return nil
304 end
reedf355df52014-10-12 12:18:40 -0700305 canvas:translate(self.pivot_x, self.pivot_y)
306 canvas:scale(self.scale, self.scale)
307 canvas:translate(-self.pivot_x, -self.pivot_y)
308 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700309
reedf355df52014-10-12 12:18:40 -0700310 self.scale = self.scale * self.scale_delta
311 return self
reed09a1d672014-10-11 13:13:11 -0700312 end
313 }
314end
315
316function onDrawContent(canvas)
reedf355df52014-10-12 12:18:40 -0700317 local drawSlideProc = function(canvas)
318 drawSlide(canvas, gSlides[gSlideIndex], gTemplate, gPaints)
reed09a1d672014-10-11 13:13:11 -0700319 end
320
reed09a1d672014-10-11 13:13:11 -0700321 if gCurrAnimation then
reedf355df52014-10-12 12:18:40 -0700322 gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
reed09a1d672014-10-11 13:13:11 -0700323 return true
324 else
reedf355df52014-10-12 12:18:40 -0700325 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700326 return false
327 end
328end
329
330function onClickHandler(x, y)
331 return false
332end
333
334local keyProcs = {
335 n = next_slide,
336 p = prev_slide,
337 r = spawn_rotate_animation,
338 s = spawn_scale_animation,
339}
340
341function onCharHandler(uni)
342 local proc = keyProcs[uni]
343 if proc then
344 proc()
345 return true
346 end
347 return false
348end