summaryrefslogblamecommitdiff
path: root/src/bin/sinks_view.c
blob: dbbfabcf5bb444aa085768da1d64a48e694aaf28 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                       
                 


                             




                               

  

                         

                                
                                  

 

                                   

                                
                          
 

                                                            

 

                                     

                                

                                                                   
 
            
      


                                                      



                                            

                                                         
      

 

                                     

                                


                                                                   
 
               
      
                                                   
           


                                                                 
 


                                                                 














                                                                       

                   
                                               
      


           
                                                              
 















                                         
      
 
 




                                                                                




                                                                          
                          









                                  


                                                
                          
                                        

                      
 



                                                                    
 

                                      





                                                        
                          
 
                                        


           
                                                               
 
                          
                                      
                                                    
 
                                       

                                       
                                                





                                                                 
                          


                               


                                                   
                                                        



                                                       
                                                            








                                                                 

                                                                        







                                                                         
                      
                     





                                             
                                                               

                                                            
                                                           







                                                                



                                   
                
                         
                   



                                             
                                                          






                                                                          
                                           





                                                  








                                                                  





                                                                 


                 





                
#include "sinks_view.h"

#include <emix.h>

#define SINKS_KEY "sinks.key"

struct Sinks_View
{
   Evas_Object *self;
   Evas_Object *genlist;
   Elm_Genlist_Item_Class *itc;
};

static void
_disconnected(void *data)
{
   struct Sinks_View *sv = data;
   elm_genlist_clear(sv->genlist);
}

static void
_sink_added(void *data, void *info)
{
   struct Sinks_View *sv = data;
   Emix_Sink *sink = info;

   elm_genlist_item_append(sv->genlist, sv->itc, sink, NULL,
                           ELM_GENLIST_ITEM_NONE, NULL, sv);
}

static void
_sink_removed(void *data, void *info)
{
   struct Sinks_View *sv = data;
   Emix_Sink *ev = info;
   Elm_Object_Item *item = elm_genlist_first_item_get(sv->genlist);

   if (item)
     {
        do
          {
             if (ev == elm_object_item_data_get(item))
               {
                  elm_object_item_del(item);
                  break;
               }
          }
        while ((item = elm_genlist_item_next_get(item)));
     }
}

static void
_sink_changed(void *data, void *info)
{
   struct Sinks_View *sv = data;
   Emix_Sink *sink = info;
   Elm_Object_Item *item = elm_genlist_first_item_get(sv->genlist);
   Evas_Object *it;

   while (item)
     {
        if (sink == elm_object_item_data_get(item))
          {
             it = elm_object_item_part_content_get(item, "item");
             if (it)
               elm_slider_value_set(it, sink->volume.volumes[0]);

             it = elm_object_item_part_content_get(item, "mute");
             if (it)
               elm_check_state_set(it, sink->mute);

             it = elm_object_item_part_content_get(item, "hover");
             if (it)
               {
                  Eina_List *l;
                  Emix_Port *sp;
                  elm_hoversel_clear(it);
                  EINA_LIST_FOREACH(sink->ports, l, sp)
                    {
                       elm_hoversel_item_add(it, sp->description, NULL,
                                             ELM_ICON_NONE, NULL, sp);
                       if (sp->active)
                         elm_object_text_set(it, sp->description);
                    }
               }
             break;
          }
        item = elm_genlist_item_next_get(item);
     }
}

static void
_events_cb(void *data, enum Emix_Event type, void *event_info)
{
   switch (type)
     {
      case EMIX_SINK_ADDED_EVENT:
         _sink_added(data, event_info);
         break;
      case EMIX_SINK_CHANGED_EVENT:
         _sink_changed(data, event_info);
         break;
      case EMIX_SINK_REMOVED_EVENT:
         _sink_removed(data, event_info);
         break;
      case EMIX_DISCONNECTED_EVENT:
         _disconnected(data);
         break;
      default:
         break;
     }
}

static void
_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED,
        void *event_info EINA_UNUSED)
{
   emix_event_callback_del(_events_cb);
}

static char *
_item_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part)
{
   Emix_Sink *sink = data;

   if (!strcmp(part, "name"))
     {
        return strdup(sink->name);
     }

   return NULL;
}

