2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <AppCommon.h>
21 #include "song_info.h"
22 #include "music-controller.h"
23 #include "common-ui.h"
24 #include "PlaySettingCtxPopup.h"
25 #include "ErrorPopupWindow.h"
27 #include "PlaybackController.h"
29 #define TOTAL_CONTROL_BTNS 6
30 #define TOTAL_EDIT_BTNS 3
31 #define LP_INTERVAL 0.5 /* seconds */
32 #define WAIT_INTERVAL 0.5 /* seconds */
33 #define LP_CHANGE 10000 /* milli seconds */
38 EO_DELETE, // TOTAL_EDIT_BTNS
45 EO_BTN_FORWARD, // TOTAL_CONTROL_BTNS
72 struct SPlaybackController {
74 CPlaySettingCtxPopup *eoCtxPopup;
75 CErrorPopupWindow *eoErrPopup;
76 Evas_Object *eoPressedObj;
78 Evas_Object *eoBtnControl[TOTAL_CONTROL_BTNS];
79 Evas_Object *eoBtnEdit[TOTAL_EDIT_BTNS];
82 Ecore_Timer *etLongPress;
84 CMusicController controller;
85 EPressTypes press_status;
87 CPlaybackController::SCallback cb;
92 SPlaybackController() {
93 memset(this, 0, sizeof(SPlaybackController));
98 void CPlaybackController::sm_CbCtxPopupBtnSelected(void* cookie, CContextPopup* instance, const char* text)
100 CPlaybackController *root = (CPlaybackController *)cookie;
102 root->m_OnCtxPopupBtnSelected(instance, text);
106 void CPlaybackController::m_OnCtxPopupBtnSelected(CContextPopup* instance, const char* text)
108 int type = CInfo::PlaybackSettingType();
112 m->controller.ChangePlayerMode(MODE_PLAYLIST_EDIT);
116 m->controller.Stop();
117 m->controller.EmptyPlaylist();
126 void CPlaybackController::sm_CbErrorPopupBtnSelected(void* cookie, CMessagePopup *instance)
128 CPlaybackController *root = (CPlaybackController *)cookie;
130 root->m_OnErrorPopupBtnSelected(instance);
134 void CPlaybackController::m_OnErrorPopupBtnSelected(CMessagePopup *instance)
136 m_DestroyErrorPopup();
137 elm_object_focus_set(m->eoBtnControl[CTRL_BTN_PLAY], EINA_TRUE);
141 Eina_Bool CPlaybackController::sm_CbWaitTimer(void *dt)
143 CPlaybackController *root = (CPlaybackController *)dt;
145 root->m_OnWaitTimer();
147 return ECORE_CALLBACK_CANCEL;
151 void CPlaybackController::m_OnWaitTimer(void)
153 m->press_status = PRESS_LONG;
154 if (m->controller.PlayState() == PLAY_STATUS_PLAY) {
155 /* Handle long press */
156 m->controller.Pause();
157 m->etLongPress = ecore_timer_add(LP_INTERVAL, sm_CbLongpressTimer, this);
160 m->press_status = PRESS_LONG_PAUSE;
167 Eina_Bool CPlaybackController::sm_CbLongpressTimer(void *dt)
169 CPlaybackController *root = (CPlaybackController *)dt;
171 root->m_OnLongpressTimer();
173 return ECORE_CALLBACK_RENEW;
177 void CPlaybackController::m_OnLongpressTimer(void)
179 m_HandleOnRepeated();
183 void CPlaybackController::m_AddControlButtons(void)
185 Evas_Object *box = NULL;
187 SBtnInfo btninfo[TOTAL_CONTROL_BTNS];
189 btninfo[CTRL_BTN_SETTINGS].txt = MUSIC_STYLE_BTN_SETTINGS;
190 btninfo[CTRL_BTN_SETTINGS].type = EO_BTN_SETTINGS;
192 btninfo[CTRL_BTN_SHUFFLE].txt = MUSIC_STYLE_BTN_SHUFFLE;
193 btninfo[CTRL_BTN_SHUFFLE].type = EO_BTN_SHUFFLE;
195 btninfo[CTRL_BTN_REPEAT].txt = MUSIC_STYLE_BTN_REPEAT;
196 btninfo[CTRL_BTN_REPEAT].type = EO_BTN_REPEAT;
198 btninfo[CTRL_BTN_REWIND].txt = MUSIC_STYLE_BTN_REWIND;
199 btninfo[CTRL_BTN_REWIND].type = EO_BTN_REWIND;
201 btninfo[CTRL_BTN_PLAY].txt = MUSIC_STYLE_BTN_PLAY;
202 btninfo[CTRL_BTN_PLAY].type = EO_BTN_PLAY;
204 btninfo[CTRL_BTN_FORWARD].txt = MUSIC_STYLE_BTN_FORWARD;
205 btninfo[CTRL_BTN_FORWARD].type = EO_BTN_FORWARD;
207 box = elm_box_add(m->eoBase);
211 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0);
212 evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0);
213 elm_box_horizontal_set(box, EINA_TRUE);
214 elm_box_padding_set(box,
215 MUSIC_CONTROL_BTNS_PADDING * elm_config_scale_get(), 0);
217 for (i = 0; i < TOTAL_CONTROL_BTNS; i++) {
218 m->eoBtnControl[i] = elm_button_add(m->eoBase);
219 if (!m->eoBtnControl[i])
222 elm_object_style_set(m->eoBtnControl[i], btninfo[i].txt);
223 evas_object_size_hint_weight_set(m->eoBtnControl[i],
224 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
225 elm_box_pack_end(box, m->eoBtnControl[i]);
227 if (i == CTRL_BTN_REWIND || i == CTRL_BTN_FORWARD) {
228 Connect(m->eoBtnControl[i], btninfo[i].type, TYPE_PRESSED | TYPE_UNPRESSED | TYPE_MOUSE_MOVE);
231 Connect(m->eoBtnControl[i], btninfo[i].type, TYPE_CLICKED | TYPE_MOUSE_MOVE);
233 evas_object_show(m->eoBtnControl[i]);
236 elm_object_part_content_set(m->eoBase, MUSIC_PART_CONTROLBTNS, box);
240 void CPlaybackController::m_AddEditPlaylistButtons(void)
242 Evas_Object *box = NULL;
244 SBtnInfo btninfo[TOTAL_EDIT_BTNS];
246 btninfo[EDIT_BTN_CANCEL].txt = MUSIC_TEXT_CANCEL;
247 btninfo[EDIT_BTN_CANCEL].type = EO_CANCEL;
249 btninfo[EDIT_BTN_DESELECT].txt = MUSIC_TEXT_DESELECT;
250 btninfo[EDIT_BTN_DESELECT].type = EO_DESELECT;
252 btninfo[EDIT_BTN_DELETE].txt = MUSIC_TEXT_DELETE;
253 btninfo[EDIT_BTN_DELETE].type = EO_DELETE;
255 box = CCommonUI::AddBox(m->eoBase);
259 elm_box_horizontal_set(box, EINA_TRUE);
260 elm_box_padding_set(box, MUSIC_EDIT_BTNS_PADDING * elm_config_scale_get(), 0);
262 for (i = 0; i < TOTAL_EDIT_BTNS; i++) {
263 m->eoBtnEdit[i] = elm_button_add(m->eoBase);
264 if (!m->eoBtnEdit[i])
267 elm_object_style_set(m->eoBtnEdit[i], MUSIC_STYLE_EDIT_BTN);
268 evas_object_size_hint_weight_set(m->eoBtnEdit[i], EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
269 elm_box_pack_end(box, m->eoBtnEdit[i]);
270 elm_object_text_set(m->eoBtnEdit[i], _(btninfo[i].txt));
272 Connect(m->eoBtnEdit[i], btninfo[i].type, TYPE_CLICKED | TYPE_MOUSE_MOVE);
274 evas_object_show(m->eoBtnEdit[i]);
276 elm_object_part_content_set(m->eoBase, MUSIC_PART_EDITBTNS, box);
277 elm_object_signal_emit(m->eoBase, MUSIC_SIGNAL_PLAYBACK_MODE, MUSIC_PLAYBACK_VIEW);
281 void CPlaybackController::m_UpdateForEmptySong(void)
283 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
284 MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
285 elm_object_focus_set(m->eoBtnControl[CTRL_BTN_SETTINGS], EINA_TRUE);
286 elm_object_focus_next_object_set(m->eoBtnControl[CTRL_BTN_REPEAT],
287 m->eoBtnControl[CTRL_BTN_REPEAT], ELM_FOCUS_RIGHT);
288 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_TRUE);
289 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_TRUE);
290 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_PLAY], EINA_TRUE);
294 void CPlaybackController::m_CreateErrorPopup(void)
296 CMessagePopup::SCallback cb;
298 cb.onBtn1Pressed = sm_CbErrorPopupBtnSelected;
300 m->eoErrPopup = new CErrorPopupWindow;
301 m->eoErrPopup->Create(m->eoBase, &cb, MUSIC_TEXT_PLAYBACK_ERROR);
308 void CPlaybackController::m_DestroyErrorPopup(void)
313 if (m->eoErrPopup->FlagCreate())
314 m->eoErrPopup->Destroy();
316 delete m->eoErrPopup;
317 m->eoErrPopup = NULL;
321 void CPlaybackController::m_CreateSettingsPopup(void)
323 CContextPopup::SCallback cb;
325 cb.onSelected = sm_CbCtxPopupBtnSelected;
327 m->eoCtxPopup = new CPlaySettingCtxPopup;
328 m->eoCtxPopup->Create(m->eoBase, &cb);
332 void CPlaybackController::m_DestroySettingsPopup(void)
337 if (m->eoCtxPopup->FlagCreate())
338 m->eoCtxPopup->Destroy();
340 delete m->eoCtxPopup;
341 m->eoCtxPopup = NULL;
345 void CPlaybackController::m_HandleForwardBtnClicked(Evas_Object *obj)
347 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED,
348 MUSIC_PLAYBACK_VIEW);
350 if (m->controller.PlayState() == PLAY_STATUS_STOP)
353 if (!m->controller.PlayNextSong()) {
354 _ERR(" music play next song failed ");
360 void CPlaybackController::m_HandleRewindBtnClicked(Evas_Object *obj)
362 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED,
363 MUSIC_PLAYBACK_VIEW);
365 if (m->controller.PlayState() == PLAY_STATUS_STOP)
368 if (!m->controller.PlayPreviousSong()) {
369 _ERR(" music play previous song failed ");
375 void CPlaybackController::m_HandleOnRepeated(void)
377 Evas_Object *obj = NULL;
379 char *timestr = NULL;
381 if (!m->eoPressedObj)
384 obj = m->eoPressedObj;
387 m->controller.GetPosition(&value);
389 if (obj == m->eoBtnControl[CTRL_BTN_REWIND]) {
391 m_RemoveTimer(TIMER_LONGPRESS);
394 value = value - LP_CHANGE;
399 if (value == m->duration) {
400 m->controller.PlayNextSong();
402 m->press_status = PRESS_LONG_PAUSE;
403 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY], MUSIC_SIGNAL_PAUSE,
404 MUSIC_PLAYBACK_VIEW);
405 m->controller.Pause();
406 m_RemoveTimer(TIMER_LONGPRESS);
410 value = value + LP_CHANGE;
411 if (value >= m->duration)
415 m->controller.SetPosition(value);
416 timestr = CCommonUI::TimeStrFromMilSeconds(value);
418 elm_object_part_text_set(m->eoBase, MUSIC_PART_PROGRESSTIME,
427 void CPlaybackController::m_RemoveTimer(int timer_code)
429 ETimers timerCode = (ETimers)timer_code;
434 ecore_timer_del(m->etWait);
439 case TIMER_LONGPRESS:
440 if (m->etLongPress) {
441 ecore_timer_del(m->etLongPress);
442 m->etLongPress = NULL;
447 _ERR(" invalid value ");
453 void CPlaybackController::m_HandleOnPressed(Evas_Object *obj)
455 m->press_status = PRESS_SHORT;
456 m->eoPressedObj = obj;
458 m->etWait = ecore_timer_add(WAIT_INTERVAL, sm_CbWaitTimer, this);
462 void CPlaybackController::m_HandleOnUnpressed(Evas_Object *obj)
464 m_RemoveTimer(TIMER_WAIT);
465 m_RemoveTimer(TIMER_LONGPRESS);
467 if (m->press_status == PRESS_SHORT) {
468 /* Handle song change */
469 if (m->controller.PlayState() == PLAY_STATUS_PLAY)
470 m->controller.Pause();
472 if (obj == m->eoBtnControl[CTRL_BTN_FORWARD])
473 m_HandleForwardBtnClicked(obj);
475 m_HandleRewindBtnClicked(obj);
477 if (m->controller.PlayState() != PLAY_STATUS_PLAY)
478 m->controller.Resume();
480 else if (m->press_status == PRESS_LONG) {
481 if (m->controller.PlayState() != PLAY_STATUS_PLAY)
482 m->controller.Resume();
485 m->press_status = PRESS_SHORT;
489 void CPlaybackController::m_UpdateSongInfo(void)
491 CSongInfo *sinfo = NULL;
494 if (!m->controller.GetCurrentSongIndex(&index)) {
495 _ERR(" music get current song index failed ");
499 if (!m->controller.GetSonginfoFromIndex(index, &sinfo)) {
500 _ERR(" music get songinfo failed ");
503 m->pSongInfo = sinfo;
507 void CPlaybackController::m_Update(void)
511 state = m->controller.PlayState();
513 case PLAY_STATUS_INITIAL:
514 // Initial State, Do nothing
517 case PLAY_STATUS_STOP:
519 elm_object_focus_set(m->eoBtnControl[CTRL_BTN_PLAY], EINA_TRUE);
520 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_TRUE);
521 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_TRUE);
524 case PLAY_STATUS_PLAY:
525 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_FALSE);
526 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_FALSE);
527 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
528 MUSIC_SIGNAL_PLAY, MUSIC_PLAYBACK_VIEW);
531 case PLAY_STATUS_PAUSE:
532 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_FALSE);
533 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_FALSE);
534 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
535 MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
539 ASSERT(!"Invalid State");
543 state = m->controller.ShuffleState();
545 case SHUFFLE_STATUS_OFF:
546 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_SHUFFLE],
547 MUSIC_SIGNAL_SHUFFLE_OFF, MUSIC_PLAYBACK_VIEW);
550 case SHUFFLE_STATUS_ON:
551 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_SHUFFLE],
552 MUSIC_SIGNAL_SHUFFLE_ON, MUSIC_PLAYBACK_VIEW);
556 ASSERT(!"Invalid State");
560 state = m->controller.RepeatState();
562 case REPEAT_STATUS_NONE:
563 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
564 MUSIC_SIGNAL_REPEAT_OFF, MUSIC_PLAYBACK_VIEW);
567 case REPEAT_STATUS_ALL:
568 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
569 MUSIC_SIGNAL_REPEAT_ALL, MUSIC_PLAYBACK_VIEW);
572 case REPEAT_STATUS_ONE:
573 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
574 MUSIC_SIGNAL_REPEAT_ONE, MUSIC_PLAYBACK_VIEW);
578 ASSERT(!"Invalid State");
584 bool CPlaybackController::Create(Evas_Object *eoBase, SCallback *cb)
589 _CHECK(m = new SPlaybackController)
590 _COMMAND{ m->eoBase = eoBase; }
591 _CHECK(m->controller.Create())
592 _CHECK(m->controller.AddListener(this))
595 m_AddControlButtons();
596 m_AddEditPlaylistButtons();
598 m->press_status = PRESS_SHORT;
601 _CHECK_FAIL{ m->controller.RemoveListener(this); }
602 _CHECK_FAIL{ m->controller.Destroy(); }
604 _CHECK_FAIL{ delete m; m = NULL; }
605 } _CREATE_END_AND_CATCH{ return false; }
611 void CPlaybackController::Destroy(void)
615 m_DestroyErrorPopup();
616 m_DestroySettingsPopup();
617 m->controller.RemoveListener(this);
624 Evas_Object *CPlaybackController::ControlBtnsObject(EPlayerControlBtns id)
627 return m->eoBtnControl[id];
631 Evas_Object *CPlaybackController::EditBtnsObject(EPlayerEditBtns id)
634 return m->eoBtnEdit[id];
638 void CPlaybackController::OnStartPlayback(void)
641 m->duration = m->pSongInfo->Duration();
645 void CPlaybackController::OnError(void)
647 m_CreateErrorPopup();
651 void CPlaybackController::OnEmptyPlaylist(void)
653 m_UpdateForEmptySong();
657 void CPlaybackController::OnRemoteButtonEvent(Evas_Object *eoBtn, EPlayerBtnsEvent ev)
661 m_HandleOnPressed(eoBtn);
664 case EVENT_UNPRESSED:
665 m_HandleOnUnpressed(eoBtn);
669 ASSERT(!"Invalid Event.");
675 void CPlaybackController::OnUpdatePlayerUI(void)
681 void CPlaybackController::OnPressed(int id, Evas_Object *obj)
686 m_HandleOnPressed(obj);
695 void CPlaybackController::OnUnpressed(int id, Evas_Object *obj)
700 m_HandleOnUnpressed(obj);
709 void CPlaybackController::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
719 case EO_BTN_SETTINGS:
721 if (!elm_object_focus_get(obj))
722 elm_object_focus_set(obj, EINA_TRUE);
731 void CPlaybackController::OnMouseClicked(int id, Evas_Object *obj)
735 m->controller.HandlePlaylistEditButtons(EDIT_BTN_CANCEL);
736 m->controller.ChangePlayerMode(MODE_PLAYBACK);
741 m->controller.HandlePlaylistEditButtons(EDIT_BTN_DESELECT);
742 elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
746 m->controller.HandlePlaylistEditButtons(EDIT_BTN_DELETE);
749 case EO_BTN_SETTINGS:
750 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
752 if (m->cb.OnCurrentSongCount &&
753 m->cb.OnCurrentSongCount(m->cb.cookie) == 0)
756 elm_object_signal_emit(obj, MUSIC_SIGNAL_CONTROL_SELECTED, MUSIC_PLAYBACK_VIEW);
757 m_DestroySettingsPopup();
758 m_CreateSettingsPopup();
762 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
764 switch (m->controller.ShuffleState()) {
765 case SHUFFLE_STATUS_OFF:
766 m->controller.SetShuffleState(SHUFFLE_STATUS_ON);
767 elm_object_signal_emit(obj, MUSIC_SIGNAL_SHUFFLE_ON, MUSIC_PLAYBACK_VIEW);
771 m->controller.SetShuffleState(SHUFFLE_STATUS_OFF);
772 elm_object_signal_emit(obj, MUSIC_SIGNAL_SHUFFLE_OFF, MUSIC_PLAYBACK_VIEW);
778 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
780 switch (m->controller.RepeatState()) {
781 case REPEAT_STATUS_NONE:
782 m->controller.SetRepeatState(REPEAT_STATUS_ALL);
783 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_ALL, MUSIC_PLAYBACK_VIEW);
786 case REPEAT_STATUS_ALL:
787 m->controller.SetRepeatState(REPEAT_STATUS_ONE);
788 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_ONE, MUSIC_PLAYBACK_VIEW);
792 m->controller.SetRepeatState(REPEAT_STATUS_NONE);
793 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_OFF, MUSIC_PLAYBACK_VIEW);
799 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
801 switch (m->controller.PlayState()) {
802 case PLAY_STATUS_PAUSE:
803 m->controller.Resume();
804 elm_object_signal_emit(obj, MUSIC_SIGNAL_PLAY, MUSIC_PLAYBACK_VIEW);
807 case PLAY_STATUS_PLAY:
808 elm_object_signal_emit(obj, MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
809 m->controller.Pause();
813 m->controller.Start();