From 718ef898d75829448123b28983f3362dc3fa0075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Bouchaud=20=28yoz=29?= Date: Sat, 15 Oct 2016 13:38:37 +0200 Subject: [PATCH] e_client: add a volume control to the window theme This commit brings 2 objects to the group "e/widgets/border/default/border", an icon and a slider. If you click the icon the volume is muted. The slider set the volume level. Theme part added "e.swallow.volume_icon" and "e.swallow.volume" @features --- src/bin/e_client_volume.c | 141 ++++++++++++++++++++++++++++++++++++++ src/bin/e_comp_object.c | 48 ++++++++++++- src/bin/e_comp_object.h | 1 + 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/bin/e_client_volume.c b/src/bin/e_client_volume.c index 1d6a9f64b..f00ca6714 100644 --- a/src/bin/e_client_volume.c +++ b/src/bin/e_client_volume.c @@ -4,6 +4,13 @@ E_API int E_EVENT_CLIENT_VOLUME = -1; E_API int E_EVENT_CLIENT_MUTE = -1; E_API int E_EVENT_CLIENT_UNMUTE = -1; +static void _e_client_volume_event_simple_free(void *d, E_Event_Client *ev); +static void _e_client_volume_event_simple(E_Client *ec, int type); +static void _e_client_volume_object_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_client_volume_object_volume_changed(void *data, Evas_Object *obj, void *event_info); +static Eina_Bool _e_client_volume_object_changed(void *data, int type, void *event); +static void _e_client_volume_object_del_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info); + static void _e_client_volume_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev) { @@ -25,6 +32,76 @@ _e_client_volume_event_simple(E_Client *ec, int type) (Ecore_End_Cb)_e_client_volume_event_simple_free, NULL); } +static void +_e_client_volume_object_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + int val; + E_Client *ec; + + ec = data; + + e_client_volume_mute_set(ec, !(ec->mute)); +} + +static void +_e_client_volume_object_volume_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + int val; + E_Client *ec; + + ec = data; + + e_client_volume_set(ec, elm_slider_value_get(obj)); +} + +static Eina_Bool +_e_client_volume_object_changed(void *data, int type, void *event) +{ + E_Event_Client *ev; + Evas_Object *o; + Evas_Object *bx; + Edje_Message_Int_Set *msg; + + ev = event; + bx = data; + + o = edje_object_part_swallow_get(bx, "e.swallow.volume_icon"); + if (o) + { + msg = alloca(sizeof(Edje_Message_Int_Set) + (2 * sizeof(int))); + msg->count = 3; + msg->val[0] = ev->ec->mute; + msg->val[1] = ev->ec->volume; + msg->val[2] = msg->val[1]; + edje_object_message_send(o, EDJE_MESSAGE_INT_SET, 0, msg); + edje_object_signal_emit(o, "e,action,volume,change", "e"); + } + o = edje_object_part_swallow_get(bx, "e.swallow.volume"); + if (o) + { + elm_slider_value_set(o, ev->ec->volume); + } + + return ECORE_CALLBACK_PASS_ON; +} + +static void +_e_client_volume_object_del_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Eina_List *handlers; + Evas_Object *o; + + handlers = data; + + o = edje_object_part_swallow_get(obj, "e.swallow.volume_icon"); + if (o) evas_object_del(o); + o = edje_object_part_swallow_get(obj, "e.swallow.volume"); + if (o) evas_object_del(o); + + E_FREE_LIST(handlers, ecore_event_handler_del); +} + + EINTERN int e_client_volume_init(void) @@ -142,6 +219,7 @@ e_client_volume_sink_append(E_Client *ec, E_Client_Volume_Sink *sink) ec->mute = !!mute; ec->volume_control_enabled = EINA_TRUE; } + e_comp_object_frame_volume_update(ec->frame); } E_API void @@ -150,6 +228,7 @@ e_client_volume_sink_remove(E_Client *ec, E_Client_Volume_Sink *sink) EINA_SAFETY_ON_NULL_RETURN(ec); ec->sinks = eina_list_remove(ec->sinks, sink); sink->clients = eina_list_remove(sink->clients, ec); + e_comp_object_frame_volume_update(ec->frame); } E_API void @@ -211,3 +290,65 @@ e_client_volume_mute_set(E_Client *ec, Eina_Bool mute) _e_client_volume_event_simple(ec, E_EVENT_CLIENT_UNMUTE); } +E_API Evas_Object * +e_client_volume_object_add(E_Client *ec, Evas *evas) +{ + Evas_Object *bx, *o; + Edje_Message_Int_Set *msg; + Eina_List *handlers = NULL; + + bx = edje_object_add(evas); + e_theme_edje_object_set(bx, + "base/theme/border/volume", + "e/widgets/border/volume"); + + if (edje_object_part_exists(bx, "e.swallow.volume_icon")) + { + o = edje_object_add(evas); + e_theme_edje_object_set(o, + "base/theme/modules/mixer", + "e/modules/mixer/main"); + + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, + _e_client_volume_object_mouse_down_cb, + ec); + edje_object_part_swallow(bx, "e.swallow.volume_icon", o); + msg = alloca(sizeof(Edje_Message_Int_Set) + (2 * sizeof(int))); + msg->count = 3; + msg->val[0] = ec->mute; + msg->val[1] = ec->volume; + msg->val[2] = msg->val[1]; + edje_object_message_send(o, EDJE_MESSAGE_INT_SET, 0, msg); + edje_object_signal_emit(o, "e,action,volume,change", "e"); + evas_object_show(o); + + } + if (edje_object_part_exists(bx, "e.swallow.volume")) + { + o = edje_object_add(evas); + o = elm_slider_add(bx); + elm_slider_min_max_set(o, ec->volume_min, + ec->volume_max); + elm_slider_span_size_set(o, ec->volume_max + * elm_config_scale_get()); + elm_slider_unit_format_set(o, "%.0f"); + elm_slider_indicator_format_set(o, "%.0f"); + evas_object_smart_callback_add(o, "changed", + _e_client_volume_object_volume_changed, + ec); + elm_slider_value_set(o, ec->volume); + edje_object_part_swallow(bx, "e.swallow.volume", o); + evas_object_show(o); + } + + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_VOLUME, + _e_client_volume_object_changed, bx); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_MUTE, + _e_client_volume_object_changed, bx); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_UNMUTE, + _e_client_volume_object_changed, bx); + + evas_object_event_callback_add(bx, EVAS_CALLBACK_DEL, + _e_client_volume_object_del_cb, handlers); + return bx; +} diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index b1fc5cae9..9a51edfc9 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -86,6 +86,7 @@ typedef struct _E_Comp_Object Evas_Object *zoomobj; // zoomap Evas_Object *shobj; // shadow object Evas_Object *effect_obj; // effects object + Evas_Object *frame_volume; // volume level object unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer) Eina_List *obj_mirror; // extra mirror objects Eina_List *obj_agent; // extra agent objects @@ -746,6 +747,7 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw) { edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj); edje_object_part_swallow(cw->frame_object, "e.swallow.icon", cw->frame_icon); + edje_object_part_swallow(cw->frame_object, "e.swallow.volume", cw->frame_volume); if (cw->zoomap_disabled) edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object); else @@ -2410,6 +2412,7 @@ _e_comp_smart_del(Evas_Object *obj) evas_object_del(cw->effect_obj); evas_object_del(cw->shobj); evas_object_del(cw->frame_icon); + evas_object_del(cw->frame_volume); evas_object_del(cw->frame_object); evas_object_del(cw->zoomobj); evas_object_del(cw->input_obj); @@ -3271,6 +3274,33 @@ e_comp_object_frame_icon_update(Evas_Object *obj) E_FREE_FUNC(cw->frame_icon, evas_object_del); } +E_API void +e_comp_object_frame_volume_update(Evas_Object *obj) +{ + Evas_Object *o; + + API_ENTRY; + + if (!cw->frame_object) return; + if (edje_object_part_exists(cw->frame_object, "e.swallow.volume")) + { + if (cw->ec->sinks) + { + if (!cw->frame_volume) + { + cw->frame_volume = e_client_volume_object_add(cw->ec, e_comp->evas); + edje_object_part_swallow(cw->frame_object, + "e.swallow.volume", cw->frame_volume); + evas_object_show(cw->frame_volume); + } + } + else + { + E_FREE_FUNC(cw->frame_volume, evas_object_del); + } + } +} + E_API Eina_Bool e_comp_object_frame_theme_set(Evas_Object *obj, const char *name) { @@ -3309,6 +3339,7 @@ e_comp_object_frame_theme_set(Evas_Object *obj, const char *name) { cw->frame_object = NULL; E_FREE_FUNC(cw->frame_icon, evas_object_del); + E_FREE_FUNC(cw->frame_volume, evas_object_del); evas_object_del(o); eina_stringshare_del(cw->frame_theme); cw->frame_theme = theme; @@ -3348,21 +3379,36 @@ e_comp_object_frame_theme_set(Evas_Object *obj, const char *name) { if (cw->frame_icon) { - if (!edje_object_part_swallow(cw->frame_object, "e.swallow.icon", cw->frame_icon)) + if (!edje_object_part_swallow(cw->frame_object, + "e.swallow.icon", + cw->frame_icon)) E_FREE_FUNC(cw->frame_icon, evas_object_del); } + if (cw->frame_volume) + { + if (!edje_object_part_swallow(cw->frame_object, + "e.swallow.volume", + cw->frame_volume)) + E_FREE_FUNC(cw->frame_volume, evas_object_del); + } } else { cw->ec->changes.icon = 1; EC_CHANGED(cw->ec); } + + if (cw->ec->volume_control_enabled) + { + e_comp_object_frame_volume_update(obj); + } } else { CRI("USER IS USING A SHITTY THEME! ABORT!!!!"); evas_object_del(o); E_FREE_FUNC(cw->frame_icon, evas_object_del); + E_FREE_FUNC(cw->frame_volume, evas_object_del); } reshadow: if (cw->shobj) diff --git a/src/bin/e_comp_object.h b/src/bin/e_comp_object.h index 1701aceb8..a6500a377 100644 --- a/src/bin/e_comp_object.h +++ b/src/bin/e_comp_object.h @@ -91,6 +91,7 @@ E_API Eina_Bool e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_ E_API Eina_Bool e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb); E_API E_Comp_Object_Mover *e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data); E_API void e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov); +E_API void e_comp_object_frame_volume_update(Evas_Object *obj); #endif #endif