1 #include <Elementary.h>
3 #include "elm_widget_player.h"
9 EAPI const char ELM_PLAYER_SMART_NAME[] = "elm_player";
11 static const char SIG_FORWARD_CLICKED[] = "forward,clicked";
12 static const char SIG_INFO_CLICKED[] = "info,clicked";
13 static const char SIG_NEXT_CLICKED[] = "next,clicked";
14 static const char SIG_PAUSE_CLICKED[] = "pause,clicked";
15 static const char SIG_PLAY_CLICKED[] = "play,clicked";
16 static const char SIG_PREV_CLICKED[] = "prev,clicked";
17 static const char SIG_REWIND_CLICKED[] = "rewind,clicked";
18 static const char SIG_STOP_CLICKED[] = "stop,clicked";
19 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
20 { SIG_FORWARD_CLICKED, "" },
21 { SIG_INFO_CLICKED, "" },
22 { SIG_NEXT_CLICKED, "" },
23 { SIG_PAUSE_CLICKED, "" },
24 { SIG_PLAY_CLICKED, "" },
25 { SIG_PREV_CLICKED, "" },
26 { SIG_REWIND_CLICKED, "" },
27 { SIG_STOP_CLICKED, "" },
31 EVAS_SMART_SUBCLASS_NEW
32 (ELM_PLAYER_SMART_NAME, _elm_player, Elm_Player_Smart_Class,
33 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
37 _elm_player_smart_event(Evas_Object *obj,
38 Evas_Object *src __UNUSED__,
39 Evas_Callback_Type type,
42 Evas_Event_Key_Down *ev = event_info;
44 ELM_PLAYER_DATA_GET(obj, sd);
46 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
47 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
48 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
49 if (!sd->video) return EINA_FALSE;
51 if ((!strcmp(ev->keyname, "Left")) ||
52 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
56 current = elm_video_play_position_get(sd->video);
57 last = elm_video_play_length_get(sd->video);
61 current -= last / 100;
62 elm_video_play_position_set(sd->video, current);
65 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
68 if ((!strcmp(ev->keyname, "Right")) ||
69 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
73 current = elm_video_play_position_get(sd->video);
74 last = elm_video_play_length_get(sd->video);
78 current += last / 100;
79 if (current < 0) current = 0;
80 elm_video_play_position_set(sd->video, current);
83 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
86 if (!strcmp(ev->keyname, "space"))
88 if (elm_video_is_playing_get(sd->video))
89 elm_video_pause(sd->video);
91 elm_video_play(sd->video);
92 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
95 fprintf(stderr, "keyname: '%s' not handle\n", ev->keyname);
101 _elm_player_smart_theme(Evas_Object *obj)
103 ELM_PLAYER_DATA_GET(obj, sd);
105 if (!ELM_WIDGET_CLASS(_elm_player_parent_sc)->theme(obj)) return EINA_FALSE;
107 #define UPDATE_THEME(Target, Name) \
110 elm_object_style_set(Target, elm_widget_style_get(obj)); \
111 if (!elm_layout_content_set(obj, Name, Target)) \
112 evas_object_hide(Target); \
113 elm_object_disabled_set(Target, elm_widget_disabled_get(obj)); \
116 UPDATE_THEME(sd->forward, "media_player/forward");
117 UPDATE_THEME(sd->info, "media_player/info");
118 UPDATE_THEME(sd->next, "media_player/next");
119 UPDATE_THEME(sd->pause, "media_player/pause");
120 UPDATE_THEME(sd->play, "media_player/play");
121 UPDATE_THEME(sd->prev, "media_player/prev");
122 UPDATE_THEME(sd->rewind, "media_player/rewind");
123 UPDATE_THEME(sd->next, "media_player/next");
124 UPDATE_THEME(sd->slider, "media_player/slider");
126 elm_layout_sizing_eval(obj);
132 _elm_player_smart_sizing_eval(Evas_Object *obj)
136 ELM_PLAYER_DATA_GET(obj, sd);
138 edje_object_size_min_get(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h);
139 edje_object_size_min_restricted_calc
140 (ELM_WIDGET_DATA(sd)->resize_obj, &w, &h, w, h);
141 evas_object_size_hint_min_set(obj, w, h);
145 _update_slider(void *data,
146 Evas_Object *obj __UNUSED__,
147 void *event_info __UNUSED__)
152 ELM_PLAYER_DATA_GET(data, sd);
154 seekable = elm_video_is_seekable_get(sd->video);
155 length = elm_video_play_length_get(sd->video);
156 pos = elm_video_play_position_get(sd->video);
158 elm_object_disabled_set(sd->slider, !seekable);
159 elm_slider_min_max_set(sd->slider, 0, length);
160 elm_slider_value_set(sd->slider, pos);
164 _update_position(void *data,
165 Evas_Object *obj __UNUSED__,
166 void *event_info __UNUSED__)
168 ELM_PLAYER_DATA_GET(data, sd);
170 elm_video_play_position_set(sd->video, elm_slider_value_get(sd->slider));
175 Evas_Object *obj __UNUSED__,
176 void *event_info __UNUSED__)
180 ELM_PLAYER_DATA_GET(data, sd);
182 pos = elm_video_play_position_get(sd->video);
183 length = elm_video_play_length_get(sd->video);
186 elm_video_play_position_set(sd->video, pos);
188 elm_layout_signal_emit(data, "elm,button,forward", "elm");
189 evas_object_smart_callback_call(data, SIG_FORWARD_CLICKED, NULL);
194 Evas_Object *obj __UNUSED__,
195 void *event_info __UNUSED__)
197 elm_layout_signal_emit(data, "elm,button,info", "elm");
198 evas_object_smart_callback_call(data, SIG_INFO_CLICKED, NULL);
203 Evas_Object *obj __UNUSED__,
204 void *event_info __UNUSED__)
208 ELM_PLAYER_DATA_GET(data, sd);
210 pos = elm_video_play_position_get(sd->video);
211 length = elm_video_play_length_get(sd->video);
214 elm_video_play_position_set(sd->video, pos);
216 elm_layout_signal_emit(data, "elm,button,next", "elm");
217 evas_object_smart_callback_call(data, SIG_NEXT_CLICKED, NULL);
222 Evas_Object *obj __UNUSED__,
223 void *event_info __UNUSED__)
225 ELM_PLAYER_DATA_GET(data, sd);
227 elm_layout_signal_emit(data, "elm,player,pause", "elm");
228 elm_video_pause(sd->video);
230 elm_layout_signal_emit(data, "elm,button,pause", "elm");
231 evas_object_smart_callback_call(data, SIG_PAUSE_CLICKED, NULL);
236 Evas_Object *obj __UNUSED__,
237 void *event_info __UNUSED__)
239 ELM_PLAYER_DATA_GET(data, sd);
241 elm_video_play(sd->video);
242 elm_layout_signal_emit(data, "elm,button,play", "elm");
243 evas_object_smart_callback_call(data, SIG_PLAY_CLICKED, NULL);
248 Evas_Object *obj __UNUSED__,
249 void *event_info __UNUSED__)
253 ELM_PLAYER_DATA_GET(data, sd);
255 pos = elm_video_play_position_get(sd->video);
256 length = elm_video_play_length_get(sd->video);
259 elm_video_play_position_set(sd->video, pos);
260 evas_object_smart_callback_call(data, SIG_PREV_CLICKED, NULL);
261 elm_layout_signal_emit(data, "elm,button,prev", "elm");
266 Evas_Object *obj __UNUSED__,
267 void *event_info __UNUSED__)
269 ELM_PLAYER_DATA_GET(data, sd);
271 elm_video_play_position_set(sd->video, 0);
272 elm_layout_signal_emit(data, "elm,button,rewind", "elm");
273 evas_object_smart_callback_call(data, SIG_REWIND_CLICKED, NULL);
278 Evas_Object *obj __UNUSED__,
279 void *event_info __UNUSED__)
281 elm_layout_signal_emit(data, "elm,button,stop", "elm");
282 evas_object_smart_callback_call(data, SIG_STOP_CLICKED, NULL);
286 _play_started(void *data,
287 Evas_Object *obj __UNUSED__,
288 void *event_info __UNUSED__)
290 elm_layout_signal_emit(data, "elm,player,play", "elm");
294 _play_finished(void *data,
295 Evas_Object *obj __UNUSED__,
296 void *event_info __UNUSED__)
298 elm_layout_signal_emit(data, "elm,player,pause", "elm");
302 _on_video_del(Elm_Player_Smart_Data *sd)
304 elm_object_disabled_set(sd->slider, EINA_TRUE);
305 elm_object_disabled_set(sd->forward, EINA_TRUE);
306 elm_object_disabled_set(sd->info, EINA_TRUE);
307 elm_object_disabled_set(sd->next, EINA_TRUE);
308 elm_object_disabled_set(sd->pause, EINA_TRUE);
309 elm_object_disabled_set(sd->play, EINA_TRUE);
310 elm_object_disabled_set(sd->prev, EINA_TRUE);
311 elm_object_disabled_set(sd->rewind, EINA_TRUE);
312 elm_object_disabled_set(sd->next, EINA_TRUE);
319 _video_del(void *data,
321 Evas_Object *obj __UNUSED__,
322 void *event_info __UNUSED__)
328 _player_button_add(Evas_Object *obj,
335 ic = elm_icon_add(obj);
336 elm_icon_standard_set(ic, name);
337 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
339 bt = elm_button_add(obj);
340 elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
341 elm_object_part_content_set(bt, "icon", ic);
342 evas_object_size_hint_align_set(bt, 0.0, 0.0);
343 elm_object_style_set(bt, "anchor");
344 evas_object_smart_callback_add(bt, "clicked", func, obj);
346 if (!elm_layout_content_set(obj, name, bt))
348 elm_widget_sub_object_add(obj, bt);
349 evas_object_hide(bt);
356 _double_to_time(double value)
362 pm = value / 60 - (ph * 60);
363 ps = value - (pm * 60);
364 pf = value * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100);
367 snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i",
370 snprintf(buf, sizeof(buf), "%02i:%02i.%02i",
373 snprintf(buf, sizeof(buf), "%02i.%02i",
376 return (char *)eina_stringshare_add(buf);
380 _str_free(char *data)
382 eina_stringshare_del(data);
385 /* a video object is never parented by a player one, just tracked.
386 * treating this special case here and delegating other objects to own
389 _elm_player_smart_content_set(Evas_Object *obj,
391 Evas_Object *content)
396 if (part && strcmp(part, "video"))
397 return ELM_CONTAINER_CLASS(_elm_player_parent_sc)->content_set
398 (obj, part, content);
400 ELM_PLAYER_DATA_GET(obj, sd);
402 if (!_elm_video_check(content)) return EINA_FALSE;
403 if (sd->video == content) return EINA_TRUE;
405 if (sd->video) evas_object_del(sd->video);
409 if (!content) return EINA_TRUE;
411 elm_object_disabled_set(sd->slider, EINA_FALSE);
412 elm_object_disabled_set(sd->forward, EINA_FALSE);
413 elm_object_disabled_set(sd->info, EINA_FALSE);
414 elm_object_disabled_set(sd->next, EINA_FALSE);
415 elm_object_disabled_set(sd->pause, EINA_FALSE);
416 elm_object_disabled_set(sd->play, EINA_FALSE);
417 elm_object_disabled_set(sd->prev, EINA_FALSE);
418 elm_object_disabled_set(sd->rewind, EINA_FALSE);
419 elm_object_disabled_set(sd->next, EINA_FALSE);
421 sd->emotion = elm_video_emotion_get(sd->video);
422 emotion_object_priority_set(sd->emotion, EINA_TRUE);
423 evas_object_event_callback_add
424 (sd->video, EVAS_CALLBACK_DEL, _video_del, sd);
426 seekable = elm_video_is_seekable_get(sd->video);
427 length = elm_video_play_length_get(sd->video);
428 pos = elm_video_play_position_get(sd->video);
430 elm_object_disabled_set(sd->slider, !seekable);
431 elm_slider_min_max_set(sd->slider, 0, length);
432 elm_slider_value_set(sd->slider, pos);
434 if (elm_video_is_playing_get(sd->video))
435 elm_layout_signal_emit(obj, "elm,player,play", "elm");
436 else elm_layout_signal_emit(obj, "elm,player,pause", "elm");
438 evas_object_smart_callback_add(sd->emotion, "frame_decode",
439 _update_slider, obj);
440 evas_object_smart_callback_add(sd->emotion, "frame_resize",
441 _update_slider, obj);
442 evas_object_smart_callback_add(sd->emotion, "length_change",
443 _update_slider, obj);
444 evas_object_smart_callback_add(sd->emotion, "position_update",
445 _update_slider, obj);
446 evas_object_smart_callback_add(sd->emotion, "playback_started",
448 evas_object_smart_callback_add(sd->emotion, "playback_finished",
449 _play_finished, obj);
451 /* FIXME: track info from video */
457 _elm_player_smart_add(Evas_Object *obj)
459 EVAS_SMART_DATA_ALLOC(obj, Elm_Player_Smart_Data);
461 ELM_WIDGET_CLASS(_elm_player_parent_sc)->base.add(obj);
463 elm_layout_theme_set(obj, "player", "base", elm_widget_style_get(obj));
465 priv->forward = _player_button_add(obj, "media_player/forward", _forward);
466 priv->info = _player_button_add(obj, "media_player/info", _info);
467 priv->next = _player_button_add(obj, "media_player/next", _next);
468 priv->pause = _player_button_add(obj, "media_player/pause", _pause);
469 priv->play = _player_button_add(obj, "media_player/play", _play);
470 priv->prev = _player_button_add(obj, "media_player/prev", _prev);
471 priv->rewind = _player_button_add(obj, "media_player/rewind", _rewind);
472 priv->stop = _player_button_add(obj, "media_player/stop", _stop);
474 priv->slider = elm_slider_add(obj);
475 elm_slider_indicator_format_function_set
476 (priv->slider, _double_to_time, _str_free);
477 elm_slider_units_format_function_set
478 (priv->slider, _double_to_time, _str_free);
479 elm_slider_min_max_set(priv->slider, 0, 0);
480 elm_slider_value_set(priv->slider, 0);
481 elm_object_disabled_set(priv->slider, EINA_TRUE);
482 evas_object_size_hint_align_set(priv->slider, EVAS_HINT_FILL, 0.5);
483 evas_object_size_hint_weight_set
484 (priv->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
486 elm_layout_content_set(obj, "media_player/slider", priv->slider);
487 evas_object_smart_callback_add
488 (priv->slider, "changed", _update_position, obj);
490 elm_layout_sizing_eval(obj);
491 elm_widget_can_focus_set(obj, EINA_TRUE);
497 _elm_player_smart_set_user(Elm_Player_Smart_Class *sc)
500 ELM_WIDGET_CLASS(sc)->base.add = _elm_player_smart_add;
502 ELM_WIDGET_CLASS(sc)->event = _elm_player_smart_event;
503 ELM_WIDGET_CLASS(sc)->theme = _elm_player_smart_theme;
505 ELM_CONTAINER_CLASS(sc)->content_set = _elm_player_smart_content_set;
507 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_player_smart_sizing_eval;
513 EAPI const Elm_Player_Smart_Class *
514 elm_player_smart_class_get(void)
516 static Elm_Player_Smart_Class _sc =
517 ELM_PLAYER_SMART_CLASS_INIT_NAME_VERSION(ELM_PLAYER_SMART_NAME);
518 static const Elm_Player_Smart_Class *class = NULL;
519 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
524 _elm_player_smart_set(&_sc);
525 esc->callbacks = _smart_callbacks;
532 elm_player_add(Evas_Object *parent)
537 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
539 obj = elm_widget_add(_elm_player_smart_class_new(), parent);
540 if (!obj) return NULL;
542 if (!elm_widget_sub_object_add(parent, obj))
543 ERR("could not add %p as sub object of %p", obj, parent);
548 (void) _elm_player_smart_class_new;