image: "pause.png" COMP;
image: "play.png" COMP;
}
+ styles {
+ style { name: "music_control_metadata_style";
+ base: "font=Sans font_size=10 align=left text_class=tb_plain color=#ffff style=shadow,bottom shadow_color=#00000080";
+ tag: "title" "+ font_size=12 font=Sans:style=Bold text_class=tb_big";
+ tag: "tag" "+ font_size=8 color=#888f";
+ tag: "br" "\n";
+ }
+ }
parts {
- part {
- name: "player_name";
- type: TEXT;
- description {
- state: "default" 0;
- text.size: 12;
- text.text: "Music player";
- text.font: "Sans";
+ part { name: "cover_bg";
+ type: IMAGE;
+ description { state: "default" 0;
+ min: 90 90;
rel1.relative: 0.0 0.0;
+ rel2.relative: 0.35 1.0;
+ image.normal: "music_control_icon.png";
+ }
+ }
+ part { name: "cover_swallow";
+ type: SWALLOW;
+ description { state: "default" 0;
+ rel1.to: "cover_bg";
+ rel2.to: "cover_bg";
+ }
+ }
+ part { name: "player_name";
+ type: TEXT;
+ effect: GLOW;
+ description { state: "default" 0;
+ color: 51 153 255 255;
+ color2: 51 153 255 24;
+ color3: 51 153 255 18;
+ text {
+ size: 12;
+ text: "Music player";
+ font: "Sans:style=Bold";
+ }
+ rel1.to: "cover_bg";
+ rel1.relative: 1.0 0.0;
rel2.relative: 1.0 0.0;
- rel2.offset: 0 16;
+ rel2.offset: 0 12;
}
}
- part {
+ part { name: "metadata";
+ type: TEXTBLOCK;
+ description { state: "default" 0;
+ text {
+ style: "music_control_metadata_style";
+ text: "Song Title";
+ align: 0.0 0.0;
+ }
+ rel1.to: "player_name";
+ rel1.relative: 0.0 1.0;
+ rel1.offset: 3 0;
+ }
+ }
+ part { name: "previous_btn";
type: IMAGE;
- name: "previous_btn";
- description {
- state: "default" 0;
+ description { state: "default" 0;
+ max: 32 32;
aspect: 1.0 1.0;
aspect_preference: BOTH;
- rel1.to: "player_name";
- rel1.relative: 0.0 1.0;
- rel2.relative: 0.33 1.0;
+ align: 0.1 1.0;
+ rel1.relative: 0.35 0.0;
image.normal: "previous.png";
}
}
- part {
+ part { name: "play_btn";
type: IMAGE;
- name: "play_btn";
- description {
- state: "default" 0;
- aspect: 1.0 1.0;
- aspect_preference: BOTH;
- rel1.to: "player_name";
- rel1.relative: 0.33 1.0;
- rel2.relative: 0.66 1.0;
- image.normal: "pause.png";
+ description { state: "default" 0;
+ max: 32 32;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ align: 0.5 1.0;
+ rel1.relative: 0.35 0.0;
+ image.normal: "pause.png";
}
- description {
- state: "play" 0.0;
- inherit: "default" 0.0;
- image.normal: "play.png";
+ description { state: "play" 0.0;
+ inherit: "default" 0.0;
+ image.normal: "play.png";
}
}
- part {
+ part { name: "next_btn";
type: IMAGE;
- name: "next_btn";
- description {
- state: "default" 0;
- aspect: 1.0 1.0;
- aspect_preference: BOTH;
- rel1.to: "player_name";
- rel1.relative: 0.66 1.0;
- rel2.relative: 1.0 1.0;
- image.normal: "next.png";
+ description { state: "default" 0;
+ max: 32 32;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ align: 0.9 1.0;
+ rel1.relative: 0.35 0.0;
+ image.normal: "next.png";
}
}
}
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, _e_music_control_Name };
static void
+parse_metadata(E_Music_Control_Module_Context *ctxt, Eina_Value *array)
+{
+ unsigned i;
+
+ E_FREE_FUNC(ctxt->meta_title, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_album, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_artist, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_cover, eina_stringshare_del);
+ // DBG("Metadata: %s", eina_value_to_string(array));
+
+ for (i = 0; i < eina_value_array_count(array); i++)
+ {
+ const char *key, *str_val;
+ Eina_Value st, subst;
+
+ eina_value_array_value_get(array, i, &st);
+ eina_value_struct_get(&st, "arg0", &key);
+ if (!strcmp(key, "xesam:title"))
+ {
+ eina_value_struct_value_get(&st, "arg1", &subst);
+ eina_value_struct_get(&subst, "arg0", &str_val);
+ ctxt->meta_title = eina_stringshare_add(str_val);
+ eina_value_flush(&subst);
+ }
+ else if (!strcmp(key, "xesam:album"))
+ {
+ eina_value_struct_value_get(&st, "arg1", &subst);
+ eina_value_struct_get(&subst, "arg0", &str_val);
+ ctxt->meta_album = eina_stringshare_add(str_val);
+ eina_value_flush(&subst);
+ }
+ else if (!strcmp(key, "xesam:artist"))
+ {
+ Eina_Value arr;
+ eina_value_struct_value_get(&st, "arg1", &subst);
+ eina_value_struct_value_get(&subst, "arg0", &arr);
+ eina_value_array_get(&arr, 0, &str_val);
+ ctxt->meta_artist = eina_stringshare_add(str_val);
+ eina_value_flush(&arr);
+ eina_value_flush(&subst);
+ }
+ else if (!strcmp(key, "mpris:artUrl"))
+ {
+ eina_value_struct_value_get(&st, "arg1", &subst);
+ eina_value_struct_get(&subst, "arg0", &str_val);
+ if (!strncmp(str_val, "file://", 7))
+ ctxt->meta_cover = eina_stringshare_add(str_val + 7);
+ eina_value_flush(&subst);
+ }
+ eina_value_flush(&st);
+ }
+}
+
+static void
cb_playback_status_get(void *data, Eldbus_Pending *p, const char *propname, Eldbus_Proxy *proxy, Eldbus_Error_Info *error_info, const char *value)
{
E_Music_Control_Module_Context *ctxt = data;
}
static void
+cb_metadata_get(void *data, Eldbus_Pending *p, const char *propname, Eldbus_Proxy *proxy, Eldbus_Error_Info *error_info, Eina_Value *value)
+{
+ E_Music_Control_Module_Context *ctxt = data;
+ parse_metadata(ctxt, value);
+ music_control_metadata_update_all(ctxt);
+}
+
+static void
prop_changed(void *data, Eldbus_Proxy *proxy, void *event_info)
{
Eldbus_Proxy_Event_Property_Changed *event = event_info;
ctxt->playing = EINA_FALSE;
music_control_state_update_all(ctxt);
}
+ else if (!strcmp(event->name, "Metadata"))
+ {
+ parse_metadata(ctxt, (Eina_Value*)event->value);
+ music_control_metadata_update_all(ctxt);
+ }
}
Eina_Bool
ctxt->mrpis2 = mpris_media_player2_proxy_get(ctxt->conn, bus, NULL);
ctxt->mpris2_player = media_player2_player_proxy_get(ctxt->conn, bus, NULL);
media_player2_player_playback_status_propget(ctxt->mpris2_player, cb_playback_status_get, ctxt);
+ media_player2_player_metadata_propget(ctxt->mpris2_player, cb_metadata_get, ctxt);
eldbus_proxy_event_callback_add(ctxt->mpris2_player, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
prop_changed, ctxt);
return EINA_TRUE;
EINA_SAFETY_ON_NULL_RETURN_VAL(music_control_mod, 0);
ctxt = music_control_mod->data;
+ E_FREE_FUNC(ctxt->meta_title, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_album, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_artist, eina_stringshare_del);
+ E_FREE_FUNC(ctxt->meta_cover, eina_stringshare_del);
+
free(ctxt->config);
E_CONFIG_DD_FREE(ctxt->conf_edd);
Eina_List *instances;
Eldbus_Connection *conn;
Eina_Bool playing:1;
+ Eina_Stringshare *meta_artist;
+ Eina_Stringshare *meta_album;
+ Eina_Stringshare *meta_title;
+ Eina_Stringshare *meta_cover;
Eldbus_Proxy *mrpis2;
Eldbus_Proxy *mpris2_player;
E_Config_DD *conf_edd;
const char *music_control_edj_path_get(void);
void music_control_popup_del(E_Music_Control_Instance *inst);
void music_control_state_update_all(E_Music_Control_Module_Context *ctxt);
+void music_control_metadata_update_all(E_Music_Control_Module_Context *ctxt);
Eina_Bool music_control_dbus_init(E_Music_Control_Module_Context *ctxt, const char *bus);
Eina_Bool _desklock_cb(void *data, int type, void *ev);
}
static void
+_metadata_update(E_Music_Control_Instance *inst)
+{
+ Eina_Strbuf *str;
+ Evas_Object *img;
+
+ if (!inst->popup) return;
+
+ str = eina_strbuf_new();
+
+ if (inst->ctxt->meta_title)
+ eina_strbuf_append_printf(str, "<title>%s</><br>", inst->ctxt->meta_title);
+ if (inst->ctxt->meta_artist)
+ eina_strbuf_append_printf(str, "<tag>by</> %s<br>", inst->ctxt->meta_artist);
+ if (inst->ctxt->meta_album)
+ eina_strbuf_append_printf(str, "<tag>from</> %s<br>", inst->ctxt->meta_album);
+ edje_object_part_text_set(inst->content_popup, "metadata", eina_strbuf_string_get(str));
+ eina_strbuf_free(str);
+
+ img = edje_object_part_swallow_get(inst->content_popup, "cover_swallow");
+ E_FREE_FUNC(img, evas_object_del);
+
+ if (inst->ctxt->meta_cover)
+ {
+ img = evas_object_image_filled_add(evas_object_evas_get(inst->content_popup));
+ evas_object_image_file_set(img, inst->ctxt->meta_cover, NULL);
+ edje_object_part_swallow(inst->content_popup, "cover_swallow", img);
+ }
+}
+
+void
+music_control_metadata_update_all(E_Music_Control_Module_Context *ctxt)
+{
+ E_Music_Control_Instance *inst;
+ Eina_List *list;
+
+ EINA_LIST_FOREACH(ctxt->instances, list, inst)
+ _metadata_update(inst);
+}
+
+static void
_btn_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source)
{
E_Music_Control_Instance *inst = data;
_player_name_update(inst);
_play_state_update(inst, EINA_TRUE);
+ _metadata_update(inst);
e_popup_autoclose(inst->popup->win, NULL, NULL, NULL);
e_gadcon_popup_show(inst->popup);
e_object_data_set(E_OBJECT(inst->popup), inst);
void
music_control_popup_del(E_Music_Control_Instance *inst)
{
+ Evas_Object *cover;
+
+ cover = edje_object_part_swallow_get(inst->content_popup, "cover_swallow");
+ E_FREE_FUNC(cover, evas_object_del);
+
E_FREE_FUNC(inst->popup, e_object_del);
}