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_UpdateSongInfo(void)
455 CSongInfo *sinfo = NULL;
458 if (!m->controller.GetCurrentSongIndex(&index)) {
459 _ERR(" music get current song index failed ");
463 if (!m->controller.GetSonginfoFromIndex(index, &sinfo)) {
464 _ERR(" music get songinfo failed ");
467 m->pSongInfo = sinfo;
471 void CPlaybackController::m_HandleOnPressed(Evas_Object *obj)
473 m->press_status = PRESS_SHORT;
474 m->eoPressedObj = obj;
476 m->etWait = ecore_timer_add(WAIT_INTERVAL, sm_CbWaitTimer, this);
480 void CPlaybackController::m_HandleOnUnpressed(Evas_Object *obj)
482 m_RemoveTimer(TIMER_WAIT);
483 m_RemoveTimer(TIMER_LONGPRESS);
485 if (m->press_status == PRESS_SHORT) {
486 /* Handle song change */
487 if (m->controller.PlayState() == PLAY_STATUS_PLAY)
488 m->controller.Pause();
490 if (obj == m->eoBtnControl[CTRL_BTN_FORWARD])
491 m_HandleForwardBtnClicked(obj);
493 m_HandleRewindBtnClicked(obj);
495 if (m->controller.PlayState() != PLAY_STATUS_PLAY)
496 m->controller.Resume();
498 else if (m->press_status == PRESS_LONG) {
499 if (m->controller.PlayState() != PLAY_STATUS_PLAY)
500 m->controller.Resume();
503 m->press_status = PRESS_SHORT;
507 bool CPlaybackController::Create(Evas_Object *eoBase, SCallback *cb)
512 _CHECK(m = new SPlaybackController)
513 _COMMAND{ m->eoBase = eoBase; }
514 _CHECK(m->controller.Create())
515 _CHECK(m->controller.AddListener(this))
518 m_AddControlButtons();
519 m_AddEditPlaylistButtons();
521 m->press_status = PRESS_SHORT;
524 _CHECK_FAIL{ m->controller.RemoveListener(this); }
525 _CHECK_FAIL{ m->controller.Destroy(); }
527 _CHECK_FAIL{ delete m; m = NULL; }
528 } _CREATE_END_AND_CATCH{ return false; }
534 void CPlaybackController::Destroy(void)
538 m_DestroyErrorPopup();
539 m_DestroySettingsPopup();
540 m->controller.RemoveListener(this);
547 void CPlaybackController::Update(void)
551 state = m->controller.PlayState();
553 case PLAY_STATUS_INITIAL:
554 // Initial State, Do nothing
557 case PLAY_STATUS_STOP:
559 elm_object_focus_set(m->eoBtnControl[CTRL_BTN_PLAY], EINA_TRUE);
560 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_TRUE);
561 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_TRUE);
564 case PLAY_STATUS_PLAY:
565 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_FALSE);
566 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_FALSE);
567 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
568 MUSIC_SIGNAL_PLAY, MUSIC_PLAYBACK_VIEW);
571 case PLAY_STATUS_PAUSE:
572 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_FORWARD], EINA_FALSE);
573 elm_object_disabled_set(m->eoBtnControl[CTRL_BTN_REWIND], EINA_FALSE);
574 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_PLAY],
575 MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
579 ASSERT(!"Invalid State");
583 state = m->controller.ShuffleState();
585 case SHUFFLE_STATUS_OFF:
586 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_SHUFFLE],
587 MUSIC_SIGNAL_SHUFFLE_OFF, MUSIC_PLAYBACK_VIEW);
590 case SHUFFLE_STATUS_ON:
591 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_SHUFFLE],
592 MUSIC_SIGNAL_SHUFFLE_ON, MUSIC_PLAYBACK_VIEW);
596 ASSERT(!"Invalid State");
600 state = m->controller.RepeatState();
602 case REPEAT_STATUS_NONE:
603 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
604 MUSIC_SIGNAL_REPEAT_OFF, MUSIC_PLAYBACK_VIEW);
607 case REPEAT_STATUS_ALL:
608 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
609 MUSIC_SIGNAL_REPEAT_ALL, MUSIC_PLAYBACK_VIEW);
612 case REPEAT_STATUS_ONE:
613 elm_object_signal_emit(m->eoBtnControl[CTRL_BTN_REPEAT],
614 MUSIC_SIGNAL_REPEAT_ONE, MUSIC_PLAYBACK_VIEW);
618 ASSERT(!"Invalid State");
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::OnComplete(void)
643 void CPlaybackController::OnStartPlayback(void)
646 m->duration = m->pSongInfo->Duration();
650 void CPlaybackController::OnStopPlayback(void)
655 void CPlaybackController::OnPausePlayback(void)
660 void CPlaybackController::OnResumePlayback(void)
665 void CPlaybackController::OnPosition(int milsec)
670 void CPlaybackController::OnError(void)
672 m_CreateErrorPopup();
676 void CPlaybackController::OnEmptyPlaylist(void)
678 m_UpdateForEmptySong();
682 void CPlaybackController::OnRemoteButtonEvent(Evas_Object *eoBtn, EPlayerBtnsEvent ev)
686 m_HandleOnPressed(eoBtn);
689 case EVENT_UNPRESSED:
690 m_HandleOnUnpressed(eoBtn);
694 ASSERT(!"Invalid Event.");
700 void CPlaybackController::OnPressed(int id, Evas_Object *obj)
705 m_HandleOnPressed(obj);
714 void CPlaybackController::OnUnpressed(int id, Evas_Object *obj)
719 m_HandleOnUnpressed(obj);
728 void CPlaybackController::OnMouseMove(int id, Evas *e, Evas_Object *obj, Evas_Event_Mouse_Move *ev)
738 case EO_BTN_SETTINGS:
740 if (!elm_object_focus_get(obj))
741 elm_object_focus_set(obj, EINA_TRUE);
750 void CPlaybackController::OnMouseClicked(int id, Evas_Object *obj)
754 m->controller.HandlePlaylistEditButtons(EDIT_BTN_CANCEL);
755 m->controller.ChangePlayerMode(MODE_PLAYBACK);
760 m->controller.HandlePlaylistEditButtons(EDIT_BTN_DESELECT);
761 elm_object_focus_set(m->eoBtnEdit[EDIT_BTN_CANCEL], EINA_TRUE);
765 m->controller.HandlePlaylistEditButtons(EDIT_BTN_DELETE);
768 case EO_BTN_SETTINGS:
769 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
771 if (m->cb.OnCurrentSongCount &&
772 m->cb.OnCurrentSongCount(m->cb.cookie) == 0)
775 elm_object_signal_emit(obj, MUSIC_SIGNAL_CONTROL_SELECTED, MUSIC_PLAYBACK_VIEW);
776 m_DestroySettingsPopup();
777 m_CreateSettingsPopup();
781 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
783 switch (m->controller.ShuffleState()) {
784 case SHUFFLE_STATUS_OFF:
785 m->controller.SetShuffleState(SHUFFLE_STATUS_ON);
786 elm_object_signal_emit(obj, MUSIC_SIGNAL_SHUFFLE_ON, MUSIC_PLAYBACK_VIEW);
790 m->controller.SetShuffleState(SHUFFLE_STATUS_OFF);
791 elm_object_signal_emit(obj, MUSIC_SIGNAL_SHUFFLE_OFF, MUSIC_PLAYBACK_VIEW);
797 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
799 switch (m->controller.RepeatState()) {
800 case REPEAT_STATUS_NONE:
801 m->controller.SetRepeatState(REPEAT_STATUS_ALL);
802 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_ALL, MUSIC_PLAYBACK_VIEW);
805 case REPEAT_STATUS_ALL:
806 m->controller.SetRepeatState(REPEAT_STATUS_ONE);
807 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_ONE, MUSIC_PLAYBACK_VIEW);
811 m->controller.SetRepeatState(REPEAT_STATUS_NONE);
812 elm_object_signal_emit(obj, MUSIC_SIGNAL_REPEAT_OFF, MUSIC_PLAYBACK_VIEW);
818 elm_object_signal_emit(obj, MUSIC_SIGNAL_BTN_CLICKED, MUSIC_PLAYBACK_VIEW);
820 switch (m->controller.PlayState()) {
821 case PLAY_STATUS_PAUSE:
822 m->controller.Resume();
823 elm_object_signal_emit(obj, MUSIC_SIGNAL_PLAY, MUSIC_PLAYBACK_VIEW);
826 case PLAY_STATUS_PLAY:
827 elm_object_signal_emit(obj, MUSIC_SIGNAL_PAUSE, MUSIC_PLAYBACK_VIEW);
828 m->controller.Pause();
832 m->controller.Start();