Mercurial > MadButterfly
annotate src/mbaf/animated_menu.c @ 776:77b561bb7929
Implement new algorithm to calculate the origin of the SVG elemnts so that we can implement object resize without changing the position of the object.
However, the image does not work here since it does not use the transformation of the group.
author | wycc |
---|---|
date | Mon, 30 Aug 2010 08:56:44 +0800 |
parents | f43224bf3524 |
children | 586e50f82c1f |
rev | line source |
---|---|
318 | 1 #include <stdio.h> |
2 #include <mb.h> | |
3 #include <string.h> | |
325 | 4 //#include "menu.h" |
456
26c302b47de1
Change name of header files.
Thinker K.F. Li <thinker@branda.to>
parents:
455
diff
changeset
|
5 #include "mb_af.h" |
26c302b47de1
Change name of header files.
Thinker K.F. Li <thinker@branda.to>
parents:
455
diff
changeset
|
6 #include "mb_ani_menu.h" |
344 | 7 static void mb_animated_menu_update(mb_animated_menu_t *m); |
318 | 8 static void set_text(coord_t *g, char *text) |
9 { | |
10 geo_t *geo; | |
11 shape_t *shape; | |
12 | |
13 FOR_COORD_MEMBERS(g, geo) { | |
14 shape = geo_get_shape(geo); | |
15 if(shape->obj.obj_type == MBO_TEXT) { | |
16 sh_text_set_text(shape, text); | |
17 } | |
18 } | |
19 } | |
20 | |
21 static void mb_animated_menu_fillMenuContent(mb_animated_menu_t *m) | |
22 { | |
23 int i; | |
24 coord_t *textgroup; | |
25 coord_t *group; | |
26 coord_t *lightbar; | |
27 | |
28 // fill new item | |
29 for(i=0;i<8;i++) { | |
30 group = (coord_t *) m->objects[m->items[i]]; | |
31 if (i < m->max) | |
32 set_text(group, m->titles[m->top+i]); | |
33 else | |
34 set_text(group, ""); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
35 rdman_coord_changed(MBAF_RDMAN(m->app),group); |
318 | 36 } |
37 | |
38 | |
39 textgroup = (coord_t *) m->objects[m->items[i]]; | |
40 coord_hide(textgroup); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
41 rdman_coord_changed(MBAF_RDMAN(m->app),textgroup); |
318 | 42 |
43 lightbar = (coord_t *) m->lightbar; | |
44 group = (coord_t *) m->objects[m->cur]; | |
45 coord_y(lightbar) = coord_y(group); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
46 rdman_coord_changed(MBAF_RDMAN(m->app),lightbar); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
47 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 48 } |
49 | |
50 static void mb_animated_menu_complete(event_t *ev,void *arg) | |
51 { | |
52 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; | |
53 | |
54 m->ready++; | |
55 } | |
56 | |
57 static void mb_animated_menu_fillMenuContentUp(mb_animated_menu_t *m) | |
58 { | |
59 int i; | |
60 coord_t *textgroup; | |
61 coord_t *group; | |
62 coord_t *lightbar; | |
63 int tmp; | |
64 mb_timeval_t start, playing, now; | |
65 mb_progm_t *progm; | |
66 mb_word_t *word; | |
67 | |
68 | |
69 // fill new item | |
70 group = (coord_t *) m->objects[m->items[8]]; | |
71 set_text(group, m->titles[m->top]); | |
72 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
73 m->progm = progm = mb_progm_new(2, MBAF_RDMAN(m->app)); |
318 | 74 MB_TIMEVAL_SET(&start, 0, 0); |
75 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
76 word = mb_progm_next_word(progm, &start, &playing); | |
77 get_now(&now); | |
78 | |
79 for(i=0;i<7;i++) { | |
80 //shift to the next item | |
81 textgroup = (coord_t *) m->objects[m->items[i]]; | |
82 mb_shift_new(0,m->menus_y[i+1]-coord_y(textgroup), textgroup,word); | |
83 } | |
84 // fade out the item[7] | |
85 textgroup = (coord_t *) m->objects[m->items[7]]; | |
86 mb_shift_new(0,100, textgroup,word); | |
87 | |
88 // fade in the item[8] | |
89 textgroup = (coord_t *) m->objects[m->items[8]]; | |
90 group = (coord_t *) m->objects[m->items[0]]; | |
91 coord_y(textgroup) = m->menus_y[0]-100; | |
92 coord_show(textgroup); | |
93 mb_shift_new(0,100, textgroup,word); | |
94 | |
95 lightbar = (coord_t *) m->lightbar; | |
96 mb_shift_new(0,m->menus_y[m->cur]-coord_y(lightbar),lightbar,word); | |
97 | |
98 MB_TIMEVAL_SET(&start, 0, m->speed); | |
99 MB_TIMEVAL_SET(&playing, 0, 0); | |
100 word = mb_progm_next_word(progm, &start, &playing); | |
101 textgroup = (coord_t *) m->objects[m->items[7]]; | |
102 mb_visibility_new(VIS_HIDDEN, textgroup,word); | |
103 | |
104 mb_progm_free_completed(progm); | |
105 m->ready--; | |
106 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
107 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
108 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 109 tmp = m->items[8]; |
110 for(i=8;i>0;i--) { | |
111 m->items[i] = m->items[i-1]; | |
112 } | |
113 m->items[0] = tmp; | |
114 } | |
115 | |
116 | |
117 static void mb_animated_menu_fillMenuContentDown(mb_animated_menu_t *m) | |
118 { | |
119 int i; | |
120 int tmp; | |
121 mb_timeval_t start, playing, now; | |
122 mb_progm_t *progm; | |
123 mb_word_t *word; | |
124 | |
125 | |
126 // fill new item | |
127 set_text((coord_t *)m->objects[m->items[8]], m->titles[m->top+7]); | |
128 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
129 m->progm = progm = mb_progm_new(2, MBAF_RDMAN(m->app)); |
318 | 130 MB_TIMEVAL_SET(&start, 0, 0); |
131 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
132 word = mb_progm_next_word(progm, &start, &playing); | |
133 get_now(&now); | |
134 | |
135 for(i=1;i<8;i++) { | |
136 //shift to the next item | |
137 mb_shift_new(0,m->menus_y[i-1]-coord_y((coord_t *)m->objects[m->items[i]]), (coord_t *) m->objects[m->items[i]],word); | |
138 } | |
139 // fade out the item[0] | |
140 mb_shift_new(0,-100, (coord_t *)m->objects[m->items[0]],word); | |
141 | |
142 // fade in the item[8] | |
143 coord_y((coord_t *)m->objects[m->items[8]]) = m->menus_y[7]+100; | |
144 coord_show(((coord_t *)(m->objects[m->items[8]]))); | |
145 mb_shift_new(0,-100, (coord_t *)m->objects[m->items[8]],word); | |
146 | |
147 mb_shift_new(0,m->menus_y[m->cur]-coord_y((coord_t *)m->lightbar),((coord_t *)(m->lightbar)),word); | |
148 | |
149 MB_TIMEVAL_SET(&start, 0, m->speed); | |
150 MB_TIMEVAL_SET(&playing, 0, 0); | |
151 word = mb_progm_next_word(progm, &start, &playing); | |
152 mb_visibility_new(VIS_VISIBLE, (coord_t *) m->objects[m->items[0]],word); | |
153 | |
154 mb_progm_free_completed(progm); | |
155 m->ready--; | |
156 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
157 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
158 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 159 tmp = m->items[0]; |
160 for(i=0;i<8;i++) { | |
161 m->items[i] = m->items[i+1]; | |
162 } | |
163 m->items[8] = tmp; | |
164 } | |
165 | |
166 void mb_animated_menu_moveLightBar(mb_animated_menu_t *m) | |
167 { | |
168 mb_timeval_t start, playing, now; | |
169 mb_progm_t *progm; | |
170 mb_word_t *word; | |
171 coord_t *lightbar; | |
172 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
173 m->progm = progm = mb_progm_new(1, MBAF_RDMAN(m->app)); |
318 | 174 MB_TIMEVAL_SET(&start, 0, 0); |
175 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
176 word = mb_progm_next_word(progm, &start, &playing); | |
177 get_now(&now); | |
178 | |
179 lightbar = (coord_t *) m->lightbar; | |
180 mb_shift_new(0,m->menus_y[m->cur]-coord_y(lightbar),lightbar,word); | |
181 mb_progm_free_completed(progm); | |
182 m->ready--; | |
183 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
184 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
185 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 186 } |
187 | |
188 static void mb_animated_menu_up(mb_animated_menu_t *m) | |
189 { | |
190 if (m->cur > 5) { | |
191 m->cur--; | |
192 mb_animated_menu_moveLightBar(m); | |
344 | 193 mb_animated_menu_update(m); |
318 | 194 } else { |
195 if (m->top > 0) { | |
196 m->top--; | |
197 mb_animated_menu_fillMenuContentUp(m); | |
344 | 198 mb_animated_menu_update(m); |
318 | 199 } else { |
200 if (m->cur == 0) | |
201 return; | |
202 m->cur--; | |
203 mb_animated_menu_moveLightBar(m); | |
344 | 204 mb_animated_menu_update(m); |
318 | 205 } |
206 } | |
207 } | |
208 static void mb_animated_menu_down(mb_animated_menu_t *m) | |
209 { | |
210 | |
211 if (m->cur < 5) { | |
212 if (m->top+m->cur <= m->max) { | |
213 m->cur++; | |
214 mb_animated_menu_moveLightBar(m); | |
344 | 215 mb_animated_menu_update(m); |
318 | 216 } |
217 } else { | |
218 if ((m->top+8) < m->max-1) { | |
219 m->top++; | |
220 mb_animated_menu_fillMenuContentDown(m); | |
344 | 221 mb_animated_menu_update(m); |
318 | 222 } else { |
223 if (m->cur+m->top < m->max-1) { | |
224 m->cur++; | |
225 mb_animated_menu_moveLightBar(m); | |
344 | 226 mb_animated_menu_update(m); |
318 | 227 } else |
228 return; | |
229 } | |
230 } | |
231 } | |
232 | |
344 | 233 void mb_animated_menu_set_update_callback(mb_animated_menu_t *m, void (*f)(mb_animated_menu_t *m, int sel)) |
234 { | |
235 m->update_callback = f; | |
236 } | |
318 | 237 void mb_animated_menu_set_callback(mb_animated_menu_t *m, void (*f)(mb_animated_menu_t *m, int sel)) |
238 { | |
239 m->callback = f; | |
240 } | |
344 | 241 static void mb_animated_menu_update(mb_animated_menu_t *m) |
242 { | |
243 if (m->update_callback) | |
244 m->update_callback(m,m->top+m->cur); | |
245 | |
246 } | |
318 | 247 static void mb_animated_menu_select(mb_animated_menu_t *m) |
248 { | |
249 if (m->callback) | |
250 m->callback(m,m->top+m->cur); | |
251 } | |
252 | |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
253 // Send the pending key in the animation progm complete callback |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
254 static void mb_animated_menu_keyHandler(event_t *ev, void *arg); |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
255 static void mb_animated_menu_send_pending_key(event_t *ev,void *arg) |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
256 { |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
257 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
258 X_kb_event_t *xkey; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
259 |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
260 xkey = &m->pending_keys[m->pending_pos]; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
261 m->pending_pos = (m->pending_pos + 1) & 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
262 mb_animated_menu_keyHandler((event_t *) xkey, m); |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
263 } |
318 | 264 static void mb_animated_menu_keyHandler(event_t *ev, void *arg) |
265 { | |
266 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; | |
267 X_kb_event_t *xkey = (X_kb_event_t *)ev; | |
268 if(xkey->event.type != EVT_KB_PRESS) { | |
269 return; | |
270 } | |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
271 if (m->ready<=0) { |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
272 m->pending_keys[m->pending_last++] = *xkey; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
273 m->pending_last &= 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
274 if(m->pending_last == m->pending_pos) |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
275 m->pending_last = (m->pending_last - 1) & 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
276 else |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
277 subject_add_observer(mb_progm_get_complete(m->progm), |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
278 mb_animated_menu_send_pending_key, |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
279 m); |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
280 return; |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
281 } |
318 | 282 switch(xkey->sym) { |
283 case 0xff51: /* left */ | |
284 break; | |
285 | |
286 case 0xff52: /* up */ | |
287 mb_animated_menu_up(m); | |
288 break; | |
289 | |
290 case 0xff53: /* right */ | |
291 break; | |
292 | |
293 case 0xff54: /* down */ | |
294 mb_animated_menu_down(m); | |
295 break; | |
296 | |
297 case 0xff0d: /* enter */ | |
298 mb_animated_menu_select(m); | |
299 break; | |
300 default: | |
301 return; | |
302 } | |
303 } | |
304 | |
305 /** \brief Create an instace of animated menu. | |
306 * | |
307 * The objectnames is used to extract symbols from the SVG file. | |
308 * ${objectnames}0 - ${objectnames}8 is the text object. | |
309 * ${objectnames}_lightbar is the lightbar. | |
310 * | |
311 */ | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
312 mb_animated_menu_t *mb_animated_menu_new(mbaf_t *app,mb_sprite_t *sp,char *objnames,char *menus[]) |
318 | 313 { |
314 mb_animated_menu_t *m; | |
757
f43224bf3524
Remove unused variables and refactor to X_MB_init_with_win
Thinker K.F. Li <thinker@codemud.net>
parents:
456
diff
changeset
|
315 int i; |
318 | 316 char name[255]; |
317 mb_obj_t *l; | |
318 int ii; | |
319 | |
320 if (menus == NULL) | |
321 i=0; | |
322 else | |
323 for(i=0;menus[i];i++); | |
324 ii=9; | |
325 | |
326 m = (mb_animated_menu_t *) malloc(sizeof(mb_animated_menu_t)); | |
327 m->items = (int *) malloc(sizeof(int)*ii*2+sizeof(mb_obj_t *)*ii); | |
328 m->app = app; | |
329 m->sprite = sp; | |
330 m->top = 0; | |
331 m->cur = 0; | |
332 m->ready = 1; | |
333 m->max = i; | |
334 m->menus_y = (int *) (m->items+ii); | |
335 m->objects = (mb_obj_t **) (m->menus_y+ii); | |
336 m->callback = NULL; | |
344 | 337 m->update_callback = NULL; |
318 | 338 m->speed = 300000; |
339 for(i=0;i<9;i++) { | |
340 m->items[i] = i; | |
341 snprintf(name,sizeof(name),"%s%d", objnames, i+1); | |
342 l = MB_SPRITE_GET_OBJ(sp,name); | |
343 if (l == NULL) { | |
344 fprintf(stderr,"Can not find symbol %s\n",name); | |
345 } | |
346 m->objects[i] = (mb_obj_t *) l; | |
347 m->menus_y[i] = coord_y((coord_t*)l); | |
348 } | |
349 m->titles = menus; | |
350 snprintf(name,sizeof(name), "%s_lightbar", objnames); | |
351 m->lightbar = (mb_obj_t *) MB_SPRITE_GET_OBJ(sp,name); | |
352 if (m->lightbar==NULL) | |
353 fprintf(stderr,"Can not find object %s\n",name); | |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
354 m->pending_pos = m->pending_last = 0; |
318 | 355 mb_animated_menu_fillMenuContent(m); |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
356 subject_add_observer(MBAF_KB_SUBJECT(app), mb_animated_menu_keyHandler,m); |
318 | 357 return m; |
358 } | |
359 | |
360 void mb_animated_menu_set_titles(mb_animated_menu_t *m, char *menus[]) | |
361 { | |
362 int i; | |
363 for(i=0;menus[i];i++); | |
364 | |
365 m->max = i; | |
366 m->top = 0; | |
367 m->cur = 0; | |
368 m->titles = menus; | |
369 mb_animated_menu_fillMenuContent(m); | |
329
740844ee48c4
Update position of light-bar after update menu item
Thinker K.F. Li <thinker@branda.to>
parents:
328
diff
changeset
|
370 mb_animated_menu_moveLightBar(m); |
318 | 371 } |
372 | |
373 | |
374 void mb_animated_menu_set_speed(mb_animated_menu_t *m,int speed) | |
375 { | |
376 m->speed = speed*1000; | |
377 } | |
378 | |
379 int mb_animated_menu_get_speed(mb_animated_menu_t *m) | |
380 { | |
381 return m->speed/1000; | |
382 } |