695 lines
22 KiB
C
695 lines
22 KiB
C
#include "empd.h"
|
|
#include "eldbus_empd_empc.h"
|
|
#include <Eldbus.h>
|
|
#include <Elementary.h>
|
|
#include "Empd_Common_Azy.h"
|
|
#include "empc.h"
|
|
#include "empc_parts.h"
|
|
|
|
|
|
#define WEIGHT evas_object_size_hint_weight_set
|
|
#define ALIGN evas_object_size_hint_align_set
|
|
#define EXPAND(X) WEIGHT((X), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND)
|
|
#define FILL(X) ALIGN((X), EVAS_HINT_FILL, EVAS_HINT_FILL)
|
|
|
|
enum
|
|
{
|
|
MPD_STATE_UNKNOWN = 0,
|
|
MPD_STATE_STOP = 1,
|
|
MPD_STATE_PLAY = 2,
|
|
MPD_STATE_PAUSE = 3,
|
|
};
|
|
|
|
#define HIDE_TIMEOUT 3.0
|
|
|
|
static int empd_state = 0;
|
|
static Evas_Object *win = NULL;
|
|
static Evas_Object *bg = NULL;
|
|
static Evas_Object *layout = NULL;
|
|
|
|
static Eina_Bool overlays_locked = EINA_FALSE;
|
|
static Evas_Object *queue_list = NULL;
|
|
static Evas_Object *controls = NULL;
|
|
static Ecore_Timer *queue_list_hide_timer = NULL;
|
|
static Ecore_Timer *controls_hide_timer = NULL;
|
|
static Eina_Bool queue_list_hiding = EINA_FALSE;
|
|
static Eina_Bool queue_list_state = EINA_TRUE;
|
|
static Eina_Bool controls_hiding = EINA_FALSE;
|
|
static Eina_Bool controls_state = EINA_TRUE;
|
|
|
|
|
|
static Eldbus_Proxy *empd_proxy = NULL;
|
|
|
|
static Eina_List *handlers = NULL;
|
|
static Eina_Hash *empd_current_queue = NULL;
|
|
|
|
static int empd_songid = -1;
|
|
static unsigned int empd_song_track = 0;
|
|
static Eina_Stringshare *empd_song_title = NULL;
|
|
static Eina_Stringshare *empd_song_artist = NULL;
|
|
static Eina_Stringshare *empd_song_album = NULL;
|
|
static Elm_Object_Item *empd_song_item = NULL;
|
|
static unsigned int empd_song_length = 0;
|
|
static unsigned int empd_song_elapsed = 0;
|
|
static unsigned int empd_queue_length = 0;
|
|
|
|
static void
|
|
queue_list_hidden(void *d EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
queue_list_state = queue_list_hiding = EINA_FALSE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
queue_list_hide(void *d EINA_UNUSED)
|
|
{
|
|
queue_list_hide_timer = NULL;
|
|
queue_list_hiding = EINA_TRUE;
|
|
elm_object_signal_emit(layout, "empc,playlist,hide", "empc");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
queue_list_show(void)
|
|
{
|
|
queue_list_hiding = EINA_FALSE;
|
|
evas_object_show(queue_list);
|
|
queue_list_state = EINA_TRUE;
|
|
elm_object_signal_emit(layout, "empc,playlist,show", "empc");
|
|
}
|
|
|
|
static void
|
|
controls_hidden(void *d EINA_UNUSED, Evas_Object *o EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
controls_state = controls_hiding = EINA_FALSE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
controls_hide(void *d EINA_UNUSED)
|
|
{
|
|
controls_hide_timer = NULL;
|
|
controls_hiding = EINA_TRUE;
|
|
elm_object_signal_emit(layout, "empc,controls,hide", "empc");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
controls_show(void)
|
|
{
|
|
controls_hiding = EINA_FALSE;
|
|
evas_object_show(controls);
|
|
controls_state = EINA_TRUE;
|
|
elm_object_signal_emit(layout, "empc,controls,show", "empc");
|
|
}
|
|
|
|
static void
|
|
title_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
if (empd_song_track)
|
|
{
|
|
char buf[1024];
|
|
|
|
snprintf(buf, sizeof(buf), "%.2d - %s", empd_song_track, empd_song_title);
|
|
elm_object_part_text_set(layout, EMPC_BASE_TEXT_TITLE, buf);
|
|
}
|
|
else
|
|
elm_object_part_text_set(layout, EMPC_BASE_TEXT_TITLE, empd_song_title);
|
|
elm_object_signal_emit(layout, "empc,title,change,2", "empc");
|
|
}
|
|
|
|
static void
|
|
title_update(void)
|
|
{
|
|
char buf[4096];
|
|
const char *st;
|
|
|
|
switch (empd_state)
|
|
{
|
|
case MPD_STATE_STOP:
|
|
st = "Stopped";
|
|
break;
|
|
case MPD_STATE_PLAY:
|
|
st = "Playing";
|
|
break;
|
|
case MPD_STATE_PAUSE:
|
|
st = "Paused";
|
|
break;
|
|
case MPD_STATE_UNKNOWN:
|
|
default:
|
|
st = "Unknown State";
|
|
break;
|
|
}
|
|
snprintf(buf, sizeof(buf), "EMPC | %s - %s (%s)", empd_song_artist, empd_song_title, st);
|
|
elm_win_title_set(win, buf);
|
|
}
|
|
|
|
static Eina_Bool
|
|
status_update(int state)
|
|
{
|
|
Evas_Object *button, *ic, *o;
|
|
|
|
if (state == empd_state) return EINA_FALSE;
|
|
empd_state = state;
|
|
o = evas_object_data_get(win, "slider");
|
|
button = evas_object_data_get(win, "play_button");
|
|
ic = elm_object_content_get(button);
|
|
switch (state)
|
|
{
|
|
case MPD_STATE_UNKNOWN:
|
|
elm_object_signal_emit(o, "empc,state,unknown", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
case MPD_STATE_STOP:
|
|
elm_object_signal_emit(o, "empc,state,stopped", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
case MPD_STATE_PLAY:
|
|
elm_object_signal_emit(o, "empc,state,playing", "empc");
|
|
elm_icon_standard_set(ic, "media_player/pause");
|
|
break;
|
|
case MPD_STATE_PAUSE:
|
|
elm_object_signal_emit(o, "empc,state,paused", "empc");
|
|
elm_icon_standard_set(ic, "media_player/play");
|
|
break;
|
|
}
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
songid_update(int songid)
|
|
{
|
|
Elm_Object_Item *it, *itp = NULL;
|
|
|
|
if (empd_songid == songid) return EINA_FALSE;
|
|
if (empd_songid != -1)
|
|
itp = eina_hash_find(empd_current_queue, &empd_songid);
|
|
empd_song_item = it = eina_hash_find(empd_current_queue, &songid);
|
|
/* don't allow set until item exists */
|
|
if (!it) return EINA_TRUE;
|
|
empd_songid = songid;
|
|
if (itp)
|
|
{
|
|
elm_object_item_signal_emit(itp, "empc,state,not_playing", "empc");
|
|
elm_genlist_item_fields_update(itp, EMPC_PLAYLIST_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
if (it)
|
|
{
|
|
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
|
elm_object_item_signal_emit(it, "empc,state,playing", "empc");
|
|
elm_genlist_item_fields_update(it, EMPC_PLAYLIST_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
if (songid >= empd_songid)
|
|
elm_object_signal_emit(layout, "empc,title,change,next", "empc");
|
|
else
|
|
elm_object_signal_emit(layout, "empc,title,change,prev", "empc");
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
void
|
|
empc_cover_done(const char *artist, const char *album, const char *uri, void *data, size_t size)
|
|
{
|
|
if (album)
|
|
{
|
|
if ((!empd_song_album) || strcasecmp(album, empd_song_album)) goto fail;
|
|
}
|
|
if ((!artist) || (!empd_song_artist) || strcasecmp(artist, empd_song_artist)) goto fail;
|
|
|
|
if (uri)
|
|
elm_image_file_set(bg, uri, NULL);
|
|
else
|
|
elm_image_memfile_set(bg, data, size, NULL, NULL);
|
|
return;
|
|
fail:
|
|
free(data);
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_connected(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empc_Connected_Data *ev)
|
|
{
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_disconnected(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empc_Disconnected_Data *ev)
|
|
{
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_current_song(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empc_CurrentSong_Data *ev)
|
|
{
|
|
empd_song_track = ev->track;
|
|
/* yes, | is intentional. */
|
|
if (songid_update(ev->songid) |
|
|
eina_stringshare_replace(&empd_song_title, ev->title) |
|
|
eina_stringshare_replace(&empd_song_artist, ev->artist))
|
|
title_update();
|
|
if (eina_stringshare_replace(&empd_song_album, ev->album))
|
|
empc_glyr_gmpc_fetch_image(empd_song_artist, empd_song_album);
|
|
elm_object_part_text_set(layout, EMPC_BASE_TEXT_ARTIST, empd_song_artist);
|
|
elm_object_part_text_set(layout, EMPC_BASE_TEXT_ALBUM, empd_song_album);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_status(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empc_Status_Data *ev)
|
|
{
|
|
Eina_Bool up = EINA_FALSE;
|
|
Evas_Object *o;
|
|
|
|
up = (empd_song_length != ev->song_length) || (empd_song_elapsed != ev->song_elapsed);
|
|
if (up)
|
|
{
|
|
o = evas_object_data_get(win, "slider");
|
|
empd_song_length = ev->song_length;
|
|
empd_song_elapsed = ev->song_elapsed;
|
|
elm_slider_value_set(o, (double)ev->song_elapsed / (double)ev->song_length);
|
|
if (empd_song_item && queue_list_state)
|
|
elm_genlist_item_fields_update(empd_song_item, EMPC_PLAYLIST_TEXT_TIME, ELM_GENLIST_ITEM_FIELD_TEXT);
|
|
}
|
|
up = songid_update(ev->songid);
|
|
if (up)
|
|
empd_empc_current_song_call(empd_proxy);
|
|
up |= status_update(ev->state);
|
|
if (up) title_update();
|
|
if (empd_queue_length != ev->queue_length)
|
|
{
|
|
/* load current playlist incrementally (max 30):
|
|
* - don't block daemon forever with large playlists
|
|
* - GREATLY decreases startup delay when showing list
|
|
* - don't block ui when receiving huge playlists
|
|
*/
|
|
unsigned int i, step = (ev->queue_length / 4) % 31;
|
|
for (i = 0; i < ev->queue_length; i += step)
|
|
empd_empc_queue_list_range_call(empd_proxy, i, i + step);
|
|
elm_genlist_clear(queue_list);
|
|
}
|
|
empd_queue_length = ev->queue_length;
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static void
|
|
queue_list_item_realize(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Elm_Object_Item *it = event_info;
|
|
Empd_Empc_Song *so;
|
|
|
|
so = elm_object_item_data_get(it);
|
|
if (empd_songid == so->songid)
|
|
elm_object_item_signal_emit(it, "empc,state,playing", "empc");
|
|
else
|
|
elm_object_item_signal_emit(it, "empc,state,not_playing", "empc");
|
|
}
|
|
|
|
static void
|
|
queue_list_double_click(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
|
|
{
|
|
Elm_Object_Item *it = event_info;
|
|
Empd_Empc_Song *so;
|
|
|
|
so = elm_object_item_data_get(it);
|
|
empd_empc_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
|
|
static void
|
|
queue_list_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
|
|
{
|
|
Elm_Object_Item *it;
|
|
Empd_Empc_Song *so;
|
|
Evas_Event_Key_Down *ev = event_info;
|
|
|
|
if ((!strcmp(ev->keyname, "Enter")) || (!strcmp(ev->keyname, "Return")))
|
|
{
|
|
it = elm_genlist_selected_item_get(obj);
|
|
if (!it) return;
|
|
so = elm_object_item_data_get(it);
|
|
empd_empc_play_id_call(empd_proxy, so->songid);
|
|
}
|
|
else if (!strcmp(ev->keyname, "Delete"))
|
|
{
|
|
const Eina_List *l, *ll;
|
|
int start = -1, num;
|
|
|
|
l = elm_genlist_selected_items_get(obj);
|
|
if (!l) return;
|
|
EINA_LIST_FOREACH(l, ll, it)
|
|
{
|
|
/* check for contiguous selection */
|
|
so = elm_object_item_data_get(it);
|
|
if (start == -1)
|
|
start = so->song_pos, num = 1;
|
|
/* fragmentation detected */
|
|
if ((elm_genlist_item_next_get(it) != eina_list_data_get(ll->next)) &&
|
|
(elm_genlist_item_prev_get(it) != eina_list_data_get(ll->next))) //selections can go both ways
|
|
{
|
|
if (so->song_pos < start) //backwards selection
|
|
start = so->song_pos;
|
|
//fprintf(stderr, "DEL %d:%d\n", start, num);
|
|
empd_empc_delete_list_range_call(empd_proxy, start, num);
|
|
start = -1, num = 0;
|
|
}
|
|
else
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static char *
|
|
queue_list_item_text_get(Empd_Empc_Song *so, Evas_Object *obj EINA_UNUSED, const char *part)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (!strcmp(part, "elm.text"))
|
|
return strdup(so->title ?: so->uri);
|
|
if (!strcmp(part, EMPC_PLAYLIST_TEXT_TRACK))
|
|
{
|
|
if (!so->track) return NULL;
|
|
snprintf(buf, sizeof(buf), "%.2d", so->track);
|
|
return strdup(buf);
|
|
}
|
|
if (empd_songid == so->songid)
|
|
snprintf(buf, sizeof(buf), "%.2d:%.2d / %.2d:%.2d",
|
|
empd_song_elapsed / 60, empd_song_elapsed % 60,
|
|
empd_song_length / 60, empd_song_length % 60);
|
|
else
|
|
snprintf(buf, sizeof(buf), "%.2ld:%.2ld", so->duration / 60, so->duration % 60);
|
|
return strdup(buf);
|
|
}
|
|
|
|
static void
|
|
queue_list_item_del(Empd_Empc_Song *so, Evas_Object *obj EINA_UNUSED)
|
|
{
|
|
if (empd_song_item && (elm_object_item_data_get(empd_song_item) == so))
|
|
empd_song_item = NULL;
|
|
eina_hash_del_by_key(empd_current_queue, &so->songid);
|
|
Empd_Empc_Song_free(so);
|
|
}
|
|
|
|
static int
|
|
queue_list_sort(Elm_Object_Item *a, Elm_Object_Item *b)
|
|
{
|
|
Empd_Empc_Song *a1, *b1;
|
|
|
|
a1 = elm_object_item_data_get(a);
|
|
b1 = elm_object_item_data_get(b);
|
|
|
|
return a1->song_pos - b1->song_pos;
|
|
}
|
|
|
|
static Eina_Bool
|
|
empc_queue_list(void *d EINA_UNUSED, int t EINA_UNUSED, Empd_Empc_QueueList_Data *ev)
|
|
{
|
|
Empd_Array_Songs *songs = NULL;
|
|
Empd_Empc_Song *so;
|
|
static Elm_Genlist_Item_Class queue_itc = {
|
|
.item_style = "playlist",
|
|
.func = {
|
|
.text_get = (Elm_Genlist_Item_Text_Get_Cb)queue_list_item_text_get,
|
|
.del = (Elm_Genlist_Item_Del_Cb)queue_list_item_del
|
|
},
|
|
.version = ELM_GENLIST_ITEM_CLASS_VERSION
|
|
};
|
|
|
|
if (!azy_value_to_Empd_Array_Songs(ev->value, &songs))
|
|
{
|
|
EINA_LOG_ERR("conversion failure");
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
EINA_LIST_FREE(songs->songs, so)
|
|
{
|
|
Elm_Object_Item *it;
|
|
|
|
it = eina_hash_find(empd_current_queue, &so->songid);
|
|
if (it)
|
|
{
|
|
Empd_Empc_Song *ss = elm_object_item_data_get(it);
|
|
if (Empd_Empc_Song_eq(so, ss))
|
|
Empd_Empc_Song_free(so);
|
|
else
|
|
{
|
|
Empd_Empc_Song_free(ss);
|
|
elm_object_item_data_set(it, so);
|
|
elm_genlist_item_update(it);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
it = elm_genlist_item_sorted_insert(queue_list, &queue_itc, so, NULL, 0, (Eina_Compare_Cb)queue_list_sort, NULL, NULL);
|
|
eina_hash_add(empd_current_queue, &so->songid, it);
|
|
}
|
|
}
|
|
free(songs);
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Evas_Object *
|
|
button_add(const char *icon)
|
|
{
|
|
Evas_Object *o, *ic;
|
|
|
|
o = elm_button_add(win);
|
|
elm_object_style_set(o, "controls");
|
|
elm_object_focus_allow_set(o, EINA_FALSE);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
ic = elm_icon_add(win);
|
|
elm_image_resizable_set(ic, 0, 0);
|
|
elm_icon_standard_set(ic, icon);
|
|
elm_object_part_content_set(o, "icon", ic);
|
|
evas_object_show(ic);
|
|
evas_object_show(o);
|
|
return o;
|
|
}
|
|
|
|
static void
|
|
control_skip_back(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
empd_empc_previous_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_stop(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
empd_empc_stop_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_toggle(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
if (empd_state == MPD_STATE_PLAY)
|
|
empd_empc_pause_call(empd_proxy, EINA_TRUE);
|
|
else
|
|
empd_empc_play_call(empd_proxy);
|
|
}
|
|
|
|
static void
|
|
control_skip_forward(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
empd_empc_next_call(empd_proxy);
|
|
}
|
|
|
|
static Eina_Bool
|
|
status_poller(void *d EINA_UNUSED)
|
|
{
|
|
empd_empc_status_call(empd_proxy);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
slider_seek(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
|
{
|
|
double val;
|
|
|
|
val = elm_slider_value_get(obj);
|
|
empd_empc_seek_call(empd_proxy, empd_songid, lround(val * empd_song_length));
|
|
}
|
|
|
|
static void
|
|
layout_mouse_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{
|
|
if (queue_list_hide_timer) ecore_timer_reset(queue_list_hide_timer);
|
|
}
|
|
|
|
static void
|
|
queue_list_mouse_in(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
E_FREE_FUNC(queue_list_hide_timer, ecore_timer_del);
|
|
if (queue_list_state && (!queue_list_hiding)) return;
|
|
queue_list_show();
|
|
}
|
|
|
|
static void
|
|
queue_list_mouse_out(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
if (overlays_locked) return;
|
|
if (!queue_list_hide_timer)
|
|
queue_list_hide_timer = ecore_timer_add(HIDE_TIMEOUT, queue_list_hide, NULL);
|
|
}
|
|
|
|
static void
|
|
controls_mouse_in(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
E_FREE_FUNC(controls_hide_timer, ecore_timer_del);
|
|
if (controls_state && (!controls_hiding)) return;
|
|
controls_show();
|
|
}
|
|
|
|
static void
|
|
controls_mouse_out(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
|
|
{
|
|
if (overlays_locked) return;
|
|
if (!controls_hide_timer)
|
|
controls_hide_timer = ecore_timer_add(HIDE_TIMEOUT, controls_hide, NULL);
|
|
}
|
|
|
|
static void
|
|
key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Event_Key_Down *ev)
|
|
{
|
|
if ((!strcmp(ev->keyname, "q")) && evas_key_modifier_is_set(ev->modifiers, "Control"))
|
|
ecore_main_loop_quit();
|
|
else if (!strcmp(ev->keyname, "F1"))
|
|
{
|
|
overlays_locked = !overlays_locked;
|
|
if (overlays_locked)
|
|
{
|
|
E_FREE_FUNC(queue_list_hide_timer, ecore_timer_del);
|
|
E_FREE_FUNC(controls_hide_timer, ecore_timer_del);
|
|
if (!controls_state)
|
|
controls_show();
|
|
if (!queue_list_state)
|
|
queue_list_show();
|
|
}
|
|
else
|
|
{
|
|
controls_hide(NULL);
|
|
queue_list_hide(NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
Evas_Object *o, *hbox;
|
|
|
|
eldbus_init();
|
|
elm_init(argc, argv);
|
|
empc_glyr_gmpc_init();
|
|
elm_theme_overlay_add(NULL, "./empc.edj");
|
|
|
|
empd_current_queue = eina_hash_int32_new(NULL);
|
|
|
|
ecore_poller_add(ECORE_POLLER_CORE, 8, status_poller, NULL);
|
|
|
|
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
|
|
|
empd_proxy = empd_empc_proxy_get(eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION), EMPD_METHOD_BASE, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_CONNECTED_EVENT, empc_connected, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_DISCONNECTED_EVENT, empc_disconnected, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_CURRENT_SONG_EVENT, empc_current_song, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_STATUS_EVENT, empc_status, NULL);
|
|
E_LIST_HANDLER_APPEND(handlers, EMPD_EMPC_QUEUE_LIST_EVENT, empc_queue_list, NULL);
|
|
|
|
empd_empc_status_call(empd_proxy);
|
|
|
|
win = elm_win_add(NULL, "empc", ELM_WIN_BASIC);
|
|
elm_win_title_set(win, "empc");
|
|
elm_win_autodel_set(win, 1);
|
|
{
|
|
Evas_Modifier_Mask ctrl;//, shift, alt;
|
|
Evas *e = evas_object_evas_get(win);
|
|
|
|
ctrl = evas_key_modifier_mask_get(e, "Control");
|
|
//shift = evas_key_modifier_mask_get(e, "Shift");
|
|
//alt = evas_key_modifier_mask_get(e, "Alt");
|
|
1 | evas_object_key_grab(win, "q", 0, ctrl, 1);
|
|
1 | evas_object_key_grab(win, "F1", 0, 0, 1);
|
|
}
|
|
evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, (Evas_Object_Event_Cb)key_down, NULL);
|
|
|
|
layout = elm_layout_add(win);
|
|
EXPAND(layout);
|
|
FILL(layout);
|
|
elm_win_resize_object_add(win, layout);
|
|
elm_layout_theme_set(layout, "layout", "empc", "base");
|
|
elm_object_signal_callback_add(layout, "empc,title,changed,1", "empc", title_changed, NULL);
|
|
|
|
elm_object_signal_callback_add(layout, "empc,playlist,mouse_in", "empc", queue_list_mouse_in, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,playlist,mouse_out", "empc", queue_list_mouse_out, NULL);
|
|
evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_MOVE, layout_mouse_move, NULL);
|
|
evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN, layout_mouse_move, NULL);
|
|
evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, layout_mouse_move, NULL);
|
|
evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_WHEEL, layout_mouse_move, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,playlist,hidden", "empc", queue_list_hidden, NULL);
|
|
elm_object_signal_emit(layout, "empc,playlist,show", "empc");
|
|
queue_list_hide_timer = ecore_timer_add(HIDE_TIMEOUT, queue_list_hide, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,controls,mouse_in", "empc", controls_mouse_in, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,controls,mouse_out", "empc", controls_mouse_out, NULL);
|
|
elm_object_signal_callback_add(layout, "empc,controls,hidden", "empc", controls_hidden, NULL);
|
|
elm_object_signal_emit(layout, "empc,controls,show", "empc");
|
|
controls_hide_timer = ecore_timer_add(HIDE_TIMEOUT, controls_hide, NULL);
|
|
evas_object_show(layout);
|
|
|
|
bg = elm_image_add(win);
|
|
elm_object_part_content_set(layout, EMPC_BASE_SWALLOW_BACKGROUND, bg);
|
|
elm_image_fill_outside_set(bg, EINA_FALSE);
|
|
evas_object_show(bg);
|
|
|
|
controls = hbox = elm_box_add(win);
|
|
elm_box_horizontal_set(hbox, EINA_TRUE);
|
|
elm_box_homogeneous_set(hbox, EINA_TRUE);
|
|
EXPAND(hbox);
|
|
FILL(hbox);
|
|
evas_object_show(hbox);
|
|
|
|
o = button_add("media_player/prev");
|
|
evas_object_smart_callback_add(o, "clicked", control_skip_back, NULL);
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/stop");
|
|
evas_object_smart_callback_add(o, "clicked", control_stop, NULL);
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/play");
|
|
evas_object_data_set(win, "play_button", o);
|
|
evas_object_smart_callback_add(o, "clicked", control_toggle, NULL);
|
|
elm_box_pack_end(hbox, o);
|
|
|
|
o = button_add("media_player/next");
|
|
evas_object_smart_callback_add(o, "clicked", control_skip_forward, NULL);
|
|
elm_box_pack_end(hbox, o);
|
|
elm_object_part_content_set(layout, EMPC_BASE_SWALLOW_CONTROLS, hbox);
|
|
|
|
o = elm_slider_add(win);
|
|
elm_object_style_set(o, "player");
|
|
evas_object_data_set(win, "slider", o);
|
|
WEIGHT(o, EVAS_HINT_EXPAND, 0);
|
|
FILL(o);
|
|
evas_object_smart_callback_add(o, "changed", slider_seek, NULL);
|
|
elm_slider_min_max_set(o, 0.0, 1.0);
|
|
elm_object_part_content_set(layout, EMPC_BASE_SWALLOW_POSITION, o);
|
|
evas_object_show(o);
|
|
|
|
queue_list = o = elm_genlist_add(win);
|
|
evas_object_smart_callback_add(o, "realized", queue_list_item_realize, NULL);
|
|
evas_object_smart_callback_add(o, "clicked,double", queue_list_double_click, NULL);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, queue_list_key_down, NULL);
|
|
elm_genlist_multi_select_mode_set(o, ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL);
|
|
elm_genlist_homogeneous_set(o, EINA_TRUE);
|
|
elm_genlist_multi_select_set(o, 1);
|
|
elm_scroller_bounce_set(o, 0, 0);
|
|
elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
|
|
elm_genlist_mode_set(o, ELM_LIST_COMPRESS);
|
|
EXPAND(o);
|
|
FILL(o);
|
|
elm_object_part_content_set(layout, EMPC_BASE_SWALLOW_PLAYLIST, o);
|
|
evas_object_show(o);
|
|
evas_object_focus_set(o, EINA_TRUE);
|
|
|
|
evas_object_show(win);
|
|
evas_object_resize(win, 300, 400);
|
|
|
|
elm_run();
|
|
return 0;
|
|
}
|