static void
_volume_changed_cb(void *data, Evas_Object *o,
                   void *event_info EINA_UNUSED)
{
   Emix_Sink *sink = data;
   double val = elm_slider_value_get(o);
   Emix_Volume volume;
   unsigned int i;

   volume.channel_count = sink->volume.channel_count;
   volume.volumes = calloc(sink->volume.channel_count, sizeof(int));
   for (i = 0; i < volume.channel_count; i++)
      volume.volumes[i] = val;

   emix_sink_volume_set(sink, volume);
   free(volume.volumes);
}

static void
_mute_changed_cb(void *data, Evas_Object *o EINA_UNUSED,
                 void *event_info EINA_UNUSED)
{
   Emix_Sink *sink = data;

   emix_sink_mute_set(sink, sink->mute);
}

static void
_port_selected_cb(void *data, Evas_Object *o, void *event_info)
{
   Emix_Sink *sink = data;
   Elm_Object_Item *item = event_info;
   Emix_Port *port = elm_object_item_data_get(item);

   if (!emix_sink_port_set(sink, port))
      ERR("Could not change the port");
   else
      elm_object_text_set(o, port->description);
}

static Evas_Object *
_item_content_get(void *data, Evas_Object *obj, const char *part)
{
   Evas_Object *item = NULL;
   Emix_Sink *sink = data;

   if (!strcmp(part, "slider"))
     {
        item = elm_slider_add(obj);
        EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);

        elm_slider_step_set(item, 1.0/BASE_VOLUME_STEP);
        elm_slider_unit_format_set(item, "%1.0f");
        elm_slider_indicator_format_set(item, "%1.0f");
        elm_slider_span_size_set(item, 120);
        elm_slider_min_max_set(item, 0.0, 100.0);
        elm_slider_value_set(item, sink->volume.volumes[0]);
        evas_object_smart_callback_add(item, "delay,changed",
                                       _volume_changed_cb, sink);
     }
   else if (!strcmp(part, "mute"))
     {
        item = elm_check_add(obj);
        EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);

        elm_object_style_set(item, "toggle");
        elm_object_translatable_part_text_set(item, "off", N_("Mute"));
        elm_object_translatable_part_text_set(item, "on", N_("Unmute"));

        elm_check_state_set(item, sink->mute);
        elm_check_state_pointer_set(item, &sink->mute);
        evas_object_smart_callback_add(item, "changed", _mute_changed_cb,
                                       sink);
     }
   else if (!strcmp(part, "hover"))
     {
        Emix_Port *sp;
        Eina_List *l;

        if (sink->ports)
           item = elm_hoversel_add(obj);

        EINA_LIST_FOREACH(sink->ports, l, sp)
          {
             elm_hoversel_item_add(item, sp->description, NULL,
                                   ELM_ICON_NONE, NULL, sp);
             if (sp->active)
                elm_object_text_set(item, sp->description);
          }
        evas_object_smart_callback_add(item, "selected",
                                       _port_selected_cb, sink);
     }

   return item;
}

Evas_Object *
sinks_view_add(Evas_Object *parent)
{
   Evas_Object *layout;
   Eina_List *l;
   struct Sinks_View *sv;
   Emix_Sink *sink;

   sv = calloc(1, sizeof(struct Sinks_View));
   EINA_SAFETY_ON_NULL_RETURN_VAL(sv, NULL);

   layout = emixer_layout_add(parent, "sinks", "default");
   EINA_SAFETY_ON_NULL_GOTO(layout, err);

   evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, _del_cb, sv);

   sv->genlist = elm_genlist_add(layout);
   EINA_SAFETY_ON_NULL_GOTO(sv->genlist, err_genlist);

   emix_event_callback_add(_events_cb, sv);

   sv->itc = elm_genlist_item_class_new();
   EINA_SAFETY_ON_NULL_GOTO(sv->itc, err_genlist);
   sv->itc->item_style = "sinks";
   sv->itc->func.text_get = _item_text_get;
   sv->itc->func.content_get = _item_content_get;

   evas_object_data_set(layout, SINKS_KEY, sv);
   elm_layout_content_set(layout, "list", sv->genlist);

   evas_object_size_hint_weight_set(sv->genlist, EVAS_HINT_EXPAND,
                                    EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(sv->genlist, EVAS_HINT_FILL,
                                   EVAS_HINT_FILL);

   EINA_LIST_FOREACH((Eina_List *)emix_sinks_get(), l, sink)
     {
        elm_genlist_item_append(sv->genlist, sv->itc, sink, NULL,
                                ELM_GENLIST_ITEM_NONE, NULL, sv);
     }

   return layout;

 err_genlist:
   free(layout);
 err:
   free(sv);

   return NULL;
}