update for beta release
[framework/uifw/e17.git] / src / modules / mixer / conf_gadget.c
1 #include "e_mod_main.h"
2
3 extern const char _e_mixer_Name[];
4
5 struct _E_Config_Dialog_Data
6 {
7    int lock_sliders;
8    int show_locked;
9    int keybindings_popup;
10    int card_num;
11    int channel;
12    const char *card;
13    const char *channel_name;
14    Eina_List *cards;
15    Eina_List *cards_names;
16    Eina_List *channels_names;
17    struct mixer_config_ui
18    {
19       Evas_Object *table;
20       struct mixer_config_ui_general
21       {
22          Evas_Object *frame;
23          Evas_Object *lock_sliders;
24          Evas_Object *show_locked;
25          Evas_Object *keybindings_popup;
26       } general;
27       struct mixer_config_ui_cards
28       {
29          Evas_Object *frame;
30          E_Radio_Group *radio;
31       } cards;
32       struct mixer_config_ui_channels
33       {
34          Evas_Object *frame;
35          Evas_Object *scroll;
36          Evas_Object *list;
37          E_Radio_Group *radio;
38          Eina_List *radios;
39       } channels;
40    } ui;
41    E_Mixer_Gadget_Config *conf;
42 };
43
44 static void
45 _mixer_fill_cards_info(E_Config_Dialog_Data *cfdata)
46 {
47    const char *card;
48    const char *name;
49    Eina_List *l;
50    int i = 0;
51
52    cfdata->card_num = -1;
53    cfdata->cards = e_mod_mixer_cards_get();
54    cfdata->cards_names = NULL;
55    EINA_LIST_FOREACH(cfdata->cards, l, card)
56      {
57         name = e_mod_mixer_card_name_get(card);
58         if ((cfdata->card_num < 0) && card && cfdata->card &&
59             (strcmp(card, cfdata->card) == 0))
60           cfdata->card_num = i;
61
62         cfdata->cards_names = eina_list_append(cfdata->cards_names, name);
63
64         i++;
65      }
66
67    if (cfdata->card_num < 0)
68      cfdata->card_num = 0;
69 }
70
71 static void
72 _mixer_fill_channels_info(E_Config_Dialog_Data *cfdata)
73 {
74    E_Mixer_System *sys;
75    const char *channel;
76    Eina_List *l;
77    int i = 0;
78
79    sys = e_mod_mixer_new(cfdata->card);
80    if (!sys)
81      return;
82
83    cfdata->channel = 0;
84    cfdata->channel_name = eina_stringshare_add(cfdata->conf->channel_name);
85    cfdata->channels_names = e_mod_mixer_channels_names_get(sys);
86    EINA_LIST_FOREACH(cfdata->channels_names, l, channel)
87      {
88         if (channel && cfdata->channel_name &&
89             (channel == cfdata->channel_name ||
90              strcmp(channel, cfdata->channel_name) == 0))
91           {
92              cfdata->channel = i;
93              break;
94           }
95
96         i++;
97      }
98    e_mod_mixer_del(sys);
99 }
100
101 static void *
102 _create_data(E_Config_Dialog *dialog)
103 {
104    E_Config_Dialog_Data *cfdata;
105    E_Mixer_Gadget_Config *conf;
106
107    cfdata = E_NEW(E_Config_Dialog_Data, 1);
108    if (!cfdata)
109      return NULL;
110
111    conf = dialog->data;
112    cfdata->conf = conf;
113    cfdata->lock_sliders = conf->lock_sliders;
114    cfdata->show_locked = conf->show_locked;
115    cfdata->keybindings_popup = conf->keybindings_popup;
116    cfdata->card = eina_stringshare_add(conf->card);
117    _mixer_fill_cards_info(cfdata);
118    _mixer_fill_channels_info(cfdata);
119
120    return cfdata;
121 }
122
123 static void
124 _free_data(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
125 {
126    E_Mixer_Gadget_Config *conf = dialog->data;
127    const char *card;
128
129    if (conf)
130      conf->dialog = NULL;
131
132    if (!cfdata)
133      return;
134
135    EINA_LIST_FREE(cfdata->cards_names, card)
136      eina_stringshare_del(card);
137
138    if (cfdata->channels_names)
139      e_mod_mixer_channels_free(cfdata->channels_names);
140    if (cfdata->cards)
141      e_mod_mixer_cards_free(cfdata->cards);
142
143    eina_stringshare_del(cfdata->card);
144    eina_stringshare_del(cfdata->channel_name);
145
146    eina_list_free(cfdata->ui.channels.radios);
147
148    E_FREE(cfdata);
149 }
150
151 static int
152 _basic_apply(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
153 {
154    E_Mixer_Gadget_Config *conf = dialog->data;
155    const char *card, *channel;
156
157    conf->lock_sliders = cfdata->lock_sliders;
158    conf->show_locked = cfdata->show_locked;
159    conf->keybindings_popup = cfdata->keybindings_popup;
160
161    card = eina_list_nth(cfdata->cards, cfdata->card_num);
162    if (card)
163      {
164         eina_stringshare_del(conf->card);
165         conf->card = eina_stringshare_ref(card);
166      }
167
168    channel = eina_list_nth(cfdata->channels_names, cfdata->channel);
169    if (channel)
170      {
171         eina_stringshare_del(conf->channel_name);
172         conf->channel_name = eina_stringshare_ref(channel);
173      }
174
175    e_mixer_update(conf->instance);
176    return 1;
177 }
178
179 static void
180 _lock_change(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
181 {
182    E_Config_Dialog_Data *cfdata = data;
183    e_widget_disabled_set(cfdata->ui.general.show_locked, !cfdata->lock_sliders);
184 }
185
186 static void
187 _basic_create_general(Evas *evas, E_Config_Dialog_Data *cfdata)
188 {
189    struct mixer_config_ui_general *ui = &cfdata->ui.general;
190
191    ui->frame = e_widget_framelist_add(evas, _("General Settings"), 0);
192
193    ui->lock_sliders = e_widget_check_add(
194                                          evas, _("Lock Sliders"), &cfdata->lock_sliders);
195    evas_object_smart_callback_add(
196                                   ui->lock_sliders, "changed", _lock_change, cfdata);
197    e_widget_framelist_object_append(ui->frame, ui->lock_sliders);
198
199    ui->show_locked = e_widget_check_add(
200                                         evas, _("Show both sliders when locked"), &cfdata->show_locked);
201    e_widget_disabled_set(ui->show_locked, !cfdata->lock_sliders);
202    e_widget_framelist_object_append(ui->frame, ui->show_locked);
203
204    ui->keybindings_popup = e_widget_check_add(
205                                         evas, _("Show Popup on volume change via keybindings"), &cfdata->keybindings_popup);
206    e_widget_framelist_object_append(ui->frame, ui->keybindings_popup);
207 }
208
209 static void
210 _clear_channels(E_Config_Dialog_Data *cfdata)
211 {
212    Evas_Object *o;
213
214    EINA_LIST_FREE(cfdata->ui.channels.radios, o)
215      evas_object_del(o);
216 }
217
218 static void
219 _fill_channels(Evas *evas, E_Config_Dialog_Data *cfdata)
220 {
221    struct mixer_config_ui_channels *ui = &cfdata->ui.channels;;
222    Evas_Object *selected;
223    Evas_Coord mw, mh;
224    const char *name;
225    Eina_List *l;
226    int i = 0;
227
228    ui->radio = e_widget_radio_group_new(&cfdata->channel);
229    EINA_LIST_FOREACH(cfdata->channels_names, l, name)
230      {
231         Evas_Object *ow;
232
233         if (!name) continue;
234
235         ow = e_widget_radio_add(evas, name, i, ui->radio);
236         ui->radios = eina_list_append(ui->radios, ow);
237         e_widget_list_object_append(ui->list, ow, 1, 1, 0.0);
238
239         ++i;
240      }
241
242    e_widget_size_min_get(ui->list, &mw, &mh);
243    evas_object_resize(ui->list, mw, mh);
244
245    selected = eina_list_nth(ui->radios, cfdata->channel);
246    if (selected)
247      {
248         Evas_Coord x, y, w, h, lx, ly;
249         evas_object_geometry_get(selected, &x, &y, &w, &h);
250         evas_object_geometry_get(ui->list, &lx, &ly, NULL, NULL);
251         x -= lx;
252         y -= ly - 10;
253         h += 20;
254         e_widget_scrollframe_child_region_show(ui->scroll, x, y, w, h);
255      }
256 }
257
258 static void
259 _channel_scroll_set_min_size(struct mixer_config_ui_channels *ui)
260 {
261    Evas_Coord w, h;
262    int len = eina_list_count(ui->radios);
263    if (len < 1)
264      return;
265
266    e_widget_size_min_get(ui->list, &w, &h);
267    h = 4 * h / len;
268    e_widget_size_min_set(ui->scroll, w, h);
269 }
270
271 static void
272 _basic_create_channels(Evas *evas, E_Config_Dialog_Data *cfdata)
273 {
274    struct mixer_config_ui_channels *ui = &cfdata->ui.channels;
275
276    ui->list = e_widget_list_add(evas, 1, 0);
277    ui->scroll = e_widget_scrollframe_simple_add(evas, ui->list);
278    ui->frame = e_widget_framelist_add(evas, _("Channels"), 0);
279
280    _fill_channels(evas, cfdata);
281
282    _channel_scroll_set_min_size(ui);
283    e_widget_framelist_object_append(ui->frame, ui->scroll);
284 }
285
286 static void
287 _card_change(void *data, Evas_Object *obj, void *event __UNUSED__)
288 {
289    E_Config_Dialog_Data *cfdata = data;
290    Evas *evas;
291    char *card;
292
293    eina_stringshare_del(cfdata->card);
294
295    e_mod_mixer_channels_free(cfdata->channels_names);
296
297    eina_stringshare_del(cfdata->channel_name);
298
299    card = eina_list_nth(cfdata->cards, cfdata->card_num);
300    cfdata->card = eina_stringshare_add(card);
301    _mixer_fill_channels_info(cfdata);
302
303    evas = evas_object_evas_get(obj);
304    _clear_channels(cfdata);
305    _fill_channels(evas, cfdata);
306 }
307
308 static void
309 _basic_create_cards(Evas *evas, E_Config_Dialog_Data *cfdata)
310 {
311    struct mixer_config_ui_cards *ui = &cfdata->ui.cards;
312    const char *card;
313    Eina_List *l;
314    int i = 0;
315
316    ui->frame = e_widget_framelist_add(evas, _("Sound Cards"), 0);
317    ui->radio = e_widget_radio_group_new(&cfdata->card_num);
318    EINA_LIST_FOREACH(cfdata->cards_names, l, card)
319      {
320         Evas_Object *ow;
321
322         if (!card) continue;
323
324         ow = e_widget_radio_add(evas, card, i, ui->radio);
325         e_widget_framelist_object_append(ui->frame, ow);
326         evas_object_smart_callback_add(ow, "changed", _card_change, cfdata);
327
328         ++i;
329      }
330 }
331
332 static Evas_Object *
333 _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
334 {
335    if (!cfdata)
336      return NULL;
337
338    cfdata->ui.table = e_widget_table_add(evas, 0);
339    _basic_create_general(evas, cfdata);
340    _basic_create_cards(evas, cfdata);
341    _basic_create_channels(evas, cfdata);
342
343    e_widget_table_object_append(cfdata->ui.table, cfdata->ui.general.frame,
344                                 0, 0, 1, 1, 1, 1, 1, 0);
345    e_widget_table_object_append(cfdata->ui.table, cfdata->ui.cards.frame,
346                                 0, 1, 1, 1, 1, 1, 1, 0);
347    e_widget_table_object_append(cfdata->ui.table, cfdata->ui.channels.frame,
348                                 0, 2, 1, 1, 1, 1, 1, 1);
349
350    return cfdata->ui.table;
351 }
352
353 void
354 e_mixer_config_pulse_toggle(void)
355 {
356
357 }
358
359 E_Config_Dialog *
360 e_mixer_config_dialog_new(E_Container *con, E_Mixer_Gadget_Config *conf)
361 {
362    E_Config_Dialog *dialog;
363    E_Config_Dialog_View *view;
364
365    if (e_config_dialog_find(_e_mixer_Name, "e_mixer_config_dialog_new"))
366      return NULL;
367
368    view = E_NEW(E_Config_Dialog_View, 1);
369    if (!view)
370      return NULL;
371
372    view->create_cfdata = _create_data;
373    view->free_cfdata = _free_data;
374    view->basic.create_widgets = _basic_create;
375    view->basic.apply_cfdata = _basic_apply;
376
377    dialog = e_config_dialog_new(con, _("Mixer Settings"),
378                                 _e_mixer_Name, "e_mixer_config_dialog_new",
379                                 e_mixer_theme_path(), 0, view, conf);
380    e_dialog_resizable_set(dialog->dia, 1);
381
382    return dialog;
383 }