From 9e207e6f9275b1d6e34d90f435508fa523441f79 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 3 Jan 2013 14:47:21 +0000 Subject: [PATCH] conf2 SVN revision: 82078 --- .gitignore | 1 + ChangeLog | 6 + NEWS | 11 +- configure.ac | 2 + src/bin/Makefile.am | 2 + src/bin/e_config.c | 4 + src/bin/e_config.h | 5 +- src/bin/e_configure_option.c | 2687 +++++++++++++++++ src/bin/e_configure_option.h | 172 ++ src/bin/e_includes.h | 1 + src/bin/e_main.c | 5 + src/bin/e_module.c | 2 + src/bin/e_remember.c | 3 +- src/bin/e_win.c | 10 + src/bin/e_win.h | 1 + src/modules/Makefile.am | 4 + src/modules/Makefile_conf2.am | 74 + src/modules/conf2/e-module-conf2.edc | 2192 ++++++++++++++ src/modules/conf2/e_conf2.c | 1326 ++++++++ src/modules/conf2/e_mod_main.c | 381 +++ src/modules/conf2/e_mod_main.h | 30 + src/modules/conf2/images/volume_knob.png | Bin 0 -> 16375 bytes .../conf2/images/volume_knob_ledsoff.png | Bin 0 -> 4066 bytes src/modules/conf2/images/volume_knob_move.png | Bin 0 -> 28115 bytes src/modules/conf2/images/volume_led_01.png | Bin 0 -> 761 bytes src/modules/conf2/images/volume_led_02.png | Bin 0 -> 757 bytes src/modules/conf2/images/volume_led_03.png | Bin 0 -> 738 bytes src/modules/conf2/images/volume_led_04.png | Bin 0 -> 742 bytes src/modules/conf2/images/volume_led_05.png | Bin 0 -> 700 bytes src/modules/conf2/images/volume_led_06.png | Bin 0 -> 710 bytes src/modules/conf2/images/volume_led_07.png | Bin 0 -> 665 bytes src/modules/conf2/images/volume_led_08.png | Bin 0 -> 585 bytes src/modules/conf2/images/volume_led_09.png | Bin 0 -> 655 bytes src/modules/conf2/images/volume_led_10.png | Bin 0 -> 705 bytes src/modules/conf2/images/volume_led_11.png | Bin 0 -> 743 bytes src/modules/conf2/images/volume_led_12.png | Bin 0 -> 738 bytes src/modules/conf2/images/volume_led_13.png | Bin 0 -> 755 bytes src/modules/conf2/images/volume_led_14.png | Bin 0 -> 755 bytes src/modules/conf2/images/volume_led_15.png | Bin 0 -> 745 bytes src/modules/conf2/images/volume_led_16.png | Bin 0 -> 716 bytes src/modules/conf2/images/volume_led_17.png | Bin 0 -> 753 bytes src/modules/conf2/images/volume_led_18.png | Bin 0 -> 752 bytes src/modules/conf2/images/volume_led_19.png | Bin 0 -> 733 bytes src/modules/conf2/images/volume_led_20.png | Bin 0 -> 716 bytes src/modules/conf2/images/volume_led_21.png | Bin 0 -> 709 bytes src/modules/conf2/images/volume_led_22.png | Bin 0 -> 681 bytes src/modules/conf2/images/volume_led_23.png | Bin 0 -> 605 bytes src/modules/conf2/images/volume_led_24.png | Bin 0 -> 692 bytes src/modules/conf2/images/volume_led_25.png | Bin 0 -> 726 bytes src/modules/conf2/images/volume_led_26.png | Bin 0 -> 699 bytes src/modules/conf2/images/volume_led_27.png | Bin 0 -> 721 bytes src/modules/conf2/images/volume_led_28.png | Bin 0 -> 748 bytes src/modules/conf2/images/volume_led_29.png | Bin 0 -> 764 bytes src/modules/conf2/images/volume_led_30.png | Bin 0 -> 740 bytes src/modules/conf2/images/volume_led_31.png | Bin 0 -> 751 bytes src/modules/conf2/images/volume_led_32.png | Bin 0 -> 761 bytes src/modules/conf2/images/volume_led_33.png | Bin 0 -> 752 bytes src/modules/conf2/images/volume_led_34.png | Bin 0 -> 723 bytes src/modules/conf2/images/volume_led_35.png | Bin 0 -> 715 bytes src/modules/conf2/images/volume_led_36.png | Bin 0 -> 694 bytes src/modules/conf2/images/volume_led_37.png | Bin 0 -> 694 bytes src/modules/conf2/images/volume_led_38.png | Bin 0 -> 600 bytes src/modules/conf2/images/volume_led_39.png | Bin 0 -> 673 bytes src/modules/conf2/images/volume_led_40.png | Bin 0 -> 695 bytes src/modules/conf2/images/volume_led_41.png | Bin 0 -> 702 bytes src/modules/conf2/images/volume_led_42.png | Bin 0 -> 730 bytes src/modules/conf2/images/volume_led_43.png | Bin 0 -> 746 bytes src/modules/conf2/images/volume_led_44.png | Bin 0 -> 751 bytes src/modules/conf2/images/volume_led_45.png | Bin 0 -> 719 bytes src/modules/conf2/module.desktop.in | 6 + 70 files changed, 6919 insertions(+), 6 deletions(-) create mode 100644 src/bin/e_configure_option.c create mode 100644 src/bin/e_configure_option.h create mode 100644 src/modules/Makefile_conf2.am create mode 100644 src/modules/conf2/e-module-conf2.edc create mode 100644 src/modules/conf2/e_conf2.c create mode 100644 src/modules/conf2/e_mod_main.c create mode 100644 src/modules/conf2/e_mod_main.h create mode 100644 src/modules/conf2/images/volume_knob.png create mode 100644 src/modules/conf2/images/volume_knob_ledsoff.png create mode 100644 src/modules/conf2/images/volume_knob_move.png create mode 100644 src/modules/conf2/images/volume_led_01.png create mode 100644 src/modules/conf2/images/volume_led_02.png create mode 100644 src/modules/conf2/images/volume_led_03.png create mode 100644 src/modules/conf2/images/volume_led_04.png create mode 100644 src/modules/conf2/images/volume_led_05.png create mode 100644 src/modules/conf2/images/volume_led_06.png create mode 100644 src/modules/conf2/images/volume_led_07.png create mode 100644 src/modules/conf2/images/volume_led_08.png create mode 100644 src/modules/conf2/images/volume_led_09.png create mode 100644 src/modules/conf2/images/volume_led_10.png create mode 100644 src/modules/conf2/images/volume_led_11.png create mode 100644 src/modules/conf2/images/volume_led_12.png create mode 100644 src/modules/conf2/images/volume_led_13.png create mode 100644 src/modules/conf2/images/volume_led_14.png create mode 100644 src/modules/conf2/images/volume_led_15.png create mode 100644 src/modules/conf2/images/volume_led_16.png create mode 100644 src/modules/conf2/images/volume_led_17.png create mode 100644 src/modules/conf2/images/volume_led_18.png create mode 100644 src/modules/conf2/images/volume_led_19.png create mode 100644 src/modules/conf2/images/volume_led_20.png create mode 100644 src/modules/conf2/images/volume_led_21.png create mode 100644 src/modules/conf2/images/volume_led_22.png create mode 100644 src/modules/conf2/images/volume_led_23.png create mode 100644 src/modules/conf2/images/volume_led_24.png create mode 100644 src/modules/conf2/images/volume_led_25.png create mode 100644 src/modules/conf2/images/volume_led_26.png create mode 100644 src/modules/conf2/images/volume_led_27.png create mode 100644 src/modules/conf2/images/volume_led_28.png create mode 100644 src/modules/conf2/images/volume_led_29.png create mode 100644 src/modules/conf2/images/volume_led_30.png create mode 100644 src/modules/conf2/images/volume_led_31.png create mode 100644 src/modules/conf2/images/volume_led_32.png create mode 100644 src/modules/conf2/images/volume_led_33.png create mode 100644 src/modules/conf2/images/volume_led_34.png create mode 100644 src/modules/conf2/images/volume_led_35.png create mode 100644 src/modules/conf2/images/volume_led_36.png create mode 100644 src/modules/conf2/images/volume_led_37.png create mode 100644 src/modules/conf2/images/volume_led_38.png create mode 100644 src/modules/conf2/images/volume_led_39.png create mode 100644 src/modules/conf2/images/volume_led_40.png create mode 100644 src/modules/conf2/images/volume_led_41.png create mode 100644 src/modules/conf2/images/volume_led_42.png create mode 100644 src/modules/conf2/images/volume_led_43.png create mode 100644 src/modules/conf2/images/volume_led_44.png create mode 100644 src/modules/conf2/images/volume_led_45.png create mode 100644 src/modules/conf2/module.desktop.in diff --git a/.gitignore b/.gitignore index 60b00be13..7b8f94223 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,7 @@ src/modules/battery/module.desktop src/modules/clock/module.desktop src/modules/comp/module.desktop src/modules/conf/module.desktop +src/modules/conf2/e-module-conf2.edj src/modules/conf_applications/module.desktop src/modules/conf_dialogs/module.desktop src/modules/conf_display/module.desktop diff --git a/ChangeLog b/ChangeLog index 2b606dbe4..e00fbdbaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-01-03 Mike Blumenkrantz + + * Added e_win_elm_available() + * Added conf2 module + * Added e_configure_option API + 2013-01-03 Carsten Haitzler * Fix translation of evrything strigns to include many more diff --git a/NEWS b/NEWS index 6670bb60f..4f7d3bee7 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,14 @@ Changes since 0.17.0: --------------------- Additions: - * Added action to reset filemanager - * Added function to hide all active menus - * Added enum for deskflip animation mode + Modules: + * conf2 + API: + * Added action to reset filemanager + * Added function to hide all active menus + * Added enum for deskflip animation mode + * Added e_win_elm_available() + * Added e_configure_option API Deprecations: * diff --git a/configure.ac b/configure.ac index c6f1d4428..e016e65c5 100644 --- a/configure.ac +++ b/configure.ac @@ -841,6 +841,7 @@ AC_E_OPTIONAL_MODULE([fileman], true) AC_E_OPTIONAL_MODULE([fileman_opinfo], true) AC_E_OPTIONAL_MODULE([wizard], true) AC_E_OPTIONAL_MODULE([conf], true) +AC_E_OPTIONAL_MODULE([conf2], $have_elementary) AC_E_OPTIONAL_MODULE([conf_wallpaper2], true) AC_E_OPTIONAL_MODULE([conf_theme], true, true) AC_E_OPTIONAL_MODULE([conf_intl], true) @@ -938,6 +939,7 @@ src/modules/winlist/module.desktop src/modules/fileman/module.desktop src/modules/fileman_opinfo/module.desktop src/modules/conf/module.desktop +src/modules/conf2/module.desktop src/modules/conf_wallpaper2/module.desktop src/modules/conf_theme/module.desktop src/modules/conf_intl/module.desktop diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 8867f9513..0e6065a81 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -59,6 +59,7 @@ e_config_data.h \ e_config_dialog.h \ e_config.h \ e_configure.h \ +e_configure_option.h \ e_confirm_dialog.h \ e_container.h \ e_datastore.h \ @@ -216,6 +217,7 @@ e_config.c \ e_config_data.c \ e_config_dialog.c \ e_configure.c \ +e_configure_option.c \ e_confirm_dialog.c \ e_container.c \ e_datastore.c \ diff --git a/src/bin/e_config.c b/src/bin/e_config.c index 082b06959..f9b46bbee 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -744,6 +744,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, transition_change, STR); /**/ E_CONFIG_LIST(D, T, remembers, _e_config_remember_edd); E_CONFIG_VAL(D, T, remember_internal_windows, INT); + E_CONFIG_VAL(D, T, remember_internal_fm_windows, UCHAR); E_CONFIG_VAL(D, T, move_info_follows, INT); /**/ E_CONFIG_VAL(D, T, resize_info_follows, INT); /**/ E_CONFIG_VAL(D, T, move_info_visible, INT); /**/ @@ -1080,6 +1081,8 @@ e_config_load(void) e_sys_action_do(E_SYS_RESTART, NULL); } } + if (!e_config->remember_internal_fm_windows) + e_config->remember_internal_fm_windows = !!(e_config->remember_internal_windows & E_REMEMBER_INTERNAL_FM_WINS); e_config->config_version = E_CONFIG_FILE_VERSION; @@ -1181,6 +1184,7 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->fullscreen_flip, 0, 1); E_CONFIG_LIMIT(e_config->icon_theme_overrides, 0, 1); E_CONFIG_LIMIT(e_config->remember_internal_windows, 0, 3); + E_CONFIG_LIMIT(e_config->remember_internal_fm_windows, 0, 1); E_CONFIG_LIMIT(e_config->desk_auto_switch, 0, 1); E_CONFIG_LIMIT(e_config->screen_limits, 0, 2); diff --git a/src/bin/e_config.h b/src/bin/e_config.h index e97a1a42b..9956ce7f7 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -38,7 +38,7 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme; /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0 +#define E_CONFIG_FILE_GENERATION 1 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH * 1000000) + E_CONFIG_FILE_GENERATION) struct _E_Config @@ -144,6 +144,7 @@ struct _E_Config const char *transition_change; // GUI Eina_List *remembers; // GUI int remember_internal_windows; // GUI + Eina_Bool remember_internal_fm_windows; // GUI int move_info_follows; // GUI int resize_info_follows; // GUI int move_info_visible; // GUI @@ -378,7 +379,7 @@ struct _E_Config const char *xft_rgba; const char *net_theme_name; // GUI const char *net_theme_name_detected; // not saved - const char *net_icon_theme_name; // GUI + const char *net_icon_theme_name; const char *gtk_font_name; } xsettings; diff --git a/src/bin/e_configure_option.c b/src/bin/e_configure_option.c new file mode 100644 index 000000000..8f6938208 --- /dev/null +++ b/src/bin/e_configure_option.c @@ -0,0 +1,2687 @@ +#include "e.h" +#include "e_fm_device.h" + +EAPI int E_EVENT_CONFIGURE_OPTION_CHANGED = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_ADD = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_DEL = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_CATEGORY_ADD = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_CATEGORY_DEL = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_TAG_ADD = -1; +EAPI int E_EVENT_CONFIGURE_OPTION_TAG_DEL = -1; + +static Eio_File *theme_ls[2] = {NULL, NULL}; +static Eio_Monitor *theme_mon[2] = {NULL, NULL}; +static Eio_File *gtk_theme_ls = NULL; +static Eina_List *gtk_theme_dirs = NULL; //Eio_File +static Eio_Monitor *gtk_theme_mon = NULL; +static Eina_List *gtk_theme_mons = NULL; //Eio_Monitor +static Eio_File *bg_ls[2] = {NULL, NULL}; +static Eio_Monitor *bg_mon[2] = {NULL, NULL}; +static Eina_Inlist *opts_list = NULL; +static Eina_Hash *tags_hash = NULL;/* tag:item */ +static Eina_List *tags_list = NULL;/* Eina_Stringshare */ +static Eina_List *opts_changed_list = NULL; //co->changed +static Eina_List *handlers = NULL; +static Eina_List *bgs = NULL; +static Eina_List *sbgs = NULL; +static Eina_List *themes = NULL; +static Eina_List *sthemes = NULL; +static Eina_List *gtk_themes = NULL; +static Eina_Bool event_block = EINA_TRUE; +static Eina_List *categories = NULL; +static Eina_Hash *category_hash = NULL; +static Eina_Hash *category_icon_hash = NULL; + +static void +_e_configure_option_event_str_end(void *d EINA_UNUSED, E_Event_Configure_Option_Category_Add *ev) +{ + eina_stringshare_del(ev->category); + free(ev); +} + +static void +_e_configure_option_event_category_add_del(Eina_Stringshare *cat, Eina_Bool del) +{ + E_Event_Configure_Option_Category_Add *ev; + + if (event_block) + { + if (del) eina_stringshare_del(cat); + return; + } + ev = E_NEW(E_Event_Configure_Option_Category_Add, 1); + ev->category = cat; + if (del) + ecore_event_add(E_EVENT_CONFIGURE_OPTION_CATEGORY_DEL, ev, (Ecore_End_Cb)_e_configure_option_event_str_end, NULL); + else + ecore_event_add(E_EVENT_CONFIGURE_OPTION_CATEGORY_ADD, ev, NULL, NULL); +} + +static void +_e_configure_option_event_tag_add_del(Eina_Stringshare *tag, Eina_Bool del) +{ + E_Event_Configure_Option_Tag_Add *ev; + + if (event_block) + { + if (del) eina_stringshare_del(tag); + return; + } + ev = E_NEW(E_Event_Configure_Option_Tag_Add, 1); + ev->tag = tag; + if (del) + ecore_event_add(E_EVENT_CONFIGURE_OPTION_TAG_DEL, ev, (Ecore_End_Cb)_e_configure_option_event_str_end, NULL); + else + ecore_event_add(E_EVENT_CONFIGURE_OPTION_TAG_ADD, ev, NULL, NULL); +} + +static void +_e_configure_option_tag_remove(E_Configure_Option *co, Eina_Stringshare *tag) +{ + Eina_List *items; + + items = eina_hash_find(tags_hash, tag); + if (!items) return; + items = eina_list_remove(items, co); + co->tags = eina_list_remove(co->tags, tag); + if (!items) + { + /* this seems dumb... */ + tags_list = eina_list_remove(tags_list, tag); + _e_configure_option_event_tag_add_del(tag, EINA_TRUE); + } + eina_hash_set(tags_hash, tag, items); +} + + +static void +_e_configure_option_free(E_Configure_Option *co) +{ + if (!co->private) + opts_list = eina_inlist_remove(opts_list, EINA_INLIST_GET(co)); + if (co->changed) + { + eina_value_flush(&co->val); + if (opts_changed_list) + opts_changed_list = eina_list_remove(opts_changed_list, co); + } + if (co->data) + eina_stringshare_del(eina_hash_find(co->data, "icon")); + eina_hash_free(co->data); + E_FREE_LIST(co->tags, eina_stringshare_del); + eina_stringshare_del(co->name); + eina_stringshare_del(co->desc); + eina_stringshare_del(co->info); + eina_stringshare_del(co->changed_action); + free(co); +} + +static void +_e_configure_option_event_del_end(void *d EINA_UNUSED, E_Event_Configure_Option_Del *ev) +{ + Eina_List *l, *ll; + Eina_Stringshare *tag; + + EINA_LIST_FOREACH_SAFE(ev->co->tags, l, ll, tag) + _e_configure_option_tag_remove(ev->co, tag); + _e_configure_option_free(ev->co); + free(ev); +} + +static void +_e_configure_option_event_del(E_Configure_Option *co) +{ + E_Event_Configure_Option_Del *ev; + + if (event_block) return; + ev = E_NEW(E_Event_Configure_Option_Del, 1); + ev->co = co; + ecore_event_add(E_EVENT_CONFIGURE_OPTION_CHANGED, ev, (Ecore_End_Cb)_e_configure_option_event_del_end, NULL); +} + +static void +_e_configure_option_event_changed(E_Configure_Option *co) +{ + E_Event_Configure_Option_Changed *ev; + + if (event_block) return; + ev = E_NEW(E_Event_Configure_Option_Changed, 1); + ev->co = co; + ecore_event_add(E_EVENT_CONFIGURE_OPTION_CHANGED, ev, NULL, NULL); +} + +static void +_e_configure_option_tag_append(E_Configure_Option *co, const char *tag) +{ + Eina_List *items; + + items = eina_hash_find(tags_hash, tag); + if (!items) + { + Eina_Stringshare *t; + + t = eina_stringshare_add(tag); + tags_list = eina_list_sorted_insert(tags_list, (Eina_Compare_Cb)strcmp, t); + _e_configure_option_event_tag_add_del(t, EINA_FALSE); + } + eina_hash_set(tags_hash, tag, eina_list_append(items, co)); + co->tags = eina_list_append(co->tags, eina_stringshare_add(tag)); +} + +static Eina_List * +_e_configure_option_ctx_list_prune(Eina_Stringshare *tag, Eina_List *opts, Eina_List *tags) +{ + Eina_List *l, *ll, *lll, *topts; + E_Configure_Option *co; + Eina_Stringshare *t; + + EINA_LIST_FOREACH_SAFE(opts, l, ll, co) + { + Eina_Bool found = EINA_FALSE; + + EINA_LIST_FOREACH(tags, lll, t) + { + if (t == tag) continue; + topts = eina_hash_find(tags_hash, t); + if (!topts) continue; + if (eina_list_data_find(topts, co)) + found = EINA_TRUE; + } + if (!found) + opts = eina_list_remove_list(opts, l); + } + + return opts; +} + +static void +_e_configure_option_value_reset(E_Configure_Option *co) +{ + if (co->type == E_CONFIGURE_OPTION_TYPE_CUSTOM) return; + if (co->changed) eina_value_flush(&co->val); + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + eina_value_setup(&co->val, EINA_VALUE_TYPE_UCHAR); + break; + case E_CONFIGURE_OPTION_TYPE_INT: + case E_CONFIGURE_OPTION_TYPE_ENUM: + eina_value_setup(&co->val, EINA_VALUE_TYPE_INT); + break; + case E_CONFIGURE_OPTION_TYPE_UINT: + eina_value_setup(&co->val, EINA_VALUE_TYPE_UINT); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + eina_value_setup(&co->val, EINA_VALUE_TYPE_DOUBLE); + break; + case E_CONFIGURE_OPTION_TYPE_STR: + eina_value_setup(&co->val, EINA_VALUE_TYPE_STRINGSHARE); + break; + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + break; + } +} + +static Eina_Bool +_e_configure_option_apply(E_Configure_Option *co, Eina_List **events, Eina_List **funcs, Eina_List **acts) +{ + E_Action *act; + void (*none)(void) = NULL; + + if (!co->changed) return EINA_FALSE; + if ((co->type == E_CONFIGURE_OPTION_TYPE_DOUBLE_INT) || (co->type == E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT)) + { + double dbl; + long x; + + eina_value_get(&co->val, &dbl); + x = lround(dbl); + if (co->type == E_CONFIGURE_OPTION_TYPE_DOUBLE_INT) + *(int*)co->valptr = x; + else + *(unsigned int*)co->valptr = MAX(x, 0); + } + else if (co->type == E_CONFIGURE_OPTION_TYPE_STR) + { + eina_stringshare_replace(co->valptr, NULL); + eina_value_get(&co->val, co->valptr); + eina_stringshare_ref(co->valptr); + } + else if (co->type != E_CONFIGURE_OPTION_TYPE_CUSTOM) + eina_value_get(&co->val, co->valptr); + _e_configure_option_value_reset(co); + + if (co->changed_action) + { + act = e_action_find(co->changed_action); + while (act && act->func.go) + { + if (!acts) + { + act->func.go((E_Object*)e_util_container_current_get(), NULL); + break; + } + if (*acts && eina_list_data_find(*acts, act)) break; + *acts = eina_list_append(*acts, act); + break; + } + } + while (co->event_type) + { + if (!events) + { + ecore_event_add(co->event_type, NULL, NULL, NULL); + break; + } + if (*events && eina_list_data_find(*events, (intptr_t*)(long)co->event_type)) break; + *events = eina_list_append(*events, (intptr_t*)(long)co->event_type); + break; + } + if (co->type == E_CONFIGURE_OPTION_TYPE_BOOL) + none = co->funcs[*(Eina_Bool*)co->valptr].none; + else if (co->funcs[0].none) + none = co->funcs[0].none; + while (none) + { + if (!funcs) + { + none(); + break; + } + if (*funcs && eina_list_data_find(*funcs, none)) break; + *funcs = eina_list_append(*funcs, none); + break; + } + if (co->funcs[0].one) + { + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + co->funcs[0].one(*(Eina_Bool*)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + co->funcs[0].one(*(unsigned char*)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: //lround(double) + case E_CONFIGURE_OPTION_TYPE_INT: + case E_CONFIGURE_OPTION_TYPE_ENUM: + co->funcs[0].one(*(int*)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: //lround(double) + case E_CONFIGURE_OPTION_TYPE_UINT: + co->funcs[0].one(*(unsigned int*)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + co->funcs[0].one(*(double*)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_STR: + co->funcs[0].one(*(Eina_Stringshare**)co->valptr); + break; + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + break; + } + } + co->changed = EINA_FALSE; + + return co->requires_restart; +} + +/******************************************************** + * CHANGE CALLBACKS + */ + +static void +_e_configure_screensaver_changed(void) +{ + if ((e_config->backlight.idle_dim) && + (e_config->backlight.timer > (e_config->screensaver_timeout))) + { + e_config->screensaver_timeout = e_config->backlight.timer; + e_config->dpms_standby_timeout = e_config->screensaver_timeout; + e_config->dpms_suspend_timeout = e_config->screensaver_timeout; + e_config->dpms_off_timeout = e_config->screensaver_timeout; + } + e_screensaver_update(); + e_dpms_update(); +} + +static void +_e_configure_dpms_changed(void) +{ + e_backlight_mode_set(NULL, E_BACKLIGHT_MODE_NORMAL); + e_backlight_level_set(NULL, e_config->backlight.normal, -1.0); + + _e_configure_screensaver_changed(); + e_backlight_update(); +} + +static void +_e_configure_pointer_changed(void) +{ + const Eina_List *l; + E_Manager *man; + + EINA_LIST_FOREACH(e_manager_list(), l, man) + { + if (man->pointer && !e_config->show_cursor) + { + e_pointer_hide(man->pointer); + continue; + } + if (man->pointer) e_object_del(E_OBJECT(man->pointer)); + man->pointer = e_pointer_window_new(man->root, 1); + } +} + +static void +_e_configure_framerate_changed(void) +{ + edje_frametime_set(1.0 / e_config->framerate); + e_canvas_recache(); +} + +static void +_e_configure_zone_desks_count_changed(void) +{ + const Eina_List *l, *ll, *lll; + E_Manager *man; + E_Container *con; + E_Zone *zone; + + EINA_LIST_FOREACH(e_manager_list(), l, man) + EINA_LIST_FOREACH(man->containers, ll, con) + EINA_LIST_FOREACH(con->zones, lll, zone) + e_zone_desk_count_set(zone, e_config->zone_desks_x_count, e_config->zone_desks_x_count); +} + + +/******************************************************** + * THUMB CALLBACKS + */ + +static Eina_Bool +_e_configure_transition_timer_cb(void *obj) +{ + Eina_Stringshare *file, *key; + Evas_Object *o, *oo; + + evas_object_data_del(obj, "conf_timer"); + o = edje_object_part_swallow_get(obj, "e.swallow.bg.new"); + edje_object_part_unswallow(obj, o); + oo = edje_object_part_swallow_get(obj, "e.swallow.bg.old"); + edje_object_part_unswallow(obj, oo); + edje_object_file_get(obj, &file, &key); + eina_stringshare_ref(file); + eina_stringshare_ref(key); + edje_object_file_set(obj, NULL, NULL); + edje_object_file_set(obj, file, key); + eina_stringshare_del(file); + eina_stringshare_del(key); + edje_object_part_swallow(obj, "e.swallow.bg.new", o); + edje_object_part_swallow(obj, "e.swallow.bg.old", oo); + edje_object_signal_emit(obj, "e,action,start", "e"); + return EINA_FALSE; +} + +static void +_e_configure_transition_done_cb(void *d EINA_UNUSED, Evas_Object *obj, const char *s EINA_UNUSED, const char *so EINA_UNUSED) +{ + Ecore_Timer *timer; + + timer = evas_object_data_get(obj, "conf_timer"); + if (timer) ecore_timer_reset(timer); + else evas_object_data_set(obj, "conf_timer", ecore_timer_add(1.0, _e_configure_transition_timer_cb, obj)); +} + +static void +_e_configure_transition_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Ecore_Timer *timer; + + timer = evas_object_data_del(obj, "conf_timer"); + if (timer) ecore_timer_del(timer); +} + +static Evas_Object * +_e_configure_transition_thumb_cb(E_Configure_Option_Info *oi, Evas *evas) +{ + Evas_Object *oj, *obj, *o, *oa; + Evas *e; + E_Zone *zone; + + zone = e_util_zone_current_get(e_manager_current_get()); + + oa = e_widget_aspect_add(evas, 150, (200 * zone->h) / zone->w); + obj = e_widget_preview_add(evas, 150, (200 * zone->h) / zone->w); + e_widget_aspect_child_set(oa, obj); + + e = e_widget_preview_evas_get(obj); + + if (oi->thumb_key) + { + oj = edje_object_add(e); + edje_object_file_set(oj, oi->thumb_file, oi->thumb_key); + edje_object_signal_callback_add(oj, "e,state,done", "*", _e_configure_transition_done_cb, NULL); + evas_object_event_callback_add(oj, EVAS_CALLBACK_DEL, _e_configure_transition_del_cb, NULL); + e_widget_preview_extern_object_set(obj, oj); + + o = edje_object_add(e); + edje_object_file_set(o, oi->thumb_file, "e/transpreview/0"); + edje_object_part_swallow(oj, "e.swallow.bg.new", o); + } + + o = edje_object_add(e); + edje_object_file_set(o, oi->thumb_file, "e/transpreview/1"); + + if (oi->thumb_key) + { + edje_object_part_swallow(oj, "e.swallow.bg.old", o); + edje_object_signal_emit(oj, "e,action,start", "e"); + } + else + e_widget_preview_extern_object_set(obj, o); + + return oa; +} + +static Evas_Object * +_e_configure_border_style_thumb_cb(E_Configure_Option_Info *oi, Evas *evas) +{ + Evas_Object *ob, *oj, *orect; + + ob = e_livethumb_add(evas); + e_livethumb_vsize_set(ob, 150, 150); + if (oi->thumb_key) + { + oj = edje_object_add(e_livethumb_evas_get(ob)); + edje_object_file_set(oj, oi->thumb_file, oi->thumb_key); + e_livethumb_thumb_set(ob, oj); + } + orect = evas_object_rectangle_add(e_livethumb_evas_get(ob)); + evas_object_color_set(orect, 0, 0, 0, 128); + evas_object_show(orect); + if (oi->thumb_key) + edje_object_part_swallow(oj, "e.swallow.client", orect); + else + e_livethumb_thumb_set(ob, orect); + return ob; +} + + +static Evas_Object * +_e_configure_icon_theme_thumb_cb(E_Configure_Option_Info *oi, Evas *evas) +{ + Evas_Object *of, *o; + unsigned int x, y; + const char **example_icon, *example_icons[] = + { + NULL, + "folder", + "user-home", + "text-x-generic", + "system-run", + "preferences-system", + NULL, + }; + if (oi->thumb_file) + { + example_icons[0] = oi->thumb_file; + example_icon = example_icons; + } + else + example_icon = example_icons + 1; + + of = e_widget_frametable_add(evas, _("Preview"), 1); + for (x = y = 0; (*example_icon); example_icon++) + { + const char *path; + + path = efreet_icon_path_find(oi->value, *example_icon, 48); + if (!path) continue; + o = e_icon_add(evas); + if (e_icon_file_set(o, path)) + e_icon_fill_inside_set(o, 1); + else + { + evas_object_del(o); + continue; + } + e_widget_frametable_object_append_full(of, o, x++, y, 1, 1, 1, 1, 0, 0, + 0.5, 0.5, 48, 48, 64, 64); + x %= 3; + if (!x) y++; + } + return of; +} + +static Evas_Object * +_e_configure_netwm_theme_thumb_cb(E_Configure_Option_Info *oi EINA_UNUSED, Evas *evas) +{ + Evas_Object *o; + +/* FIXME: uhhhhhhhhhhhhhhhhhhhhhh */ + //o = e_widget_label_add(evas, oi->name); + o = e_box_add(evas); + return o; +} + +/******************************************************** + * INFO CALLBACKS + */ + + +/* FIXME +static Eina_List * +_e_configure_language_info_cb(E_Configure_Option *co) +{ + Eina_List *l, *ret = NULL; + E_Configure_Option_Info *oi; + char *lang; + + l = e_intl_language_list(); + EINA_LIST_FREE(l, lang) + { + + //oi = e_configure_option_info_new(co, + free(lang); + } + + return ret; +} +*/ + +static Eina_List * +_e_configure_border_shade_transition_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Linear", + "Accelerate, then decelerate", + "Accelerate", + "Decelerate", + "Pronounced accelerate", + "Pronounced decelerate", + "Pronounced accelerate, then decelerate", + "Bounce", + "Bounce more" + }; + + for (x = 0; x <= E_TRANSITION_BOUNCE_LOTS; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_window_placement_policy_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Try not to cover other windows", + "Try not to cover gadgets", + "Place at mouse pointer (automatic)", + "Place at mouse pointer (interactive)" + }; + + for (x = 0; x <= E_WINDOW_PLACEMENT_MANUAL; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_focus_policy_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Click", + "Pointer", + "Sloppy" + }; + + for (x = 0; x <= E_FOCUS_SLOPPY; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_focus_setting_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Don't set focus on new windows", + "Set focus on all new windows", + "Set focus only on all new dialog windows", + "Set focus only on new dialog windows if dialog's parent window has focus" + }; + + for (x = 0; x <= E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_window_activehint_policy_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Ignore application", + "Animate application window", + "Raise and set focus to application window" + }; + + for (x = 0; x <= E_ACTIVEHINT_POLICY_ACTIVATE; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_fullscreen_policy_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Resize window, do not resize screen", + "Resize window and screen" + }; + + for (x = 0; x <= E_FULLSCREEN_ZOOM; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_maximize_policy_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Fullscreen", /* 1 */ + "Expand to maximum size without covering shelves", /* 2 */ + NULL, + "Expand to maximum size ignoring shelves" /* 4 */ + }; + + for (x = E_MAXIMIZE_FULLSCREEN; x <= E_MAXIMIZE_FILL; x++) + { + if (!name[x]) continue; + oi = e_configure_option_info_new(co, _(name[x - 1]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_font_hinting_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "No hinting", + "Automatic hinting", + "Bytecode hinting" + }; + + for (x = 0; x <= EVAS_FONT_HINTING_BYTECODE; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_desklock_login_box_zone_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + int num = 0; + E_Manager *m; + Eina_List *ml; + const char *name[] = + { + "Show on all screens", + "Show on screen of pointer", + "Show on screen %d" + }; + + EINA_LIST_FOREACH(e_manager_list(), ml, m) + { + Eina_List *cl; + E_Container *con; + + EINA_LIST_FOREACH(m->containers, cl, con) + num += eina_list_count(con->zones); + } + + for (x = -2; x < num; x++) + { + char buf[128]; + + if (x < 0) + oi = e_configure_option_info_new(co, _(name[x + 2]), (intptr_t*)(long)x); + else + { + snprintf(buf, sizeof(buf), _(name[2]), x); + oi = e_configure_option_info_new(co, buf, (intptr_t*)(long)x); + } + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_clientlist_group_by_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "No grouping", + "Virtual desktop", + "Window class" + }; + + for (x = 0; x <= E_CLIENTLIST_GROUP_CLASS; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_clientlist_separate_with_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "No separation", + "Separator bars", + "Separate menus" + }; + + for (x = 0; x <= E_CLIENTLIST_GROUP_SEP_MENU; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_clientlist_sort_by_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "No sorting", + "Alphabetical order", + "Window stacking layer", + "Recently used windows first" + }; + + for (x = 0; x <= E_CLIENTLIST_SORT_MOST_RECENT; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_clientlist_separate_iconified_apps_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Group by owner virtual desktop", + "Group by current virtual desktop", + "Separate group" + }; + + for (x = 0; x <= E_CLIENTLIST_GROUPICONS_SEP; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_desk_flip_animate_mode_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "No animation", + "Pane", + "Zoom" + }; + + for (x = 0; x <= E_DESKFLIP_ANIMATION_MODE_ZOOM; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_screen_limits_info_cb(E_Configure_Option *co) +{ + Eina_List *ret = NULL; + E_Configure_Option_Info *oi; + int x; + const char *name[] = + { + "Allow windows partly out of the screen limits", + "Allow windows completely out of the screen limits", + "Keep windows completely within the screen limits" + }; + + for (x = 0; x <= E_SCREEN_LIMITS_WITHIN; x++) + { + oi = e_configure_option_info_new(co, _(name[x]), (intptr_t*)(long)x); + oi->current = (*(int*)co->valptr == x); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static int +_e_configure_icon_theme_info_sort_cb(const void *data1, const void *data2) +{ + const Efreet_Icon_Theme *m1 = data1, *m2 = data2; + + if (!data2) return -1; + if (!m1->name.name) return 1; + if (!m2->name.name) return -1; + + return strcmp(m1->name.name, m2->name.name); +} + +static Eina_List * +_e_configure_icon_theme_info_cb(E_Configure_Option *co) +{ + Eina_List *l, *ret = NULL; + Efreet_Icon_Theme *theme; + E_Configure_Option_Info *oi; + + l = efreet_icon_theme_list_get(); + if (!l) return NULL; + l = eina_list_sort(l, 0, _e_configure_icon_theme_info_sort_cb); + EINA_LIST_FREE(l, theme) + { + if (!theme->directories) continue; //invalid + if (!e_util_strcasecmp(theme->name.internal, "hicolor")) continue; //default + oi = e_configure_option_info_new(co, theme->name.name, eina_stringshare_add(theme->name.internal)); + oi->current = !e_util_strcmp(e_config->icon_theme, theme->name.internal); + oi->thumb_file = eina_stringshare_add(theme->example_icon); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_netwm_theme_info_cb(E_Configure_Option *co) +{ + Eina_List *l, *ret = NULL; + E_Configure_Option_Info *oi; + Eina_Stringshare *dir; + Eina_Bool gtk2, gtk3; + + EINA_LIST_FOREACH(gtk_themes, l, dir) + { + char buf[PATH_MAX]; + const char *name; + + snprintf(buf, sizeof(buf), "%s/gtk-2.0", dir); + gtk2 = ecore_file_is_dir(buf); + snprintf(buf, sizeof(buf), "%s/gtk-3.0", dir); + gtk3 = ecore_file_is_dir(buf); + if ((!gtk2) && (!gtk3)) continue; + name = ecore_file_file_get(dir); + snprintf(buf, sizeof(buf), "%s (%s)%s%s%s", name, gtk2 ? "gtk2" : "gtk3", + (gtk2 && gtk3) ? " (" : "", (gtk2 && gtk3) ? "gtk3" : "", (gtk2 && gtk3) ? ")" : ""); + oi = e_configure_option_info_new(co, buf, eina_stringshare_add(name)); + oi->current = (e_config->xsettings.net_theme_name == oi->value); + ret = eina_list_append(ret, oi); + } + return ret; +} + +static Eina_List * +_e_configure_transition_info_cb(E_Configure_Option *co) +{ + Eina_Stringshare *style; + Eina_List *l, *ret = NULL; + Eina_Stringshare *cur, *file; + char buf[4096]; + const char *key; + E_Configure_Option_Info *oi; + + file = e_theme_edje_file_get("base/theme/widgets", "e/transpreview/0"); + key = "e/transitions/%s"; + cur = *(Eina_Stringshare**)co->valptr; + + oi = e_configure_option_info_new(co, _("None"), NULL); + oi->thumb_file = eina_stringshare_ref(file); + oi->current = (!cur); + ret = eina_list_append(ret, oi); + + l = e_theme_transition_list(); + EINA_LIST_FREE(l, style) + { + oi = e_configure_option_info_new(co, style, style); + ret = eina_list_append(ret, oi); + oi->thumb_file = eina_stringshare_ref(file); + snprintf(buf, sizeof(buf), key, style); + oi->thumb_key = eina_stringshare_add(buf); + oi->current = (style == cur); + } + return ret; +} + +static Eina_List * +_e_configure_border_style_info_cb(E_Configure_Option *co) +{ + Eina_Stringshare *style; + Eina_List *l, *ret = NULL; + Eina_Stringshare *file; + char buf[4096]; + const char *key; + E_Configure_Option_Info *oi; + + file = e_theme_edje_file_get("base/theme/borders", "e/widgets/border/default/border"); + oi = e_configure_option_info_new(co, "borderless", eina_stringshare_add("borderless")); + ret = eina_list_append(ret, oi); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_add("e/widgets/border/borderless/border"); + oi->current = !e_util_strcmp(e_config->theme_default_border_style, "borderless"); + key = "e/widgets/border/%s/border"; + + l = e_theme_border_list(); + EINA_LIST_FREE(l, style) + { + oi = e_configure_option_info_new(co, style, style); + ret = eina_list_append(ret, oi); + oi->thumb_file = eina_stringshare_ref(file); + snprintf(buf, sizeof(buf), key, style); + oi->thumb_key = eina_stringshare_add(buf); + if (e_config->theme_default_border_style) + oi->current = (style == e_config->theme_default_border_style); + else if (!strcmp(style, "default")) + oi->current = EINA_TRUE; + } + return ret; +} + +static Eina_List * +_e_configure_init_default_theme_info_cb(E_Configure_Option *co) +{ + Eina_List *l, *ret = NULL; + Eina_Stringshare *file; + char buf[PATH_MAX], *p; + E_Configure_Option_Info *oi; + Eina_Stringshare *key; + + key = eina_stringshare_add("e/init/splash"); + EINA_LIST_FOREACH(themes, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + strncpy(buf, ecore_file_file_get(file), p - file); + oi = e_configure_option_info_new(co, buf, eina_stringshare_add(buf)); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + ret = eina_list_append(ret, oi); + oi->current = (oi->name == *(Eina_Stringshare**)co->valptr); + } + if (ret && sthemes) + ret = eina_list_append(ret, e_configure_option_info_new(co, NULL, NULL)); + EINA_LIST_FOREACH(sthemes, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + strncpy(buf, ecore_file_file_get(file), p - file); + oi = e_configure_option_info_new(co, buf, eina_stringshare_add(buf)); + ret = eina_list_append(ret, oi); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + oi->current = (oi->name == *(Eina_Stringshare**)co->valptr); + } + eina_stringshare_del(key); + return ret; +} + +static Eina_List * +_e_configure_background_info_cb(E_Configure_Option *co) +{ + Eina_List *l, *ret = NULL; + Eina_Stringshare *file; + const char *f; + Eina_Stringshare *cur; + char buf[PATH_MAX], *p; + E_Configure_Option_Info *oi; + Eina_Stringshare *key; + + key = eina_stringshare_add("e/desktop/background"); + cur = *(Eina_Stringshare**)co->valptr; + if (!cur) + { + E_Config_Theme *ct; + ct = e_theme_config_get("theme"); + cur = ct->file; + } + EINA_LIST_FOREACH(themes, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + f = ecore_file_file_get(file); + memcpy(buf, f, p - f); + buf[p - f] = 0; + oi = e_configure_option_info_new(co, buf, eina_stringshare_ref(file)); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + ret = eina_list_append(ret, oi); + oi->current = ((file == cur) || (!e_util_strcmp(f, cur))); + + } + EINA_LIST_FOREACH(sthemes, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + f = ecore_file_file_get(file); + memcpy(buf, f, p - f); + buf[p - f] = 0; + oi = e_configure_option_info_new(co, buf, eina_stringshare_ref(file)); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + ret = eina_list_append(ret, oi); + oi->current = ((file == cur) || (!e_util_strcmp(f, cur))); + } + EINA_LIST_FOREACH(bgs, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + f = ecore_file_file_get(file); + memcpy(buf, f, p - f); + buf[p - f] = 0; + oi = e_configure_option_info_new(co, buf, eina_stringshare_ref(file)); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + ret = eina_list_append(ret, oi); + oi->current = ((file == cur) || (!e_util_strcmp(f, cur))); + } + if (ret && sthemes) + ret = eina_list_append(ret, e_configure_option_info_new(co, NULL, NULL)); + EINA_LIST_FOREACH(sbgs, l, file) + { + if (!edje_file_group_exists(file, key)) continue; + p = strrchr(file, '.'); + f = ecore_file_file_get(file); + memcpy(buf, f, p - f); + buf[p - f] = 0; + oi = e_configure_option_info_new(co, buf, eina_stringshare_ref(file)); + ret = eina_list_append(ret, oi); + oi->thumb_file = eina_stringshare_ref(file); + oi->thumb_key = eina_stringshare_ref(key); + oi->current = ((file == cur) || (!e_util_strcmp(f, cur))); + } + eina_stringshare_del(key); + return ret; +} + +static int +_sort_cb(const char *a, const char *b) +{ + const char *f1, *f2; + + f1 = ecore_file_file_get(a); + f2 = ecore_file_file_get(b); + return e_util_strcasecmp(f1, f2); +} + +static Eina_Bool +_gtk_theme_check(const char *file) +{ + Eina_Stringshare *dir; + Eina_List *l; + + EINA_LIST_FOREACH(gtk_themes, l, dir) + if (!strcasecmp(ecore_file_file_get(dir), ecore_file_file_get(file))) return EINA_FALSE; + return EINA_TRUE; +} + +static void +_init_main_cb(void *data __UNUSED__, Eio_File *handler, const char *file) +{ + if (handler == theme_ls[0]) + themes = eina_list_sorted_insert(themes, (Eina_Compare_Cb)_sort_cb, eina_stringshare_add(file)); + else if (handler == theme_ls[1]) + sthemes = eina_list_sorted_insert(sthemes, (Eina_Compare_Cb)_sort_cb, eina_stringshare_add(file)); + else if (handler == bg_ls[0]) + bgs = eina_list_sorted_insert(bgs, (Eina_Compare_Cb)_sort_cb, eina_stringshare_add(file)); + else if (handler == bg_ls[1]) + sbgs = eina_list_sorted_insert(sbgs, (Eina_Compare_Cb)_sort_cb, eina_stringshare_add(file)); + else if (_gtk_theme_check(file)) + gtk_themes = eina_list_sorted_insert(gtk_themes, (Eina_Compare_Cb)_sort_cb, eina_stringshare_add(file)); +} + +static void +_init_error_cb(void *data __UNUSED__, Eio_File *handler, int error __UNUSED__) +{ + if ((!theme_ls[0]) && (!theme_ls[1]) && (!bg_ls[0]) && (!bg_ls[1]) && + (!gtk_theme_ls) && (!gtk_theme_dirs)) goto out; + if (theme_ls[0] == handler) + { + theme_ls[0] = NULL; + E_FREE_LIST(themes, eina_stringshare_del); + } + else if (theme_ls[1] == handler) + { + theme_ls[1] = NULL; + E_FREE_LIST(sthemes, eina_stringshare_del); + } + else if (bg_ls[0] == handler) + { + bg_ls[0] = NULL; + E_FREE_LIST(bgs, eina_stringshare_del); + } + else if (bg_ls[1] == handler) + { + bg_ls[1] = NULL; + E_FREE_LIST(sbgs, eina_stringshare_del); + } + else if (gtk_theme_ls == handler) + gtk_theme_ls = NULL; + else + gtk_theme_dirs = eina_list_remove(gtk_theme_dirs, handler); + return; +out: + E_FREE_LIST(themes, eina_stringshare_del); + E_FREE_LIST(sthemes, eina_stringshare_del); + E_FREE_LIST(bgs, eina_stringshare_del); + E_FREE_LIST(sbgs, eina_stringshare_del); + E_FREE_LIST(gtk_themes, eina_stringshare_del); +} + +static void +_init_done_cb(void *data __UNUSED__, Eio_File *handler) +{ + if ((!theme_ls[0]) && (!theme_ls[1]) && (!bg_ls[0]) && (!bg_ls[1]) && + (!gtk_theme_ls) && (!gtk_theme_dirs)) goto out; + if (theme_ls[0] == handler) + theme_ls[0] = NULL; + else if (theme_ls[1] == handler) + theme_ls[1] = NULL; + else if (bg_ls[0] == handler) + bg_ls[0] = NULL; + else if (bg_ls[1] == handler) + bg_ls[1] = NULL; + else if (gtk_theme_ls == handler) + gtk_theme_ls = NULL; + else + gtk_theme_dirs = eina_list_remove(gtk_theme_dirs, handler); + + return; +out: + E_FREE_LIST(themes, eina_stringshare_del); + E_FREE_LIST(sthemes, eina_stringshare_del); + E_FREE_LIST(bgs, eina_stringshare_del); + E_FREE_LIST(sbgs, eina_stringshare_del); + E_FREE_LIST(gtk_themes, eina_stringshare_del); +} + +static Eina_Bool +_gtk_filter_cb(void *data __UNUSED__, Eio_File *handler __UNUSED__, const char *file) +{ + return ecore_file_is_dir(file); +} + +static Eina_Bool +_edj_filter_cb(void *data __UNUSED__, Eio_File *handler __UNUSED__, const char *file) +{ + return eina_str_has_extension(file, ".edj"); +} + +static Eina_Bool +_monitor_theme_rescan(void *d __UNUSED__, int type __UNUSED__, Eio_Monitor_Event *ev) +{ + char buf[PATH_MAX]; + + if (theme_mon[0] == ev->monitor) + { + if (theme_ls[0]) return ECORE_CALLBACK_RENEW; + E_FREE_LIST(themes, eina_stringshare_del); + e_user_dir_concat_static(buf, "themes"); + theme_ls[0] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + } + else if (theme_mon[1] == ev->monitor) + { + if (theme_ls[1]) return ECORE_CALLBACK_RENEW; + E_FREE_LIST(sthemes, eina_stringshare_del); + e_prefix_data_concat_static(buf, "data/themes"); + theme_ls[1] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + } + else if (bg_mon[0] == ev->monitor) + { + if (bg_ls[0]) return ECORE_CALLBACK_RENEW; + E_FREE_LIST(bgs, eina_stringshare_del); + e_user_dir_concat_static(buf, "backgrounds"); + bg_ls[0] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + } + else if (bg_mon[1] == ev->monitor) + { + if (bg_ls[1]) return ECORE_CALLBACK_RENEW; + E_FREE_LIST(sbgs, eina_stringshare_del); + e_prefix_data_concat_static(buf, "data/backgrounds"); + bg_ls[1] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + } + else + { + const char *dir; + Eina_List *l; + + if (gtk_theme_ls && (gtk_theme_mon == ev->monitor)) return ECORE_CALLBACK_RENEW; + if (gtk_theme_ls) eio_file_cancel(gtk_theme_ls); + E_FREE_LIST(gtk_themes, eina_stringshare_del); + E_FREE_LIST(gtk_theme_dirs, eio_file_cancel); + e_user_homedir_concat_static(buf, ".themes"); + gtk_theme_ls = eio_file_ls(buf, _gtk_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + EINA_LIST_FOREACH(efreet_data_dirs_get(), l, dir) + { + Eio_File *ls; + + snprintf(buf, sizeof(buf), "%s/themes", dir); + ls = eio_file_ls(buf, _gtk_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + if (!ls) continue; + gtk_theme_dirs = eina_list_append(gtk_theme_dirs, ls); + } + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_monitor_error(void *d __UNUSED__, int type __UNUSED__, Eio_Monitor_Event *ev) +{ + if (theme_mon[0] == ev->monitor) + theme_mon[0] = NULL; + else if (theme_mon[1] == ev->monitor) + theme_mon[1] = NULL; + else if (bg_mon[0] == ev->monitor) + bg_mon[0] = NULL; + else if (bg_mon[1] == ev->monitor) + bg_mon[1] = NULL; + else if (gtk_theme_mon == ev->monitor) + gtk_theme_mon = NULL; + else + gtk_theme_mons = eina_list_remove(gtk_theme_mons, ev->monitor); + return ECORE_CALLBACK_RENEW; +} + +EINTERN int +e_configure_option_init(void) +{ + E_Configure_Option *co; + char buf[PATH_MAX]; + + E_EVENT_CONFIGURE_OPTION_CHANGED = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_ADD = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_DEL = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_CATEGORY_ADD = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_CATEGORY_DEL = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_TAG_ADD = ecore_event_type_new(); + E_EVENT_CONFIGURE_OPTION_TAG_DEL = ecore_event_type_new(); + + tags_hash = eina_hash_string_superfast_new(NULL); +#define OPT_ADD(TYPE, NAME, DESC, ...) \ + co = e_configure_option_add(E_CONFIGURE_OPTION_TYPE_##TYPE, DESC, #NAME, EINA_FALSE, &e_config->NAME, NULL);\ + e_configure_option_tags_set(co, (const char*[]){__VA_ARGS__, NULL}, 0) +#define OPT_HELP(STR) \ + co->help = eina_stringshare_add(_(STR)) +#define OPT_MINMAX_STEP_FMT(MIN, MAX, STEP, FMT) \ + co->minmax[0] = (MIN), co->minmax[1] = (MAX), co->step = (STEP),\ + co->info = eina_stringshare_add(_(FMT)) +#define OPT_ICON(ICON) \ + e_configure_option_data_set(co, "icon", eina_stringshare_add(ICON)) + + OPT_ADD(BOOL, show_splash, _("Show splash screen on startup"), _("splash"), _("startup")); + OPT_ADD(STR, init_default_theme, _("Startup splash theme"), _("splash"), _("startup"), _("theme"), _("animate")); + co->info_cb = _e_configure_init_default_theme_info_cb; + OPT_ICON("preferences-startup"); + + OPT_ADD(STR, transition_start, _("Startup transition effect"), _("transition"), _("startup"), _("theme"), _("animate")); + co->info_cb = _e_configure_transition_info_cb; + co->thumb_cb = _e_configure_transition_thumb_cb; + OPT_ICON("preferences-transitions"); + OPT_ADD(STR, transition_desk, _("Desk change transition effect"), _("transition"), _("vdesk"), _("theme"), _("animate")); + co->info_cb = _e_configure_transition_info_cb; + co->thumb_cb = _e_configure_transition_thumb_cb; + OPT_ICON("preferences-transitions"); + OPT_ADD(STR, transition_change, _("Wallpaper change transition effect"), _("transition"), _("wallpaper"), _("theme"), _("animate")); + co->info_cb = _e_configure_transition_info_cb; + co->thumb_cb = _e_configure_transition_thumb_cb; + OPT_ICON("preferences-transitions"); + + OPT_ADD(CUSTOM, themes, _("Enlightenment theme settings"), _("theme")); + co->info = eina_stringshare_add("appearance/theme"); + OPT_ICON("preferences-desktop-theme"); + OPT_ADD(CUSTOM, desktop_backgrounds, _("Desktop wallpaper settings"), _("wallpaper")); + co->info = eina_stringshare_add("appearance/wallpaper"); + OPT_ICON("preferences-desktop-wallpaper"); + OPT_ADD(STR, desktop_default_background, _("Default desktop wallpaper"), _("wallpaper")); + co->info_cb = _e_configure_background_info_cb; + co->funcs[0].none = co->funcs[1].none = e_bg_update; + OPT_ICON("preferences-desktop-wallpaper"); + OPT_ADD(CUSTOM, color_classes, _("Enlightenment color settings"), _("theme"), _("color")); + co->info = eina_stringshare_add("appearance/colors"); + OPT_ICON("preferences-desktop-color"); + OPT_ADD(STR, desktop_default_name, _("Default desktop name"), _("desktop"), _("name")); + OPT_HELP("Used in Pager displays"); + OPT_ICON("preferences-desktop"); + //OPT_ADD(STR, desktop_default_window_profile; + + OPT_ADD(DOUBLE, menus_scroll_speed, _("Menu scroll speed"), _("menu"), _("scroll"), _("speed")); + OPT_MINMAX_STEP_FMT(1.0, 20000.0, 100, "%5.0f pixels/s"); + OPT_HELP("Speed at which the menus move onto screen if offscreen"); + OPT_ADD(DOUBLE, menus_fast_mouse_move_threshhold, _("Menu fast move threshold"), _("menu"), _("move"), _("speed")); + OPT_MINMAX_STEP_FMT(1.0, 2000.0, 10, "%4.0f pixels/s"); + OPT_HELP("Moving the mouse faster than this speed over a menu causes menu items to not be selected"); + OPT_ADD(DOUBLE, menus_click_drag_timeout, _("Menu mouse deactivate delay"), _("menu"), _("drag"), _("delay")); + OPT_MINMAX_STEP_FMT(0.0, 10.0, 0.25, "%2.2f seconds"); + OPT_HELP("The minimum time before a menu can be closed by clicking the mouse outside the menu"); + OPT_ADD(DOUBLE_INT, menu_autoscroll_margin, _("Menu autoscroll margin"), _("menu"), _("scroll")); + OPT_MINMAX_STEP_FMT(0, 50, 1, "%2.0f pixels"); + OPT_HELP("The distance from the edge of the screen before menus begin to move away from the edge"); + OPT_ADD(DOUBLE_INT, menu_autoscroll_cursor_margin, _("Menu autoscroll cursor margin"), _("menu"), _("scroll"), _("mouse"), _("pointer")); + OPT_MINMAX_STEP_FMT(0, 50, 1, "%2.0f pixels"); + OPT_HELP("The distance of the mouse pointer from the edge of the screen before menus begin to move away from the edge"); + + OPT_ADD(BOOL, border_shade_animate, _("Enable window shading animation"), _("border"), _("shade"), _("animate")); + OPT_ADD(ENUM, border_shade_transition, _("Window shade animation type"), _("border"), _("shade"), _("animate")); //enum + co->info_cb = _e_configure_border_shade_transition_info_cb; + OPT_ICON("preferences-system-windows"); + OPT_ADD(DOUBLE, border_shade_speed, _("Window shade animation speed"), _("border"), _("shade"), _("animate"), _("speed")); + OPT_MINMAX_STEP_FMT(100, 9900, 100, "%4.0f pixels/s"); + + /* advanced */ + OPT_ADD(DOUBLE, framerate, _("Framerate"), _("speed"), _("animate")); + OPT_MINMAX_STEP_FMT(5.0, 200.0, 1, "%1.0f frames/second"); + OPT_HELP("The framerate at which animations in Enlightenment occur"); + co->funcs[0].none = _e_configure_framerate_changed; + OPT_ADD(DOUBLE_INT, priority, _("Application exec priority"), _("application"), _("exec"), _("priority")); + OPT_MINMAX_STEP_FMT(0, 19, 1, "%1.0f"); + co->funcs[0].one = ecore_exe_run_priority_set; + OPT_ADD(DOUBLE_INT, image_cache, _("Image cache size"), _("cache"), _("image"), _("size")); + OPT_MINMAX_STEP_FMT(0, 32 * 1024, 1024, "%4.0f KiB"); + co->funcs[0].none = _e_configure_framerate_changed; + OPT_ADD(DOUBLE_INT, font_cache, _("Font cache size"), _("cache"), _("font"), _("size")); + OPT_MINMAX_STEP_FMT(0, 4 * 1024, 128, "%3.0f KiB"); + co->funcs[0].none = _e_configure_framerate_changed; + OPT_ADD(DOUBLE_INT, edje_cache, _("Edje cache size"), _("cache"), _("edje"), _("size")); + OPT_MINMAX_STEP_FMT(0, 256, 1, "%1.0f files"); + co->funcs[0].none = _e_configure_framerate_changed; + OPT_ADD(DOUBLE_INT, edje_collection_cache, _("Edje collection cache size"), _("cache"), _("edje"), _("size")); + OPT_MINMAX_STEP_FMT(0, 512, 2, "%1.0f collections"); + co->funcs[0].none = _e_configure_framerate_changed; + OPT_ADD(DOUBLE_INT, cache_flush_poll_interval, _("Cache flushing interval"), _("cache"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(8, 4096, 8, "%1.0f ticks"); + co->funcs[0].none = _e_configure_framerate_changed; + + OPT_ADD(CUSTOM, path_append_data, _("Search directory settings"), _("environment")); + co->info = eina_stringshare_add("advanced/search_directories"); + OPT_ICON("preferences-directories"); + OPT_ADD(CUSTOM, path_append_data, _("Environment variable settings"), _("environment")); + co->info = eina_stringshare_add("advanced/environment_variables"); + OPT_ICON("preferences-variables"); + + OPT_ADD(CUSTOM, randr_serialized_setup, _("Screen resolution and orientation settings"), _("screen"), _("size")); + co->info = eina_stringshare_add("screen/screen_setup"); + OPT_ICON("preferences-system-screen-resolution"); + + OPT_ADD(DOUBLE_INT, zone_desks_x_count, _("Horizontal virtual desktop count"), _("vdesk"), _("desktop"), _("screen")); + co->funcs[0].none = _e_configure_zone_desks_count_changed; + OPT_ADD(DOUBLE_INT, zone_desks_y_count, _("Vertical virtual desktop count"), _("vdesk"), _("desktop"), _("screen")); + co->funcs[0].none = _e_configure_zone_desks_count_changed; + OPT_ADD(BOOL, edge_flip_dragging, _("Edge flip while dragging"), _("edge"), _("flip"), _("drag"), _("binding")); + OPT_HELP("Enable edge binding functionality while dragging objects to screen edge"); + OPT_ADD(BOOL, use_composite, _("Use ARGB instead of shaped windows"), _("border")); + + OPT_ADD(CUSTOM, modules, _("Module settings"), _("module")); + co->info = eina_stringshare_add("extensions/modules"); + OPT_ICON("preferences-plugin"); + OPT_ADD(BOOL, no_module_delay, _("Disable module delay"), _("module"), _("delay")); + OPT_HELP("If enabled, this causes E to load all modules at once during startup " + "instead of loading them incrementally"); + + /* FIXME */ + OPT_ADD(CUSTOM, language, _("Language"), _("language")); + co->info = eina_stringshare_add("language/language_settings"); + OPT_ICON("preferences-desktop-locale"); + //co->requires_restart = 1; + //co->funcs[0].one = e_intl_language_set; + OPT_ADD(CUSTOM, desklock_language, _("Desklock language"), _("desklock"), _("language")); + co->info = eina_stringshare_add("language/desklock_language_settings"); + OPT_ICON("preferences-desklock-locale"); + + OPT_ADD(ENUM, window_placement_policy, _("Window placement policy"), _("border"), _("placement")); //enum + co->info_cb = _e_configure_window_placement_policy_info_cb; + OPT_ICON("preferences-system-windows"); + OPT_HELP("Determines where and how new windows are placed when created"); + OPT_ADD(BOOL, window_grouping, _("Group new windows from same application"), _("border"), _("placement")); + OPT_ADD(BOOL, desk_auto_switch, _("Switch to desk of new window"), _("border"), _("placement"), _("vdesk")); + + OPT_ADD(ENUM, focus_policy, _("Window focus policy"), _("focus"), _("border")); //enum + co->info_cb = _e_configure_focus_policy_info_cb; + OPT_ICON("preferences-focus"); + OPT_ADD(ENUM, focus_setting, _("New window focus policy"), _("focus"), _("border")); //enum + co->info_cb = _e_configure_focus_setting_info_cb; + OPT_ICON("preferences-focus"); + OPT_ADD(BOOL, pass_click_on, _("Pass click to unfocused windows"), _("focus"), _("border"), _("click")); + OPT_HELP("When clicking an unfocused window, the click is not passed through to the application"); + OPT_ADD(ENUM, window_activehint_policy, _("Policy when applications request focus"), _("focus"), _("border")); //enum + co->info_cb = _e_configure_window_activehint_policy_info_cb; + OPT_ICON("preferences-focus"); + OPT_ADD(BOOL, always_click_to_raise, _("Always raise window when clicked"), _("focus"), _("border"), _("click"), _("raise")); + OPT_ADD(BOOL, always_click_to_focus, _("Always focus window when clicked"), _("focus"), _("border"), _("click")); + OPT_ADD(BOOL, use_auto_raise, _("Enable window autoraise"), _("focus"), _("border"), _("raise")); + OPT_ADD(DOUBLE, auto_raise_delay, _("Window autoraise delay"), _("focus"), _("border"), _("raise"), _("delay")); + OPT_MINMAX_STEP_FMT(0.0, 9.9, 0.1, "%1.1f seconds"); + OPT_ADD(BOOL, focus_last_focused_per_desktop, _("Revert window focus on desk switch"), _("border"), _("focus"), _("vdesk")); + OPT_ADD(BOOL, focus_revert_on_hide_or_close, _("Revert window focus on window hide or close"), _("border"), _("focus")); + OPT_ADD(BOOL, pointer_slide, _("Warp pointer to new windows and away from closed windows"), _("border"), _("focus"), _("warp"), _("pointer")); + OPT_ADD(BOOL, border_raise_on_mouse_action, _("Windows raise on mouse move/resize"), _("border"), _("raise"), _("focus"), _("mouse"), _("pointer"), _("move"), _("resize")); + OPT_ADD(BOOL, border_raise_on_focus, _("Windows raise when focused"), _("border"), _("raise"), _("focus"), _("mouse")); + + OPT_ADD(DOUBLE_INT, drag_resist, _("Shelf gadget resistance"), _("gadget"), _("resist"), _("drag"), _("shelf")); + OPT_MINMAX_STEP_FMT(0, 100, 2, "%2.0f pixels"); + OPT_ADD(CUSTOM, shelves, _("Shelf settings"), _("shelf"), _("desktop")); + co->info = eina_stringshare_add("extensions/shelves"); + OPT_ICON("preferences-desktop-shelf"); + + OPT_ADD(BOOL, use_resist, _("Enable resistance when dragging windows"), _("border"), _("resist"), _("drag")); + OPT_ADD(DOUBLE_INT, desk_resist, _("Window resistance against screen edges"), _("border"), _("resist"), _("vdesk"), _("screen"), _("drag")); + OPT_MINMAX_STEP_FMT(0, 100, 2, "%2.0f pixels"); + OPT_ADD(DOUBLE_INT, window_resist, _("Window resistance against other windows"), _("border"), _("resist"), _("drag")); + OPT_MINMAX_STEP_FMT(0, 100, 2, "%2.0f pixels"); + OPT_ADD(DOUBLE_INT, gadget_resist, _("Window resistance against desktop gadgets"), _("gadget"), _("resist"), _("desktop"), _("drag")); + OPT_MINMAX_STEP_FMT(0, 100, 2, "%2.0f pixels"); + + OPT_ADD(BOOL, geometry_auto_move, _("Move window after autoresizing"), _("border"), _("placement")); + OPT_ADD(BOOL, geometry_auto_resize_limit, _("Limit window autoresizing to useful geometry"), _("border"), _("placement"), _("resize")); + OPT_HELP("Useful geometry is calculated as the screen size minus the geometry of any shelves which do not allow windows to overlap them"); + + OPT_ADD(BOOL, winlist_warp_while_selecting, _("Winlist moves pointer to currently selected window while selecting"), _("border"), _("winlist"), _("focus"), _("warp"), _("pointer")); + OPT_ADD(BOOL, winlist_warp_at_end, _("Winlist moves pointer to currently selected window after winlist closes"), _("border"), _("winlist"), _("focus"), _("warp"), _("pointer")); + OPT_ADD(DOUBLE, winlist_warp_speed, _("Winlist pointer warp speed while selecting"), _("border"), _("winlist"), _("focus"), _("warp"), _("pointer"), _("speed")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(BOOL, winlist_scroll_animate, _("Enable winlist scroll animation"), _("border"), _("winlist"), _("animate")); + OPT_ADD(DOUBLE, winlist_scroll_speed, _("Winlist scroll speed"), _("border"), _("winlist"), _("animate"), _("speed")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(BOOL, winlist_list_show_iconified, _("Winlist shows iconified windows"), _("border"), _("winlist"), _("iconif")); + OPT_ADD(BOOL, winlist_list_show_other_desk_iconified, _("Winlist shows iconified windows from other desks"), _("border"), _("winlist"), _("iconif"), _("vdesk")); + OPT_ADD(BOOL, winlist_list_show_other_screen_iconified, _("Winlist shows iconified windows from other screens"), _("border"), _("winlist"), _("iconif"), _("screen")); + OPT_ADD(BOOL, winlist_list_show_other_desk_windows, _("Winlist shows windows from other desks"), _("border"), _("winlist"), _("vdesk")); + OPT_ADD(BOOL, winlist_list_show_other_screen_windows, _("Winlist shows windows from other screens"), _("border"), _("winlist"), _("screen")); + OPT_ADD(BOOL, winlist_list_uncover_while_selecting, _("Winlist uniconifies and unshades windows while selecting"), _("border"), _("winlist"), _("raise")); + OPT_ADD(BOOL, winlist_list_jump_desk_while_selecting, _("Winlist switches desks while selecting"), _("border"), _("winlist"), _("vdesk")); + OPT_ADD(BOOL, winlist_list_focus_while_selecting, _("Winlist focuses windows while selecting"), _("border"), _("winlist"), _("focus")); + OPT_ADD(BOOL, winlist_list_raise_while_selecting, _("Winlist raises windows while selecting"), _("border"), _("winlist"), _("raise"), _("focus")); + OPT_ADD(DOUBLE, winlist_pos_align_x, _("Winlist horizontal alignment"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(DOUBLE, winlist_pos_align_y, _("Winlist vertical alignment"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(DOUBLE, winlist_pos_size_w, _("Winlist width"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(DOUBLE, winlist_pos_size_h, _("Winlist height"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0.0, 1.0, 0.01, "%1.2f"); + OPT_ADD(DOUBLE_INT, winlist_pos_min_w, _("Winlist minimum width"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0, 4000, 10, "%4.0f pixels"); + OPT_ADD(DOUBLE_INT, winlist_pos_min_h, _("Winlist minimum height"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0, 4000, 10, "%4.0f pixels"); + OPT_ADD(DOUBLE_INT, winlist_pos_max_w, _("Winlist maximum width"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0, 4000, 10, "%4.0f pixels"); + OPT_ADD(DOUBLE_INT, winlist_pos_max_h, _("Winlist maximum height"), _("border"), _("winlist"), _("placement")); + OPT_MINMAX_STEP_FMT(0, 4000, 10, "%4.0f pixels"); + + OPT_ADD(ENUM, fullscreen_policy, _("Fullscreen window policy"), _("fullscreen")); //enum + co->info_cb = _e_configure_fullscreen_policy_info_cb; + OPT_ICON("preferences-window-geometry"); + OPT_ADD(ENUM, maximize_policy, _("Window maximize policy"), _("border"), _("maximize")); //enum + co->info_cb = _e_configure_maximize_policy_info_cb; + OPT_ICON("preferences-window-geometry"); + OPT_ADD(BOOL, allow_manip, _("Allow moving of maximized windows"), _("border"), _("maximize")); + OPT_ADD(BOOL, border_fix_on_shelf_toggle, _("Adjust windows on shelf toggle"), _("border"), _("shelf"), _("placement")); + OPT_HELP("When using an autohiding shelf, this option causes maximized windows to expand and contract to fill the space that the shelf occupies when it hides"); + OPT_ADD(BOOL, allow_above_fullscreen, _("Allow windows above fullscreen windows"), _("border"), _("focus"), _("placement"), _("fullscreen")); + + OPT_ADD(BOOL, kill_if_close_not_possible, _("Kill window if process not responding to close"), _("border"), _("kill")); + OPT_ADD(BOOL, kill_process, _("Kill process instead of client"), _("border"), _("kill")); + OPT_ADD(DOUBLE, kill_timer_wait, _("Window kill delay"), _("border"), _("kill"), _("delay")); + OPT_MINMAX_STEP_FMT(1, 30, 1, "%1.0f seconds"); + OPT_ADD(BOOL, ping_clients, _("Enable window client pinging"), _("border"), _("delay")); + OPT_ADD(DOUBLE_INT, ping_clients_interval, _("Window client ping interval (CPU ticks)"), _("border"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(1, 256, 1, "%1.0f seconds"); + + /* FIXME */ + OPT_ADD(CUSTOM, remembers, _("Window remember settings"), _("border"), _("remember")); + co->info = eina_stringshare_add("windows/window_remembers"); + OPT_ICON("preferences-desktop-window-remember"); + OPT_ADD(BOOL, remember_internal_windows, _("Remember internal window geometry"), _("border"), _("remember")); + OPT_HELP("This option causes E to remember the geometry of its internal dialogs and windows, NOT including filemanager windows"); + OPT_ADD(BOOL, remember_internal_fm_windows, _("Remember internal filemanager window geometry"), _("border"), _("remember"), _("files")); + OPT_HELP("This option causes E to remember the geometry of its internal filemanager windows, NOT including dialog windows"); + + OPT_ADD(BOOL, move_info_follows, _("Window position info follows window when moving"), _("border"), _("placement"), _("move")); + OPT_ADD(BOOL, resize_info_follows, _("Window geometry info follows window when resizing"), _("border"), _("placement"), _("resize")); + OPT_ADD(BOOL, move_info_visible, _("Window position info visible when moving"), _("border"), _("placement"), _("move")); + OPT_ADD(BOOL, resize_info_visible, _("Window geometry info visible when moving"), _("border"), _("placement"), _("resize")); + + OPT_ADD(CUSTOM, key_bindings, _("Key bindings"), _("input"), _("key"), _("binding")); + co->info = eina_stringshare_add("keyboard_and_mouse/key_bindings"); + OPT_ICON("preferences-desktop-keyboard-shortcuts"); + OPT_ADD(CUSTOM, mouse_bindings, _("Mouse bindings"), _("input"), _("mouse"), _("binding")); + co->info = eina_stringshare_add("keyboard_and_mouse/mouse_bindings"); + OPT_ICON("preferences-desktop-mouse"); + OPT_ADD(CUSTOM, acpi_bindings, _("ACPI bindings"), _("input"), _("acpi"), _("binding")); + co->info = eina_stringshare_add("keyboard_and_mouse/acpi_bindings"); + OPT_ICON("preferences-system-power-management"); + OPT_ADD(CUSTOM, edge_bindings, _("Screen edge bindings"), _("input"), _("edge"), _("screen"), _("binding")); + co->info = eina_stringshare_add("keyboard_and_mouse/edge_bindings"); + OPT_ICON("preferences-desktop-edge-bindings"); + OPT_ADD(CUSTOM, signal_bindings, _("Edje signal bindings"), _("input"), _("edje"), _("mouse"), _("binding")); + co->info = eina_stringshare_add("advanced/signal_bindings"); + OPT_ICON("preferences-desktop-signal-bindings"); + OPT_ADD(CUSTOM, xkb.used_layouts, _("Keyboard layout settings"), _("input"), _("key"), _("language")); + co->info = eina_stringshare_add("keyboard_and_mouse/xkbswitch"); + OPT_ICON("preferences-desktop-keyboard"); + + /* FIXME */ + OPT_ADD(CUSTOM, input_method, _("Input method"), _("input"), _("language")); + co->info = eina_stringshare_add("language/input_method_settings"); + OPT_ICON("preferences-imc"); + //co->funcs[0].one = e_intl_input_method_set; + + OPT_ADD(BOOL, transient.move, _("Transient windows follow movement of their child"), _("border"), _("transient"), _("move"), _("placement")); + OPT_ADD(BOOL, transient.resize, _("Transient windows follow resize of their child"), _("border"), _("transient"), _("placement"), _("resize")); + OPT_ADD(BOOL, transient.raise, _("Transient windows follow raise of their child"), _("border"), _("transient"), _("raise"), _("placement")); + OPT_ADD(BOOL, transient.lower, _("Transient windows follow lower of their child"), _("border"), _("transient"), _("placement"), _("raise")); + OPT_ADD(BOOL, transient.layer, _("Transient windows follow layer change of their child"), _("border"), _("transient"), _("placement")); + OPT_ADD(BOOL, transient.desktop, _("Transient windows follow desk change of their child"), _("border"), _("transient"), _("placement"), _("vdesk")); + OPT_ADD(BOOL, transient.iconify, _("Transient windows follow iconification of their child"), _("border"), _("transient"), _("iconif")); + + OPT_ADD(BOOL, menu_eap_name_show, _("Application menus shows Name field"), _("menu")); + OPT_HELP("This information is taken from the related .desktop file"); + OPT_ADD(BOOL, menu_eap_generic_show, _("Application menus shows Generic field"), _("menu")); + OPT_HELP("This information is taken from the related .desktop file"); + OPT_ADD(BOOL, menu_eap_comment_show, _("Application menus shows Comment field"), _("menu")); + OPT_HELP("This information is taken from the related .desktop file"); + + OPT_ADD(CUSTOM, path_append_data, _("Create a new application launcher"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/new_application"); + OPT_ICON("preferences-applications-add"); + OPT_ADD(CUSTOM, path_append_data, _("Application launchers"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/personal_applications"); + OPT_ICON("preferences-applications-personal"); + OPT_ADD(CUSTOM, path_append_data, _("Favorite applications"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/favorite_applications"); + OPT_ICON("user-bookmarks"); + OPT_ADD(CUSTOM, path_append_data, _("Ibar applications"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/ibar_applications"); + OPT_ICON("preferences-applications-ibar"); + OPT_ADD(CUSTOM, path_append_data, _("Desk lock applications"), _("application"), _("exec"), _("desklock")); + co->info = eina_stringshare_add("applications/screen_lock_applications"); + OPT_ICON("preferences-applications-screen-lock"); + OPT_ADD(CUSTOM, path_append_data, _("Desk unlock applications"), _("application"), _("exec"), _("desklock")); + co->info = eina_stringshare_add("applications/screen_unlock_applications"); + OPT_ICON("preferences-applications-screen-unlock"); + OPT_ADD(CUSTOM, path_append_data, _("Enlightenment restart applications"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/restart_applications"); + OPT_ICON("preferences-applications-restart"); + OPT_ADD(CUSTOM, path_append_data, _("Enlightenment start applications"), _("application"), _("exec"), _("startup")); + co->info = eina_stringshare_add("applications/startup_applications"); + OPT_ICON("preferences-applications-startup"); + OPT_ADD(CUSTOM, path_append_data, _("Enlightenment default applications"), _("application"), _("exec")); + co->info = eina_stringshare_add("applications/default_applications"); + OPT_ICON("preferences-desktop-default-applications"); + OPT_ADD(BOOL, menu_favorites_show, _("Show Favorite Applications in the main menu"), _("menu"), _("application")); + OPT_ADD(BOOL, menu_apps_show, _("Show Applications in the main menu"), _("menu"), _("application")); + + OPT_ADD(BOOL, menu_gadcon_client_toplevel, _("Show gadget settings in top-level gadget menu"), _("menu"), _("gadget")); + + OPT_ADD(STR, exebuf_term_cmd, _("Launch commands with this command"), _("exec")); + OPT_ICON("modules-launcher"); + OPT_HELP("Command used to launch files and applications"); + + OPT_ADD(BOOL, use_app_icon, _("Window borders use application icon"), _("border"), _("image")); + OPT_HELP("Applications provide their own icons. If this option is not set, E will use internal theme icons instead of the application-provided icon"); + + OPT_ADD(CUSTOM, path_append_data, _("Enlightenment profile settings"), _("profile")); + co->info = eina_stringshare_add("settings/profiles"); + OPT_ICON("preferences-profiles"); + + OPT_ADD(BOOL, cnfmdlg_disabled, _("Disable confirmation dialogs"), _("confirm"), _("dialog")); + OPT_HELP("This option suppresses all confirmation dialogs and assumes that the user has clicked the confirm option"); + OPT_ADD(BOOL, cfgdlg_auto_apply, _("Configuration dialogs automatically apply their changes"), _("dialog"), _("settings")); + OPT_HELP("This option causes any configuration options to be applied immediately when changed instead of requiring the 'Apply' button to be clicked"); + OPT_ADD(BOOL, cfgdlg_default_mode, _("Configuration dialogs show advanced view by default"), _("dialog"), _("border"), _("settings")); + OPT_HELP("Configurations dialogs can have basic and advanced views; this option causes all configuration dialogs to show the advanced view by default"); + OPT_ADD(BOOL, cfgdlg_normal_wins, _("Configuration dialog windows are normal windows"), _("dialog"), _("border")); + OPT_HELP("This option causes configuration dialogs to be normal windows instead of dialog windows"); + + OPT_ADD(CUSTOM, font_defaults, _("Enlightenment font settings"), _("font")); + co->info = eina_stringshare_add("appearance/fonts"); + OPT_ICON("preferences-desktop-font"); + OPT_ADD(ENUM, font_hinting, _("Set font hinting mode"), _("font"), _("hinting")); //enum + co->info_cb = _e_configure_font_hinting_info_cb; + OPT_ICON("preferences-desktop-font"); + +/* seems to be disabled ? + OPT_ADD(STR, desklock_personal_passwd, _("Desklock custom password"), _("desklock")); //passwd + OPT_HELP("This option causes desklock to use a custom-provided password instead of the user's password"); +*/ + OPT_ADD(BOOL, desklock_auth_method, _("Use custom command for desklock"), _("desklock"), _("exec")); + OPT_HELP("This option allows an external application to manage desklock"); + OPT_ADD(STR, desklock_custom_desklock_cmd, _("Custom desklock command"), _("desklock"), _("exec")); + OPT_ICON("preferences-system-lock-screen"); + OPT_ADD(ENUM, desklock_login_box_zone, _("Desklock login box shows on which screen?"), _("desklock"), _("screen")); //enum+slider + co->info_cb = _e_configure_desklock_login_box_zone_info_cb; + OPT_ICON("preferences-system-lock-screen"); + OPT_ADD(BOOL, desklock_start_locked, _("Desklock activates on login"), _("desklock")); + OPT_ADD(BOOL, desklock_on_suspend, _("Desklock activates on resume from suspend"), _("desklock")); + OPT_ADD(BOOL, desklock_autolock_screensaver, _("Desklock activates during screensaver"), _("desklock"), _("delay"), _("screensaver")); + OPT_ADD(DOUBLE, desklock_post_screensaver_time, _("Desklock activates X seconds after screensaver activates"), _("desklock"), _("delay"), _("screensaver")); + OPT_MINMAX_STEP_FMT(0.0, 300.0, 10, "%2.0f seconds"); + OPT_ADD(BOOL, desklock_autolock_idle, _("Desklock activates when idle"), _("desklock"), _("delay")); + OPT_ADD(DOUBLE, desklock_autolock_idle_timeout, _("Desklock activates when idle for X seconds"), _("desklock"), _("delay")); + OPT_MINMAX_STEP_FMT(30, 5400.0, 60, "%2.0f seconds"); + OPT_ADD(BOOL, desklock_use_custom_desklock, _("Use custom desklock wallpaper"), _("desklock"), _("wallpaper")); + OPT_ADD(BOOL, desklock_ask_presentation, _("Prompt for desklock timer delay if deactivated quickly"), _("desklock"), _("delay")); + OPT_ADD(DOUBLE, desklock_ask_presentation_timeout, _("Desklock quick deactivation timer delay"), _("desklock"), _("delay")); + OPT_MINMAX_STEP_FMT(1.0, 300.0, 10, "%2.0f seconds"); + + OPT_ADD(BOOL, screensaver_enable, _("Enable screensaver"), _("screensaver")); + OPT_ADD(DOUBLE_INT, screensaver_timeout, _("Screensaver activates when idle for X seconds"), _("screensaver"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(30, 5400, 60, "%2.0f seconds"); + + //OPT_ADD(INT, screensaver_interval, _("screensaver"), _("delay")); NOT USED? + //OPT_ADD(INT, screensaver_blanking, _("screensaver"), _("delay")); NOT USED? + //OPT_ADD(INT, screensaver_expose, _("screensaver"), _("delay")); NOT USED? + OPT_ADD(BOOL, screensaver_ask_presentation, _("Prompt for screensaver timer delay if deactivated quickly"), _("screensaver")); + co->funcs[0].none = co->funcs[1].none = _e_configure_screensaver_changed; + OPT_ADD(DOUBLE, screensaver_ask_presentation_timeout, _("Screensaver quick deactivation timer delay"), _("screensaver"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(1.0, 300.0, 10, "%2.0f seconds"); + co->funcs[0].none = co->funcs[1].none = _e_configure_screensaver_changed; + OPT_ADD(BOOL, screensaver_suspend, _("Suspend when screensaver activates"), _("screensaver")); + co->funcs[0].none = co->funcs[1].none = _e_configure_screensaver_changed; + OPT_ADD(BOOL, screensaver_suspend_on_ac, _("Suspend when screensaver activates even if on AC"), _("screensaver")); + co->funcs[0].none = co->funcs[1].none = _e_configure_screensaver_changed; + OPT_ADD(DOUBLE, screensaver_suspend_delay, _("Screensaver suspend delay"), _("screensaver"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(1.0, 20.0, 1, "%1.0f seconds"); + co->funcs[0].none = co->funcs[1].none = _e_configure_screensaver_changed; + +/* appears to use screensaver values + OPT_ADD(BOOL, dpms_enable, _("Enable DPMS"), _("dpms")); + OPT_ADD(BOOL, dpms_standby_enable, _("dpms")); + OPT_ADD(DOUBLE_INT, dpms_standby_timeout, _("dpms"), _("delay")); + OPT_MINMAX_STEP_FMT(30, 5400); + OPT_ADD(BOOL, dpms_suspend_enable, _("dpms")); + OPT_ADD(DOUBLE_INT, dpms_suspend_timeout, _("dpms"), _("delay")); + OPT_MINMAX_STEP_FMT(30, 5400); + OPT_ADD(BOOL, dpms_off_enable, _("dpms")); + OPT_ADD(DOUBLE_INT, dpms_off_timeout, _("dpms"), _("delay")); + OPT_MINMAX_STEP_FMT(30, 5400); +*/ + OPT_ADD(ENUM, clientlist_group_by, _("Window list menu grouping policy"), _("menu"), _("border")); //enum + co->info_cb = _e_configure_clientlist_group_by_info_cb; + OPT_ICON("preferences-winlist"); + OPT_ADD(BOOL, clientlist_include_all_zones, _("Window list menu includes windows from all screens"), _("menu"), _("border"), _("screen")); + OPT_ADD(ENUM, clientlist_separate_with, _("Window list menu separator policy"), _("menu"), _("border")); //enum + co->info_cb = _e_configure_clientlist_separate_with_info_cb; + OPT_ICON("preferences-winlist"); + OPT_ADD(ENUM, clientlist_sort_by, _("Window list menu sort policy"), _("menu"), _("border")); //enum + co->info_cb = _e_configure_clientlist_sort_by_info_cb; + OPT_ICON("preferences-winlist"); + OPT_ADD(ENUM, clientlist_separate_iconified_apps, _("Window list menu iconified window grouping policy"), _("menu"), _("border"), _("iconif")); //enum + co->info_cb = _e_configure_clientlist_separate_iconified_apps_info_cb; + OPT_ICON("preferences-winlist"); + OPT_ADD(BOOL, clientlist_warp_to_iconified_desktop, _("Window list menu warps to desktop of selected iconified window"), _("menu"), _("border"), _("warp"), _("vdesk")); + OPT_ADD(BOOL, clientlist_limit_caption_len, _("Enable window list menu length limit"), _("menu"), _("border"), _("size")); + OPT_ADD(DOUBLE_INT, clientlist_max_caption_len, _("Window list menu length limit (characters)"), _("menu"), _("border"), _("size")); //slider + OPT_MINMAX_STEP_FMT(2, E_CLIENTLIST_MAX_CAPTION_LEN, 2, "%1.0f characters"); + + OPT_ADD(BOOL, use_e_cursor, _("Use Enlightenment theme cursor"), _("pointer"), _("theme")); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + OPT_ADD(DOUBLE_INT, cursor_size, _("Mouse cursor size"), _("pointer"), _("size"), _("theme")); + OPT_MINMAX_STEP_FMT(8, 128, 4, "%1.0f pixels"); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + OPT_ADD(BOOL, show_cursor, _("Show mouse cursor"), _("pointer")); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + OPT_ADD(BOOL, idle_cursor, _("Enable idle effects for mouse cursor"), _("pointer"), _("animate")); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + OPT_ADD(BOOL, mouse_hand, _("Enable left-handed mouse"), _("mouse")); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + /* FIXME: need to group these two + OPT_ADD(DOUBLE_INT, mouse_accel_numerator, _("mouse"), _("speed")); //slider + OPT_MINMAX_STEP_FMT(1, 10); + OPT_ADD(DOUBLE_INT, mouse_accel_denominator, _("mouse"), _("speed")); //also slider + OPT_MINMAX_STEP_FMT(1, 10); + */ + OPT_ADD(DOUBLE_INT, mouse_accel_threshold, _("Mouse acceleration threshold"), _("mouse"), _("speed")); + OPT_MINMAX_STEP_FMT(1, 10, 1, "%1.0f"); + co->funcs[0].none = co->funcs[1].none = _e_configure_pointer_changed; + + OPT_ADD(BOOL, desk_flip_wrap, _("Enable desk flip between last and first desks"), _("vdesk"), _("flip"), _("edge")); + OPT_ADD(BOOL, fullscreen_flip, _("Enable desk flipping with fullscreen windows"), _("vdesk"), _("flip"), _("edge"), _("fullscreen")); + OPT_ADD(BOOL, multiscreen_flip, _("Enable desk flipping with multiple monitors (DANGEROUS)"), _("vdesk"), _("flip"), _("edge"), _("screen")); + + OPT_ADD(ENUM, desk_flip_animate_mode, _("Desk flip animation type"), _("vdesk"), _("animate"), _("flip")); //enum + co->info_cb = _e_configure_desk_flip_animate_mode_info_cb; + OPT_ICON("preferences-desktop"); + //OPT_ADD(INT, desk_flip_animate_interpolation, _("vdesk"), _("animate"), _("flip")); //NOT USED? + OPT_ADD(DOUBLE, desk_flip_animate_time, _("Desk flip animation length"), _("vdesk"), _("animate"), _("flip"), _("speed")); + OPT_MINMAX_STEP_FMT(0, 5, 0.05, "%1.2f seconds"); + + OPT_ADD(STR, theme_default_border_style, _("Default window border style"), _("border"), _("theme")); + co->info_cb = _e_configure_border_style_info_cb; + co->thumb_cb = _e_configure_border_style_thumb_cb; + OPT_ICON("preferences-system-windows"); + + OPT_ADD(ENUM, screen_limits, _("Window screen limit policy"), _("screen"), _("size"), _("border"), _("placement")); //enum + co->info_cb = _e_configure_screen_limits_info_cb; + OPT_ICON("preferences-system-windows"); + + OPT_ADD(DOUBLE_INT, thumb_nice, _("Thumbnailing process priority"), _("priority"), _("image")); //enum + OPT_MINMAX_STEP_FMT(0, 19, 1, "%1.0f"); + OPT_HELP("Enlightenment runs its own thumbnailing daemon in the background. This option configures the priority of that process"); + + OPT_ADD(BOOL, thumbscroll_enable, _("Enable click-to-drag scrolling (thumbscrolling)"), _("scroll")); + OPT_ADD(DOUBLE_INT, thumbscroll_threshhold, _("Thumbscroll threshold"), _("scroll"), _("speed")); //slider + OPT_MINMAX_STEP_FMT(0, 64, 4, "%1.0f pixels"); + OPT_ADD(DOUBLE, thumbscroll_momentum_threshhold, _("Thumbscroll momentum threshold"), _("scroll"), _("speed")); //slider + OPT_MINMAX_STEP_FMT(0, 2000, 20, "%1.0f pixels/second"); + OPT_ADD(DOUBLE, thumbscroll_friction, _("Thumbscroll resistance"), _("scroll"), _("resist")); //slider + OPT_MINMAX_STEP_FMT(0, 5.0, 0.1, "%1.0f"); + + OPT_ADD(BOOL, show_desktop_icons, _("Show files on desktop"), _("desktop"), _("files")); + co->changed_action = eina_stringshare_add("fileman_reset"); + OPT_ADD(BOOL, filemanager_single_click, _("Filemanager uses single click to activate"), _("click"), _("files")); + co->changed_action = eina_stringshare_add("fileman_reset"); + OPT_ADD(BOOL, device_desktop, _("Filemanager shows removable devices on desktop"), _("desktop"), _("files")); + co->funcs[0].none = e_fm2_device_hide_desktop_icons; + co->funcs[1].none = e_fm2_device_show_desktop_icons; + OPT_ADD(BOOL, device_auto_mount, _("Filemanager automatically mounts removable devices when attached"), _("files")); + OPT_ADD(BOOL, device_auto_open, _("Filemanager automatically opens removable devices when attached"), _("files")); + OPT_ADD(BOOL, filemanager_copy, _("Filemanager always performs `cp+rm` instead of `mv`"), _("files")); + OPT_ADD(BOOL, filemanager_secure_rm, _("Filemanager deletes files securely"), _("files")); + + OPT_ADD(DOUBLE, border_keyboard.timeout, _("Window change timeout when moving or resizing using keyboard"), _("border"), _("placement"), _("delay"), _("key")); //slider + OPT_MINMAX_STEP_FMT(1, 10, 1, "%1.0f seconds"); + OPT_ADD(DOUBLE_UCHAR, border_keyboard.move.dx, _("Window horizontal movement speed when using keyboard"), _("border"), _("placement"), _("move"), _("key")); //slider + OPT_MINMAX_STEP_FMT(1, 255, 1, "%1.0f pixels"); + OPT_ADD(DOUBLE_UCHAR, border_keyboard.move.dy, _("Window vertical movement speed when using keyboard"), _("border"), _("placement"), _("move"), _("key")); //slider + OPT_MINMAX_STEP_FMT(1, 255, 1, "%1.0f pixels"); + OPT_ADD(DOUBLE_UCHAR, border_keyboard.resize.dx, _("Window horizontal resize speed when using keyboard"), _("border"), _("placement"), _("resize"), _("key")); //slider + OPT_MINMAX_STEP_FMT(1, 255, 1, "%1.0f pixels"); + OPT_ADD(DOUBLE_UCHAR, border_keyboard.resize.dy, _("Window vertical movement speed when using keyboard"), _("border"), _("placement"), _("resize"), _("key")); //slider + OPT_MINMAX_STEP_FMT(1, 255, 1, "%1.0f pixels"); + + //OPT_ADD(DOUBLE, scale.min, _("Minimum scaling"), _("scale"), _("size")); + //co->requires_restart = 1; + //OPT_ADD(DOUBLE, scale.max, _("Maximum scaling"), _("scale"), _("size")); + //co->requires_restart = 1; + OPT_ADD(DOUBLE, scale.factor, _("Overall scaling factor"), _("scale"), _("size")); + OPT_MINMAX_STEP_FMT(0.25, 8.0, 0.25, "%1.2f pixels"); + co->requires_restart = 1; + OPT_ADD(BOOL, scale.use_dpi, _("Use screen DPI for scaling"), _("scale"), _("size")); + co->requires_restart = 1; + OPT_ADD(BOOL, scale.use_custom, _("Use custom DPI for scaling"), _("scale"), _("size")); + co->requires_restart = 1; + OPT_ADD(DOUBLE_INT, scale.base_dpi, _("Custom DPI to use when scaling"), _("scale"), _("size")); + OPT_MINMAX_STEP_FMT(30, 800, 1, "%1.0f DPI"); + co->requires_restart = 1; + + OPT_ADD(DOUBLE_INT, syscon.main.icon_size, _("System Console primary action icon size"), _("syscon"), _("size"), _("image")); + OPT_MINMAX_STEP_FMT(16, 256, 4, "%1.0f pixels"); + OPT_ADD(DOUBLE_INT, syscon.secondary.icon_size, _("System Console secondary action icon size"), _("syscon"), _("size"), _("image")); + OPT_MINMAX_STEP_FMT(16, 256, 4, "%1.0f pixels"); + OPT_ADD(DOUBLE_INT, syscon.extra.icon_size, _("System Console extra action icon size"), _("syscon"), _("size"), _("image")); + OPT_MINMAX_STEP_FMT(16, 256, 4, "%1.0f pixels"); + OPT_ADD(DOUBLE, syscon.timeout, _("System Console idle timeout"), _("syscon"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(0, 60, 1, "%1.0f seconds"); + OPT_ADD(BOOL, syscon.do_input, _("System Console performs default action after idle timeout"), _("syscon"), _("input")); + //Eina_List *actions + + OPT_ADD(DOUBLE, backlight.normal, _("Backlight \"normal\" brightness"), _("backlight")); //slider + OPT_MINMAX_STEP_FMT(0, 1.0, 0.01, "%1.2f"); + co->funcs[0].none = _e_configure_dpms_changed; + OPT_ADD(DOUBLE, backlight.dim, _("Backlight \"dim\" brightness"), _("backlight")); //slider + OPT_MINMAX_STEP_FMT(0, 1.0, 0.01, "%1.2f"); + co->funcs[0].none = _e_configure_dpms_changed; + OPT_ADD(DOUBLE, backlight.transition, _("Backlight transition length"), _("backlight"), _("animate"), _("speed")); //slider + OPT_MINMAX_STEP_FMT(0, 5.0, 0.1, "%1.1f seconds"); + co->funcs[0].none = _e_configure_dpms_changed; + OPT_ADD(BOOL, backlight.idle_dim, _("Backlight dims after idle"), _("backlight")); + co->funcs[0].none = co->funcs[1].none = _e_configure_dpms_changed; + OPT_ADD(DOUBLE, backlight.timer, _("Backlight idle delay"), _("backlight"), _("delay")); //slider + OPT_MINMAX_STEP_FMT(5, 300, 1, "%1.0f seconds"); + co->funcs[0].none = _e_configure_dpms_changed; + + /* FIXME + OPT_ADD(DOUBLE, powersave.none, _("powersave")); + OPT_MINMAX_STEP_FMT(0.01, 5400.00); + OPT_ADD(DOUBLE, powersave.low, _("powersave")); + OPT_MINMAX_STEP_FMT(0.01, 5400.00); + OPT_ADD(DOUBLE, powersave.medium, _("powersave")); + OPT_MINMAX_STEP_FMT(0.01, 5400.00); + OPT_ADD(DOUBLE, powersave.high, _("powersave")); + OPT_MINMAX_STEP_FMT(0.01, 5400.00); + OPT_ADD(DOUBLE, powersave.extreme, _("powersave")); + OPT_MINMAX_STEP_FMT(0.01, 5400.00); + OPT_ADD(DOUBLE_UINT, powersave.min, _("powersave")); + OPT_MINMAX_STEP_FMT(E_POWERSAVE_MODE_NONE, E_POWERSAVE_MODE_EXTREME); + OPT_ADD(DOUBLE_UINT, powersave.max, _("powersave")); + OPT_MINMAX_STEP_FMT(E_POWERSAVE_MODE_NONE, E_POWERSAVE_MODE_EXTREME); + */ + OPT_ADD(BOOL, deskenv.load_xrdb, _("Load ~/.xrdb on startup"), _("environment")); + OPT_ADD(BOOL, deskenv.load_xmodmap, _("Load ~/.Xmodmap"), _("environment")); + OPT_ADD(BOOL, deskenv.load_gnome, _("Run gnome-settings-daemon"), _("environment")); + OPT_ADD(BOOL, deskenv.load_kde, _("Run kdeinit"), _("environment")); + + OPT_ADD(BOOL, xsettings.enabled, _("Enable GTK application settings"), _("environment"), _("theme"), _("xsettings")); + co->funcs[1].none = co->funcs[0].none = e_xsettings_config_update; + OPT_ADD(BOOL, xsettings.match_e17_theme, _("Try setting GTK theme to match E17 theme"), _("environment"), _("theme"), _("xsettings")); + co->funcs[1].none = co->funcs[0].none = e_xsettings_config_update; + OPT_ADD(STR, xsettings.net_theme_name, _("GTK theme name"), _("environment"), _("theme"), _("name"), _("xsettings")); + co->funcs[0].none = e_xsettings_config_update; + co->info_cb = _e_configure_netwm_theme_info_cb; + co->thumb_cb = _e_configure_netwm_theme_thumb_cb; + OPT_ICON("preferences-desktop-theme"); + + OPT_ADD(BOOL, xsettings.match_e17_icon_theme, _("Enable use of icon theme for applications"), _("environment"), _("theme"), _("image"), _("xsettings")); + co->funcs[0].none = e_xsettings_config_update; + OPT_ADD(STR, icon_theme, _("Icon theme"), _("environment"), _("image"), _("theme"), _("xsettings")); //enum + co->funcs[0].none = e_xsettings_config_update; + co->info_cb = _e_configure_icon_theme_info_cb; + co->thumb_cb = _e_configure_icon_theme_thumb_cb; + co->event_type = E_EVENT_CONFIG_ICON_THEME; + OPT_ICON("preferences-desktop-theme"); + OPT_ADD(BOOL, icon_theme_overrides, _("Icon theme overrides E17 internal theme icons"), _("environment"), _("image"), _("theme"), _("xsettings")); // + co->funcs[1].none = co->funcs[0].none = e_xsettings_config_update; + + OPT_ADD(BOOL, exe_always_single_instance, _("Always launch applications as single-instance"), _("exec")); + //OPT_ADD(INT, use_desktop_window_profile, + + + e_user_dir_concat_static(buf, "themes"); + theme_ls[0] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + theme_mon[0] = eio_monitor_add(buf); + e_prefix_data_concat_static(buf, "data/themes"); + theme_ls[1] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + theme_mon[1] = eio_monitor_add(buf); + + e_user_homedir_concat_static(buf, ".themes"); + gtk_theme_ls = eio_file_ls(buf, _gtk_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + gtk_theme_mon = eio_monitor_add(buf); + { + const char *dir; + const Eina_List *l; + + EINA_LIST_FOREACH(efreet_data_dirs_get(), l, dir) + { + Eio_File *ls; + + snprintf(buf, sizeof(buf), "%s/themes", dir); + ls = eio_file_ls(buf, _gtk_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + if (!ls) continue; + gtk_theme_dirs = eina_list_append(gtk_theme_dirs, ls); + gtk_theme_mons = eina_list_append(gtk_theme_mons, eio_monitor_add(buf)); + } + } + + e_user_dir_concat_static(buf, "backgrounds"); + bg_ls[0] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + bg_mon[0] = eio_monitor_add(buf); + e_prefix_data_concat_static(buf, "data/backgrounds"); + bg_ls[1] = eio_file_ls(buf, _edj_filter_cb, _init_main_cb, _init_done_cb, _init_error_cb, NULL); + bg_mon[1] = eio_monitor_add(buf); + + E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_SELF_DELETED, _monitor_error, NULL); + E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_FILE_CREATED, _monitor_theme_rescan, NULL); + E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_FILE_DELETED, _monitor_theme_rescan, NULL); + E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_ERROR, _monitor_error, NULL); + + category_hash = eina_hash_string_superfast_new((Eina_Free_Cb)eina_list_free); + category_icon_hash = eina_hash_string_superfast_new((Eina_Free_Cb)eina_stringshare_del); + + e_configure_option_category_tag_add(_("appearance"), _("wallpaper")); + e_configure_option_category_tag_add(_("appearance"), _("splash")); + e_configure_option_category_tag_add(_("appearance"), _("font")); + e_configure_option_category_tag_add(_("appearance"), _("border")); + e_configure_option_category_tag_add(_("appearance"), _("transition")); + e_configure_option_category_tag_add(_("appearance"), _("scale")); + e_configure_option_category_tag_add(_("appearance"), _("xsettings")); + e_configure_option_category_icon_set(_("appearance"), "preferences-look"); + + e_configure_option_category_tag_add(_("applications"), _("application")); + e_configure_option_category_tag_add(_("applications"), _("files")); + e_configure_option_category_tag_add(_("applications"), _("xsettings")); + e_configure_option_category_icon_set(_("applications"), "preferences-applications"); + + e_configure_option_category_tag_add(_("screen"), _("desklock")); + e_configure_option_category_tag_add(_("screen"), _("screen")); + e_configure_option_category_tag_add(_("screen"), _("vdesk")); + e_configure_option_category_tag_add(_("screen"), _("desktop")); + e_configure_option_category_tag_add(_("screen"), _("shelf")); + e_configure_option_category_icon_set(_("screen"), "preferences-desktop-display"); + + e_configure_option_category_tag_add(_("windows"), _("border")); + e_configure_option_category_tag_add(_("windows"), _("focus")); + e_configure_option_category_tag_add(_("windows"), _("winlist")); + e_configure_option_category_tag_add(_("windows"), _("placement")); + e_configure_option_category_tag_add(_("windows"), _("resist")); + e_configure_option_category_tag_add(_("windows"), _("remember")); + e_configure_option_category_tag_add(_("windows"), _("iconif")); + e_configure_option_category_tag_add(_("windows"), _("kill")); + e_configure_option_category_tag_add(_("windows"), _("transient")); + e_configure_option_category_tag_add(_("windows"), _("move")); + e_configure_option_category_tag_add(_("windows"), _("resize")); + e_configure_option_category_icon_set(_("windows"), "preferences-system-windows"); + + e_configure_option_category_tag_add(_("menus"), _("menu")); + e_configure_option_category_icon_set(_("menus"), "preferences-menus"); + + e_configure_option_category_tag_add(_("input"), _("mouse")); + e_configure_option_category_tag_add(_("input"), _("pointer")); + e_configure_option_category_tag_add(_("input"), _("key")); + e_configure_option_category_tag_add(_("input"), _("binding")); + e_configure_option_category_icon_set(_("input"), "preferences-behavior"); + + e_configure_option_category_tag_add(_("advanced"), _("framerate")); + e_configure_option_category_tag_add(_("advanced"), _("cache")); + e_configure_option_category_tag_add(_("advanced"), _("priority")); + e_configure_option_category_icon_set(_("advanced"), "preferences-advanced"); + + e_configure_option_category_tag_add(_("settings"), _("dialog")); + e_configure_option_category_tag_add(_("settings"), _("profile")); + e_configure_option_category_tag_add(_("settings"), _("module")); + e_configure_option_category_icon_set(_("settings"), "preferences-preferences"); + + event_block = EINA_FALSE; + + return 1; +} + +EINTERN int +e_configure_option_shutdown(void) +{ + Eina_Stringshare *tag; + + opts_changed_list = eina_list_free(opts_changed_list); + event_block = EINA_TRUE; + EINA_LIST_FREE(tags_list, tag) + { + eina_hash_del_by_key(tags_hash, tag); + eina_stringshare_del(tag); + } + while (opts_list) + _e_configure_option_free((E_Configure_Option*)opts_list); + E_FN_DEL(eina_hash_free, tags_hash); + E_FN_DEL(eio_monitor_del, theme_mon[0]); + E_FN_DEL(eio_monitor_del, theme_mon[1]); + E_FN_DEL(eio_file_cancel, theme_ls[0]); + E_FN_DEL(eio_file_cancel, theme_ls[1]); + E_FN_DEL(eio_file_cancel, gtk_theme_ls); + E_FREE_LIST(gtk_theme_dirs, eio_file_cancel); + E_FN_DEL(eio_monitor_del, gtk_theme_mon); + E_FREE_LIST(gtk_theme_mons, eio_monitor_del); + E_FREE_LIST(gtk_themes, eina_stringshare_del); + E_FREE_LIST(themes, eina_stringshare_del); + E_FREE_LIST(sthemes, eina_stringshare_del); + E_FN_DEL(eio_monitor_del, bg_mon[0]); + E_FN_DEL(eio_monitor_del, bg_mon[1]); + E_FN_DEL(eio_file_cancel, bg_ls[0]); + E_FN_DEL(eio_file_cancel, bg_ls[1]); + E_FREE_LIST(bgs, eina_stringshare_del); + E_FREE_LIST(sbgs, eina_stringshare_del); + E_FREE_LIST(handlers, ecore_event_handler_del); + E_FN_DEL(eina_hash_free, category_hash); + E_FN_DEL(eina_hash_free, category_icon_hash); + categories = eina_list_free(categories); + return 1; +} + +EAPI E_Configure_Option * +e_configure_option_add(E_Configure_Option_Type type, const char *desc, const char *name, Eina_Bool private_scope, void *valptr, const void *data) +{ + E_Configure_Option *co; + + co = E_NEW(E_Configure_Option, 1); + if (!private_scope) + opts_list = eina_inlist_append(opts_list, EINA_INLIST_GET(co)); + co->type = type; + _e_configure_option_value_reset(co); + co->name = eina_stringshare_add(name); + co->desc = eina_stringshare_add(desc); + co->valptr = valptr; + co->data = (void*)data; + co->private = !!private_scope; + _e_configure_option_event_changed(co); + return co; +} + +EAPI void +e_configure_option_tags_set(E_Configure_Option *co, const char **const tags, unsigned int num_tags) +{ + Eina_List *l, *ll; + Eina_Stringshare *tag; + unsigned int x; + const char **t; + + EINA_SAFETY_ON_NULL_RETURN(co); + EINA_LIST_FOREACH_SAFE(co->tags, l, ll, tag) + _e_configure_option_tag_remove(co, tag); + if (!tags) return; + if (num_tags) + { + for (x = 0; x < num_tags; x++) + _e_configure_option_tag_append(co, tags[x]); + + } + else + { + for (t = tags; t && *t; t++) + _e_configure_option_tag_append(co, *t); + } +} + +EAPI E_Configure_Option_Info * +e_configure_option_info_new(E_Configure_Option *co, const char *name, const void *value) +{ + E_Configure_Option_Info *oi; + + oi = E_NEW(E_Configure_Option_Info, 1); + oi->co = co; + oi->name = eina_stringshare_add(name); + oi->value = (void*)value; + return oi; +} + +EAPI void +e_configure_option_info_free(E_Configure_Option_Info *oi) +{ + if (!oi) return; + eina_stringshare_del(oi->name); + eina_stringshare_del(oi->thumb_file); + eina_stringshare_del(oi->thumb_key); + free(oi); +} + +EAPI Eina_List * +e_configure_option_info_get(E_Configure_Option *co) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(co, NULL); + if (!co->info_cb) return NULL; + return co->info_cb(co); +} + +EAPI Evas_Object * +e_configure_option_info_thumb_get(E_Configure_Option_Info *oi, Evas *evas) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(oi, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL); + if (!oi->co->thumb_cb) return NULL; + return oi->co->thumb_cb(oi, evas); +} + +EAPI void +e_configure_option_del(E_Configure_Option *co) +{ + Eina_List *l, *ll; + Eina_Stringshare *tag; + + if (!co) return; + if (!event_block) + { + _e_configure_option_event_del(co); + return; + } + EINA_LIST_FOREACH_SAFE(co->tags, l, ll, tag) + _e_configure_option_tag_remove(co, tag); + _e_configure_option_free(co); +} + +EAPI void * +e_configure_option_data_set(E_Configure_Option *co, const char *key, const void *data) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(co, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); + if ((!co->data) && (!data)) return NULL; + if (!co->data) co->data = eina_hash_string_small_new(NULL); + return eina_hash_set(co->data, key, data); +} + +EAPI void * +e_configure_option_data_get(E_Configure_Option *co, const char *key) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(co, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); + if (!co->data) return NULL; + return eina_hash_find(co->data, key); +} + +EAPI void +e_configure_option_changed(E_Configure_Option *co) +{ + Eina_Bool e_restart; + unsigned char u; + int i; + unsigned int ui; + double d; + long long int l; + Eina_Stringshare *s; + Eina_Bool changed; + + EINA_SAFETY_ON_NULL_RETURN(co); + changed = co->changed; + co->changed = EINA_TRUE; + if (!e_config->cfgdlg_auto_apply) + { + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + eina_value_get(&co->val, &u); + if (*(unsigned char*)co->valptr != u) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + eina_value_get(&co->val, &d); + l = lround(d); + u = MAX(0, l); + if (*(unsigned char*)co->valptr != u) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: //lround(double) + eina_value_get(&co->val, &d); + if (*(int*)co->valptr != lround(d)) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_INT: + case E_CONFIGURE_OPTION_TYPE_ENUM: + eina_value_get(&co->val, &i); + if (*(int*)co->valptr != i) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: //lround(double) + eina_value_get(&co->val, &d); + l = lround(d); + ui = MAX(0, l); + if (*(unsigned int*)co->valptr != ui) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_UINT: + eina_value_get(&co->val, &ui); + if (*(unsigned int*)co->valptr != ui) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + eina_value_get(&co->val, &d); + if (fabs(*(double*)co->valptr - d) > DBL_EPSILON) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_STR: + eina_value_get(&co->val, &s); + if (*(Eina_Stringshare**)co->valptr != s) break; + co->changed = EINA_FALSE; + break; + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + break; + } + if (changed && (!co->changed)) + { + _e_configure_option_value_reset(co); + opts_changed_list = eina_list_remove(opts_changed_list, co); + } + else if ((!changed) && (co->changed)) + opts_changed_list = eina_list_append(opts_changed_list, co); + } + else + { + e_restart = _e_configure_option_apply(co, NULL, NULL, NULL); + e_config_save_queue(); + if (e_restart) e_sys_action_do(E_SYS_RESTART, NULL); + } + _e_configure_option_event_changed(co); +} + +EAPI void +e_configure_option_reset(E_Configure_Option *co) +{ + EINA_SAFETY_ON_NULL_RETURN(co); + + if (!co->changed) return; + _e_configure_option_value_reset(co); + opts_changed_list = eina_list_remove(opts_changed_list, co); + co->changed = EINA_FALSE; + _e_configure_option_event_changed(co); +} + +EAPI void +e_configure_option_reset_all(void) +{ + E_Configure_Option *co; + + EINA_LIST_FREE(opts_changed_list, co) + { + _e_configure_option_value_reset(co); + co->changed = EINA_FALSE; + _e_configure_option_event_changed(co); + } +} + +EAPI void +e_configure_option_apply(E_Configure_Option *co) +{ + Eina_Bool e_restart; + + EINA_SAFETY_ON_NULL_RETURN(co); + + if (!co->changed) return; + + if (opts_changed_list) + opts_changed_list = eina_list_remove(opts_changed_list, co); + e_restart = _e_configure_option_apply(co, NULL, NULL, NULL); + e_config_save_queue(); + if (e_restart) e_sys_action_do(E_SYS_RESTART, NULL); +} + +EAPI void +e_configure_option_apply_all(void) +{ + E_Configure_Option *co; + Eina_Bool e_restart = EINA_FALSE; + Eina_List *events = NULL, *funcs = NULL, *acts = NULL; + E_Action *act; + void (*none)(void); + intptr_t *event; + + EINA_LIST_FREE(opts_changed_list, co) + e_restart |= _e_configure_option_apply(co, &events, &funcs, &acts); + EINA_LIST_FREE(events, event) + ecore_event_add((long)event, NULL, NULL, NULL); + EINA_LIST_FREE(funcs, none) + none(); + EINA_LIST_FREE(acts, act) + act->func.go((E_Object*)e_util_container_current_get(), NULL); + e_config_save_queue(); + if (e_restart) e_sys_action_do(E_SYS_RESTART, NULL); +} + +EAPI const void * +e_configure_option_value_get(E_Configure_Option *co) +{ + static unsigned char u; + static double d; + static long l; + static unsigned int i; + static Eina_Stringshare *s; + + EINA_SAFETY_ON_NULL_RETURN_VAL(co, NULL); + if (e_config->cfgdlg_auto_apply || (!co->changed)) return co->valptr; + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + eina_value_get(&co->val, &u); + return &u; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: //lround(double) + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: //lround(double) + case E_CONFIGURE_OPTION_TYPE_ENUM: //lround(double) + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + eina_value_get(&co->val, &d); + return &d; + case E_CONFIGURE_OPTION_TYPE_INT: + eina_value_get(&co->val, &l); + return &l; + case E_CONFIGURE_OPTION_TYPE_UINT: + eina_value_get(&co->val, &i); + return &i; + case E_CONFIGURE_OPTION_TYPE_STR: + eina_value_get(&co->val, &s); + return &s; + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + break; + } + return NULL; +} + +EAPI const Eina_List * +e_configure_option_tags_list(void) +{ + return tags_list; +} + +EAPI const Eina_List * +e_configure_option_changed_list(void) +{ + return opts_changed_list; +} + +EAPI const Eina_List * +e_configure_option_tag_list_options(const char *tag) +{ + if (!tags_hash) return NULL; + return eina_hash_find(tags_hash, tag); +} + +EAPI const Eina_List * +e_configure_option_category_list_tags(const char *cat) +{ + if (!categories) return NULL; + return eina_hash_find(category_hash, cat); +} + +EAPI const Eina_List * +e_configure_option_category_list(void) +{ + return categories; +} + +EAPI void +e_configure_option_category_tag_add(const char *cat, const char *tag) +{ + Eina_List *l; + Eina_Stringshare *t, *c; + + EINA_SAFETY_ON_NULL_RETURN(cat); + EINA_SAFETY_ON_NULL_RETURN(tag); + t = eina_stringshare_add(tag); + if (!eina_list_data_find(tags_list, t)) + { + eina_stringshare_del(t); + return; + } + if (!categories) + { + c = eina_stringshare_add(cat); + eina_hash_add(category_hash, cat, eina_list_append(NULL, t)); + categories = eina_list_append(categories, c); + _e_configure_option_event_category_add_del(c, EINA_FALSE); + eina_stringshare_del(t); + return; + } + l = eina_hash_find(category_hash, cat); + if (l) + { + if (!eina_list_data_find(l, t)) + eina_hash_set(category_hash, cat, eina_list_append(l, t)); + } + else + { + c = eina_stringshare_add(cat); + categories = eina_list_append(categories, c); + eina_hash_add(category_hash, cat, eina_list_append(NULL, t)); + _e_configure_option_event_category_add_del(c, EINA_FALSE); + } + eina_stringshare_del(t); +} + +EAPI void +e_configure_option_category_tag_del(const char *cat, const char *tag) +{ + Eina_List *l; + Eina_Stringshare *t, *c; + + if (!cat) return; + if (!tag) return; + if (!categories) return; + if (!tags_list) return; + + l = eina_hash_find(category_hash, cat); + if (!l) return; + t = eina_stringshare_add(tag); + l = eina_list_remove(l, t); + eina_hash_set(category_hash, cat, l); + if (!l) + { + c = eina_stringshare_add(cat); + categories = eina_list_remove(categories, c); + _e_configure_option_event_category_add_del(c, EINA_TRUE); + eina_stringshare_del(c); + } + eina_stringshare_del(t); +} + +EAPI Eina_Stringshare * +e_configure_option_category_icon_get(const char *cat) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(cat, NULL); + return eina_hash_find(category_icon_hash, cat); +} + +EAPI void +e_configure_option_category_icon_set(const char *cat, const char *icon) +{ + EINA_SAFETY_ON_NULL_RETURN(cat); + eina_stringshare_del(eina_hash_set(category_icon_hash, cat, eina_stringshare_add(icon))); +} + +EAPI E_Configure_Option_Ctx * +e_configure_option_ctx_new(void) +{ + return E_NEW(E_Configure_Option_Ctx, 1); +} + +EAPI Eina_Bool +e_configure_option_ctx_update(E_Configure_Option_Ctx *ctx, const char *str) +{ + Eina_List *l, *ll, *tlist, *clist = NULL; + Eina_Stringshare *tag; + char *s, *e; + + if ((!str) || (!str[0])) + { + if ((!ctx->tags) && (ctx->opts)) return EINA_FALSE; + ctx->tags = eina_list_free(ctx->tags); + ctx->opts = eina_list_free(ctx->opts); + return ctx->changed = EINA_TRUE; + } + tlist = eina_list_clone(tags_list); + for (s = e = strdupa(str); e[0]; e++) + { + if (isalnum(e[0])) continue; + e[0] = 0; + if (e - s > 1) + { + EINA_LIST_FOREACH_SAFE(tlist, l, ll, tag) + { + if ((!strcasestr(s, tag)) && (!strcasestr(tag, s))) continue; + if (eina_list_data_find(clist, tag)) continue; + clist = eina_list_append(clist, tag); + tlist = eina_list_remove(tlist, l); + } + } + s = e + 1; + } + if (e - s > 1) + { + EINA_LIST_FOREACH_SAFE(tlist, l, ll, tag) + { + if ((!strcasestr(s, tag)) && (!strcasestr(tag, s))) continue; + if (eina_list_data_find(clist, tag)) continue; + clist = eina_list_append(clist, tag); + tlist = eina_list_remove(tlist, l); + } + } + eina_list_free(tlist); + if (eina_list_count(clist) != eina_list_count(ctx->tags)) + goto update; + for (l = ctx->tags, ll = clist; l && ll; l = eina_list_next(l), ll = eina_list_next(ll)) + if (l->data != ll->data) goto update; + + eina_list_free(clist); + return EINA_FALSE; +update: + eina_list_free(ctx->tags); + ctx->tags = clist; + return ctx->changed = EINA_TRUE; +} + +EAPI Eina_Bool +e_configure_option_ctx_tag_add(E_Configure_Option_Ctx *ctx, Eina_Stringshare *tag) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(tag, EINA_FALSE); + + if (ctx->tags && eina_list_data_find(ctx->tags, tag)) return EINA_FALSE; + ctx->tags = eina_list_append(ctx->tags, tag); + return ctx->changed = EINA_TRUE; +} + +EAPI Eina_Bool +e_configure_option_ctx_tag_pop(E_Configure_Option_Ctx *ctx) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE); + if (!ctx->tags) return EINA_FALSE; + ctx->tags = eina_list_remove_list(ctx->tags, eina_list_last(ctx->tags)); + return ctx->changed = EINA_TRUE; +} + +EAPI const Eina_List * +e_configure_option_ctx_match_tag_list(E_Configure_Option_Ctx *ctx) +{ + const Eina_List *l; + E_Configure_Option *co; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + + ctx->match_tags = eina_list_free(ctx->match_tags); + e_configure_option_ctx_option_list(ctx); + if (eina_list_count(ctx->opts) < 2) return NULL; + EINA_LIST_FOREACH(e_configure_option_ctx_option_list(ctx), l, co) + { + Eina_List *ll; + Eina_Stringshare *tag; + + EINA_LIST_FOREACH(co->tags, ll, tag) + { + if ((!ctx->match_tags) || (!eina_list_data_find(ctx->match_tags, tag))) + ctx->match_tags = eina_list_append(ctx->match_tags, tag); + } + } + return ctx->match_tags; +} + +EAPI const Eina_List * +e_configure_option_ctx_option_list(E_Configure_Option_Ctx *ctx) +{ + Eina_List *l; + E_Configure_Option *co; + Eina_Stringshare *tag; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL); + + if ((!ctx->changed) && (ctx->opts)) return ctx->opts; + ctx->opts = eina_list_free(ctx->opts); + EINA_LIST_FOREACH(ctx->tags, l, tag) + { + Eina_List *ll, *lll, *opts = NULL; + + ll = eina_hash_find(tags_hash, tag); + if (!ll) continue; + opts = eina_list_clone(ll); + if (ctx->opts) + { + /* prune duplicates */ + EINA_LIST_FOREACH_SAFE(opts, ll, lll, co) + { + if (eina_list_data_find_list(ctx->opts, co)) + opts = eina_list_remove_list(opts, ll); + } + } + if (eina_list_count(ctx->tags) > 1) + /* reduce to matches */ + opts = _e_configure_option_ctx_list_prune(tag, opts, ctx->tags); + if (opts) + ctx->opts = eina_list_merge(ctx->opts, opts); + } + ctx->changed = EINA_FALSE; + return ctx->opts; +} + +EAPI void +e_configure_option_ctx_free(E_Configure_Option_Ctx *ctx) +{ + if (!ctx) return; + eina_list_free(ctx->tags); + eina_list_free(ctx->opts); + eina_list_free(ctx->match_tags); + free(ctx); +} diff --git a/src/bin/e_configure_option.h b/src/bin/e_configure_option.h new file mode 100644 index 000000000..8e43fadba --- /dev/null +++ b/src/bin/e_configure_option.h @@ -0,0 +1,172 @@ +#ifdef E_TYPEDEFS + +typedef struct E_Event_Configure_Option E_Event_Configure_Option_Changed; +typedef struct E_Event_Configure_Option E_Event_Configure_Option_Add; +typedef struct E_Event_Configure_Option E_Event_Configure_Option_Del; +typedef struct E_Event_Configure_Category E_Event_Configure_Option_Category_Add; +typedef struct E_Event_Configure_Category E_Event_Configure_Option_Category_Del; +typedef struct E_Event_Configure_Tag E_Event_Configure_Option_Tag_Add; +typedef struct E_Event_Configure_Tag E_Event_Configure_Option_Tag_Del; +typedef struct E_Configure_Option_Info E_Configure_Option_Info; +typedef struct E_Configure_Option E_Configure_Option; +typedef struct E_Configure_Option_Ctx E_Configure_Option_Ctx; +typedef void (*E_Configure_Option_Set_Cb)(); +typedef Eina_List *(*E_Configure_Option_Info_Cb)(E_Configure_Option *); +typedef Evas_Object *(*E_Configure_Option_Info_Thumb_Cb)(E_Configure_Option_Info *, Evas *); + +#else +# ifndef E_CONFIGURE_OPTION_H +# define E_CONFIGURE_OPTION_H + +#define E_CONFIGURE_OPTION_TAG_LENGTH 128 + +#define E_CONFIGURE_OPTION_ADD(OPT, TYPE, NAME, CFGPTR, DESC, ...) \ + OPT = e_configure_option_add(E_CONFIGURE_OPTION_TYPE_##TYPE, DESC, #NAME, EINA_TRUE, &CFGPTR->NAME, NULL);\ + e_configure_option_tags_set(OPT, (const char*[]){__VA_ARGS__, NULL}, 0) +#define E_CONFIGURE_OPTION_HELP(OPT, STR) \ + OPT->help = eina_stringshare_add(_(STR)) +#define E_CONFIGURE_OPTION_MINMAX_STEP_FMT(OPT, MIN, MAX, STEP, FMT) \ + OPT->minmax[0] = (MIN), OPT->minmax[1] = (MAX), OPT->step = (STEP),\ + OPT->info = eina_stringshare_add(_(FMT)) +#define E_CONFIGURE_OPTION_ICON(OPT, ICON) \ + e_configure_option_data_set(OPT, "icon", eina_stringshare_add(ICON)) +#define E_CONFIGURE_OPTION_LIST_CLEAR(LIST) do {\ + while (LIST) \ + { \ + E_Configure_Option *co; \ +\ + co = (E_Configure_Option*)LIST; \ + LIST = eina_inlist_remove(LIST, EINA_INLIST_GET(co)); \ + e_configure_option_del(co); \ + }\ +} while (0) + + +EAPI extern int E_EVENT_CONFIGURE_OPTION_CHANGED; +EAPI extern int E_EVENT_CONFIGURE_OPTION_ADD; +EAPI extern int E_EVENT_CONFIGURE_OPTION_DEL; +EAPI extern int E_EVENT_CONFIGURE_OPTION_CATEGORY_ADD; +EAPI extern int E_EVENT_CONFIGURE_OPTION_CATEGORY_DEL; +EAPI extern int E_EVENT_CONFIGURE_OPTION_TAG_ADD; +EAPI extern int E_EVENT_CONFIGURE_OPTION_TAG_DEL; + +typedef enum +{ + E_CONFIGURE_OPTION_TYPE_BOOL, + E_CONFIGURE_OPTION_TYPE_INT, + E_CONFIGURE_OPTION_TYPE_UINT, + E_CONFIGURE_OPTION_TYPE_ENUM, + E_CONFIGURE_OPTION_TYPE_DOUBLE, + E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR, //lround(double) + E_CONFIGURE_OPTION_TYPE_DOUBLE_INT, //lround(double) + E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT, //lround(double) + E_CONFIGURE_OPTION_TYPE_STR, + E_CONFIGURE_OPTION_TYPE_CUSTOM, +} E_Configure_Option_Type; + +struct E_Configure_Option +{ + EINA_INLIST; + Eina_Value val; + E_Configure_Option_Type type; + void *valptr; + Eina_Hash *data; + + double minmax[2]; //for sliders + double step; //for sliders + Eina_Stringshare *info; //for sliders, custom + E_Configure_Option_Info_Cb info_cb; //for enums + E_Configure_Option_Info_Thumb_Cb thumb_cb; //for custom thumbs + + Eina_Stringshare *name; + Eina_Stringshare *desc; + Eina_Stringshare *help; + Eina_List *tags; //Eina_Stringshare + + int event_type; //event to emit if changed + Eina_Stringshare *changed_action; //action to call if changed + struct + { + void (*none)(void); + void (*one)(); + void (*two)(); + } funcs[2]; //disable, enable + Eina_Bool private : 1; + Eina_Bool requires_restart : 1; + Eina_Bool changed : 1; +}; + +struct E_Configure_Option_Info +{ + E_Configure_Option *co; + Eina_Stringshare *name; + void *value; + Eina_Stringshare *thumb_file; + Eina_Stringshare *thumb_key; + Eina_Bool current : 1; +}; + +struct E_Event_Configure_Option +{ + E_Configure_Option *co; +}; + +struct E_Event_Configure_Category +{ + Eina_Stringshare *category; +}; + +struct E_Event_Configure_Tag +{ + Eina_Stringshare *tag; +}; + +struct E_Configure_Option_Ctx +{ + Eina_List *tags; // Eina_Stringshare + Eina_List *match_tags; // Eina_Stringshare + Eina_List *opts; // E_Configure_Option + Eina_Stringshare *category; + Eina_Bool changed : 1; +}; + +EAPI const Eina_List *e_configure_option_tags_list(void); +EAPI const Eina_List *e_configure_option_changed_list(void); +EAPI void e_configure_option_apply_all(void); +EAPI void e_configure_option_reset_all(void); + +EAPI E_Configure_Option *e_configure_option_add(E_Configure_Option_Type type, const char *desc, const char *name, Eina_Bool private_scope, void *valptr, const void *data); +EAPI void e_configure_option_tags_set(E_Configure_Option *co, const char const **tags, unsigned int num_tags); +EAPI void e_configure_option_del(E_Configure_Option *eci); +EAPI const Eina_List *e_configure_option_tag_list_options(const char *tag); +EAPI void e_configure_option_changed(E_Configure_Option *co); +EAPI void e_configure_option_apply(E_Configure_Option *co); +EAPI void e_configure_option_reset(E_Configure_Option *co); +EAPI void *e_configure_option_data_set(E_Configure_Option *co, const char *key, const void *data); +EAPI void *e_configure_option_data_get(E_Configure_Option *co, const char *key); +EAPI const void *e_configure_option_value_get(E_Configure_Option *co); + +EAPI E_Configure_Option_Info *e_configure_option_info_new(E_Configure_Option *co, const char *name, const void *value); +EAPI void e_configure_option_info_free(E_Configure_Option_Info *oi); +EAPI Eina_List *e_configure_option_info_get(E_Configure_Option *co); +EAPI Evas_Object *e_configure_option_info_thumb_get(E_Configure_Option_Info *oi, Evas *evas); + +EAPI const Eina_List *e_configure_option_category_list(void); +EAPI const Eina_List *e_configure_option_category_list_tags(const char *cat); +EAPI void e_configure_option_category_tag_add(const char *cat, const char *tag); +EAPI void e_configure_option_category_tag_del(const char *cat, const char *tag); +EAPI Eina_Stringshare *e_configure_option_category_icon_get(const char *cat); +EAPI void e_configure_option_category_icon_set(const char *cat, const char *icon); + +EAPI E_Configure_Option_Ctx *e_configure_option_ctx_new(void); +EAPI void e_configure_option_ctx_free(E_Configure_Option_Ctx *ctx); +EAPI Eina_Bool e_configure_option_ctx_update(E_Configure_Option_Ctx *ctx, const char *str); +EAPI const Eina_List *e_configure_option_ctx_option_list(E_Configure_Option_Ctx *ctx); +EAPI const Eina_List *e_configure_option_ctx_match_tag_list(E_Configure_Option_Ctx *ctx); +EAPI Eina_Bool e_configure_option_ctx_tag_add(E_Configure_Option_Ctx *ctx, Eina_Stringshare *tag); +EAPI Eina_Bool e_configure_option_ctx_tag_pop(E_Configure_Option_Ctx *ctx); + +EINTERN int e_configure_option_init(void); +EINTERN int e_configure_option_shutdown(void); +# endif +#endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 1faabbf96..40a48a66e 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -57,6 +57,7 @@ #include "e_pan.h" #include "e_dialog.h" #include "e_configure.h" +#include "e_configure_option.h" #include "e_about.h" #include "e_theme_about.h" #include "e_widget.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index ee8fd8ab0..0917e2d98 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -508,6 +508,11 @@ main(int argc, char **argv) TS("E_Config Init Done"); _e_main_shutdown_push(e_config_shutdown); + TS("E_Configure Option Init"); + e_configure_option_init(); + TS("E_Configure Option Init Done"); + _e_main_shutdown_push(e_configure_option_shutdown); + _xdg_data_dirs_augment(); _fix_user_default_edj(); diff --git a/src/bin/e_module.c b/src/bin/e_module.c index 936d12cce..e354bb43a 100644 --- a/src/bin/e_module.c +++ b/src/bin/e_module.c @@ -706,6 +706,8 @@ _e_module_whitelist_check(void) "xkbswitch", "echievements", "music-control", + "conf2", + NULL // end marker }; diff --git a/src/bin/e_remember.c b/src/bin/e_remember.c index 321a634a9..61f89dea0 100644 --- a/src/bin/e_remember.c +++ b/src/bin/e_remember.c @@ -602,7 +602,8 @@ _e_remember_cb_hook_eval_post_new_border(void *data __UNUSED__, void *border) if (!strncmp(bd->client.icccm.class, "e_fwin", 6)) { - if (!(e_config->remember_internal_windows & E_REMEMBER_INTERNAL_FM_WINS)) + if (!(e_config->remember_internal_windows & E_REMEMBER_INTERNAL_FM_WINS) && + (!e_config->remember_internal_fm_windows)) return; } else diff --git a/src/bin/e_win.c b/src/bin/e_win.c index 17982fe99..549e5f412 100644 --- a/src/bin/e_win.c +++ b/src/bin/e_win.c @@ -229,6 +229,16 @@ e_win_shutdown(void) return 1; } +EAPI Eina_Bool +e_win_elm_available(void) +{ +#ifdef HAVE_ELEMENTARY + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + EAPI E_Win * e_win_new(E_Container *con) { diff --git a/src/bin/e_win.h b/src/bin/e_win.h index e67fbba48..4845d5c1f 100644 --- a/src/bin/e_win.h +++ b/src/bin/e_win.h @@ -46,6 +46,7 @@ struct _E_Win EINTERN int e_win_init (void); EINTERN int e_win_shutdown (void); +EAPI Eina_Bool e_win_elm_available(void); EAPI E_Win *e_win_new (E_Container *con); EAPI void e_win_show (E_Win *win); EAPI void e_win_hide (E_Win *win); diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index 63d3ba1ca..3f7209d85 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -90,6 +90,10 @@ if USE_MODULE_CONF include Makefile_conf.am endif +if USE_MODULE_CONF2 +include Makefile_conf2.am +endif + if USE_MODULE_CONF_WALLPAPER2 include Makefile_conf_wallpaper2.am endif diff --git a/src/modules/Makefile_conf2.am b/src/modules/Makefile_conf2.am new file mode 100644 index 000000000..db6b684a2 --- /dev/null +++ b/src/modules/Makefile_conf2.am @@ -0,0 +1,74 @@ +conf2dir = $(MDIR)/conf2 +conf2_DATA = conf2/e-module-conf2.edj \ + conf2/module.desktop + +EXTRA_DIST += $(conf2_DATA) $(conf2dir)/e-module-conf2.edc +EXTRA_DIST += \ +images/volume_knob_ledsoff.png \ +images/volume_knob_move.png \ +images/volume_knob.png \ +images/volume_led_01.png \ +images/volume_led_02.png \ +images/volume_led_03.png \ +images/volume_led_04.png \ +images/volume_led_05.png \ +images/volume_led_06.png \ +images/volume_led_07.png \ +images/volume_led_08.png \ +images/volume_led_09.png \ +images/volume_led_10.png \ +images/volume_led_11.png \ +images/volume_led_12.png \ +images/volume_led_13.png \ +images/volume_led_14.png \ +images/volume_led_15.png \ +images/volume_led_16.png \ +images/volume_led_17.png \ +images/volume_led_18.png \ +images/volume_led_19.png \ +images/volume_led_20.png \ +images/volume_led_21.png \ +images/volume_led_22.png \ +images/volume_led_23.png \ +images/volume_led_24.png \ +images/volume_led_25.png \ +images/volume_led_26.png \ +images/volume_led_27.png \ +images/volume_led_28.png \ +images/volume_led_29.png \ +images/volume_led_30.png \ +images/volume_led_31.png \ +images/volume_led_32.png \ +images/volume_led_33.png \ +images/volume_led_34.png \ +images/volume_led_35.png \ +images/volume_led_36.png \ +images/volume_led_37.png \ +images/volume_led_38.png \ +images/volume_led_39.png \ +images/volume_led_40.png \ +images/volume_led_41.png \ +images/volume_led_42.png \ +images/volume_led_43.png \ +images/volume_led_44.png \ +images/volume_led_45.png + +conf2pkgdir = $(MDIR)/conf2/$(MODULE_ARCH) +conf2pkg_LTLIBRARIES = conf2/module.la + +conf2_module_la_SOURCES = conf2/e_mod_main.c \ + conf2/e_mod_main.h \ + conf2/e_conf2.c + +conf2_module_la_CFLAGS = $(AM_CFLAGS) @ELM_CFLAGS@ +conf2_module_la_LIBADD = @ELM_LIBS@ + +CONF2_EDJE_FLAGS = $(EDJE_FLAGS) -id $(srcdir)/conf2/images -id $(top_srcdir)/data/themes/img + +conf2/%.edj: conf2/%.edc Makefile + $(EDJE_CC) $(CONF2_EDJE_FLAGS) $< $@ + +.PHONY: conf2 install-conf2 +conf2: $(conf2pkg_LTLIBRARIES) $(conf2_DATA) +install-conf2: install-conf2DATA install-conf2pkgLTLIBRARIES + diff --git a/src/modules/conf2/e-module-conf2.edc b/src/modules/conf2/e-module-conf2.edc new file mode 100644 index 000000000..3c93fb746 --- /dev/null +++ b/src/modules/conf2/e-module-conf2.edc @@ -0,0 +1,2192 @@ +#define ASPECT_FILL(_ASPECT) \ + aspect: _ASPECT _ASPECT; aspect_preference: NONE; +#define TILED_PATTERN(_WIDTH, _HEIGHT) \ + fill { size { relative: 0.0 0.0; offset: _WIDTH _HEIGHT; } } +#define TILED_HORIZ(_WIDTH) \ + fill { size { relative: 0.0 1.0; offset: _WIDTH 0; } } +#define FIXED_SIZE(_WIDTH, _HEIGHT) \ + min: _WIDTH _HEIGHT; max: _WIDTH _HEIGHT; fixed: 1 1; + +collections { + group { + name: "elm/conf2/option/overlay"; + images.image: "vgrad_med_curved.png" COMP; + parts { + part { name: "base"; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "vgrad_med_curved.png"; + fill { + smooth: 0; + size { + relative: 0.0 1.0; + offset: 64 0; + } + } + } + description { state: "hide" 0.0; + inherit: "default"; + visible: 0; + } + } + part { + name: "e.text.label"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default"; + fixed: 0 1; + rel1.offset: 2 -30; + rel2.offset: -3 -15; + rel2.to_y: "e.swallow.content"; + rel2.relative: 1 0; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + text { font: "Sans"; size: 10; + min: 1 1; + ellipsis: 0.8; + align: 0.5 0.5; + text_class: "ilist_item"; + } + } + } + part { + name: "e.swallow.content"; + type: SWALLOW; + scale: 1; + description { + state: "default"; + min: 170 170; + rel1.offset: 2 3; + rel2.offset: -3 -3; + } + } + part { + name: "e.text.value"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default"; + fixed: 0 1; + rel1.relative: 0 1; + rel1.offset: 2 5; + rel2.offset: -3 25; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + text { font: "Sans"; size: 10; + min: 1 1; + ellipsis: 0.8; + align: 0.5 0.5; + text_class: "ilist_item"; + } + } + } + } + programs { + program { + signal: "e,state,bg_hide"; + source: "e"; + action: STATE_SET "hide" 0; + target: "base"; + } + } + } + + group { + name: "elm/conf2/tag/list"; + parts { + part { + name: "e.swallow.options"; + type: SWALLOW; + repeat_events: 1; + scale: 1; + clip_to: "clip"; + description { + state: "default"; + rel2.relative: 1 0; + minmul: 1 0; + } + description { + state: "show"; + rel2.relative: 1 0.5; + } + } + part { + name: "e.swallow.tags"; + type: SWALLOW; + repeat_events: 1; + scale: 1; + clip_to: "clip"; + description { + state: "default"; + rel1.to_y: "e.swallow.options"; + rel1.relative: 0 1; + } + } + part { + name: "clip"; + type: RECT; + scale: 1; + mouse_events: 0; + description { + state: "default"; + rel1.to: "e.swallow.options"; + rel2.to: "e.swallow.tags"; + color: 255 255 255 255; + } + description { + state: "show"; + color: 0 0 0 222; + } + } + part { + name: "clip_events"; + type: RECT; + scale: 1; + mouse_events: 1; + description { + state: "default"; + color: 0 0 0 0; + visible: 0; + } + description { + state: "show"; + color: 0 0 0 0; + visible: 1; + } + } + part { + name: "e.swallow.discard"; + type: SWALLOW; + scale: 1; + description { + state: "default"; + fixed: 1 1; + max: 60 30; + rel1.to_y: "e.swallow.tags"; + rel1.relative: 1 0; + rel1.offset: -180 30; + } + description { + state: "hidden"; + inherit: "default"; + rel1.to_x: "e.swallow.tags"; + rel1.offset: 150 30; + } + } + part { + name: "e.swallow.apply"; + type: SWALLOW; + scale: 1; + description { + state: "default"; + fixed: 1 1; + max: 60 30; + rel1.to_y: "e.swallow.discard"; + rel1.relative: 1 1; + rel1.offset: -180 20; + } + description { + state: "hidden"; + inherit: "default"; + rel1.to_x: "e.swallow.tags"; + rel1.offset: 150 20; + } + } + part { + name: "e.swallow.overlay"; + type: SWALLOW; + scale: 1; + description { + state: "default"; + rel1.relative: 0.25 0.25; + rel2.relative: 0.75 0.75; + visible: 0; + } + description { + state: "show"; + inherit: "default"; + visible: 1; + } + } + } + programs { + program { name: "collapse"; + signal: "e,action,collapse"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "e.swallow.options"; + transition: DECELERATE 0.3; + } + program { name: "expand"; + signal: "e,action,expand"; + source: "e"; + action: STATE_SET "show" 0.0; + target: "e.swallow.options"; + transition: DECELERATE 0.3; + } + program { name: "apply_show"; + signal: "e,action,apply_show"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "e.swallow.apply"; + transition: DECELERATE 0.3; + } + program { name: "apply_hide"; + signal: "e,action,apply_hide"; + source: "e"; + action: STATE_SET "hidden" 0.0; + target: "e.swallow.apply"; + transition: DECELERATE 0.3; + } + program { name: "discard_show"; + signal: "e,action,discard_show"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "e.swallow.discard"; + transition: DECELERATE 0.3; + } + program { name: "discard_hide"; + signal: "e,action,discard_hide"; + source: "e"; + action: STATE_SET "hidden" 0.0; + target: "e.swallow.discard"; + transition: DECELERATE 0.3; + } + program { name: "overlay_show"; + signal: "e,action,overlay_show"; + source: "e"; + action: STATE_SET "show" 0.0; + target: "e.swallow.overlay"; + target: "clip"; + target: "clip_events"; + transition: DECELERATE 0.3; + } + program { name: "overlay_hide"; + signal: "e,action,overlay_hide"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "e.swallow.overlay"; + target: "clip"; + target: "clip_events"; + transition: DECELERATE 0.3; + } + program { name: "overlay_dismiss"; + signal: "mouse,up,1"; + source: "clip_events"; + action: SIGNAL_EMIT "e,action,overlay_dismiss" "e"; + } + } + } + + group { name: "elm/label/base/conf2"; + parts { + part { name: "elm.text"; type: TEXT; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 2; + rel2.offset: -3 -3; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "label_text"; + text { font: "Sans"; size: 10; + min: 1 1; + align: 0.0 0.5; + text_class: "label"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 21 21 21 255; + color3: 255 255 255 25; + } + } + } + } + + group { name: "elm/entry/base-single/conf2"; + styles + { + style { name: "entry_textblock_style"; + base: "font=Sans font_size=10 color=#ffffff wrap=none style=shadow,bottom shadow_color=#00000080 text_class=entry color_class=entry_text"; + } + style { name: "entry_textblock_disabled_style"; + base: "font=Sans font_size=10 color=#151515 wrap=none style=shadow,bottom shadow_color=#ffffff19 text_class=entry color_class=entry_text_disabled"; + } + /* FIXME */ + style { name: "entry_textblock_guide_style"; + base: "font=Sans font_size=10 color=#00000080 wrap=none text_class=entry left_margin=2 right_margin=2 ellipsis=0.0"; + tag: "em" "+ font_style=Oblique"; + tag: "hilight" "+ font_weight=Bold"; + } + } + parts { + part { name: "elm.guide"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + text { + style: "entry_textblock_guide_style"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; + type: TEXTBLOCK; + mouse_events: 1; + scale: 1; + entry_mode: EDITABLE; + select_mode: DEFAULT; + cursor_mode: BEFORE; + multiline: 0; + source: "elm/entry/selection/conf2"; // selection under + // source2: "X"; // selection over + // source3: "X"; // cursor under + source4: "elm/entry/cursor/conf2"; // cursorover + //source5: "elm/entry/anchor/conf2"; // anchor under + // source6: "X"; // anchor over + description { state: "default" 0.0; + /* we gotta use 0 0 here, because of scrolled entries */ + fixed: 0 0; + text { + style: "entry_textblock_style"; + min: 1 1; + max: 0 0; + align: 0.0 0.5; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style"; + min: 0 1; + } + } + } + } + programs { + program { name: "focus"; + signal: "load"; + source: ""; + action: FOCUS_SET; + target: "elm.text"; + } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "elm.text"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.text"; + } + program { name: "gdisable"; + signal: "elm,guide,disabled"; + source: "elm"; + action: STATE_SET "hidden" 0.0; + target: "elm.guide"; + } + program { name: "genable"; + signal: "elm,guide,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.guide"; + } + } + } + + + group { name: "elm/entry/cursor/conf2"; + min: 1 0; + images.image: "white_bar_vert_glow.png" COMP; + parts { + part { name: "cursor"; mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: -4 -4; + rel2.offset: 3 3; + image.normal: "white_bar_vert_glow.png"; + image.border: 4 4 4 4; + fill.smooth: 0; + color: 255 255 255 0; + min: 9 10; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 255; + } + } + } + programs { + program { + signal: "elm,action,focus"; source: "elm"; + action: ACTION_STOP; + target: "cursor_show"; + target: "cursor_hide"; + target: "cursor_show_timer"; + target: "cursor_hide_timer"; + after: "cursor_show"; + } + program { + name: "on_cursor_hide"; + signal: "elm,action,unfocus"; source: "elm"; + action: ACTION_STOP; + target: "cursor_show"; + target: "cursor_hide"; + target: "cursor_show_timer"; + target: "cursor_hide_timer"; + after: "cursor_hide_stop"; + } + program { + name: "cursor_hide_stop"; + action: STATE_SET "default" 0.0; + target: "cursor"; + } + program { name: "cursor_show"; + action: STATE_SET "visible" 0.0; + target: "cursor"; + after: "cursor_show_timer"; + } + program { name: "cursor_hide"; + action: STATE_SET "default" 0.0; + target: "cursor"; + transition: SINUSOIDAL 0.2; + after: "cursor_hide_timer"; + } + program { name: "cursor_show_timer"; + in: 0.5 0.0; + after: "cursor_hide"; + } + program { name: "cursor_hide_timer"; + in: 0.2 0.0; + after: "cursor_show"; + } + } + } + + + + group { name: "elm/entry/selection/conf2"; + parts { + part { name: "selection"; type: RECT; mouse_events: 0; + description { state: "default" 0.0; + color: 51 153 255 255; + } + } + } + } + + group { name: "elm/button/base/conf2"; + images.image: "button_normal.png" COMP; + images.image: "button_clicked.png" COMP; + parts { + part { name: "base"; + description { state: "default" 0.0; + image.normal: "button_normal.png"; + image.border: 4 4 3 5; + image.middle: SOLID; + rel1.offset: -1 0; + rel2.offset: 0 1; + fill.smooth: 0; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + image.normal: "button_clicked.png"; + image.border: 5 5 4 6; + } + } + part { name: "icon_clip"; type: RECT; + description { state: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 64; + } + } + part { name: "elm.swallow.content"; type: SWALLOW; mouse_events: 0; + clip_to: "icon_clip"; + description { state: "default" 0.0; + min: 17 17; + align: 0.0 0.5; + fixed: 1 0; + rel1.offset: 6 5; + rel1.to: "base"; + rel2.offset: 6 -8; + rel2.relative: 0 1; + rel2.to: "base"; + } + description { state: "icon" 0.0; + inherit: "default" 0.0; + fixed: 0 0; + align: 0.5 0.5; + rel2.relative: 1.0 1.0; + rel2.offset: -7 -8; + } + } + part { name: "label_clip"; type: RECT; + description { state: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + clip_to: "label_clip"; + description { state: "default" 0.0; + rel1.offset: 2 5; + rel1.to_x: "elm.swallow.content"; + rel1.relative: 1 0; + rel1.to_y: "base"; + rel2.offset: -7 -9; + rel2.to: "base"; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "button_text"; + text { font: "Sans"; size: 10; + min: 1 1; + align: 0.5 0.5; + text_class: "button"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 21 21 21 255; + color3: 255 255 255 25; + color_class: "button_text_disabled"; + } + description { state: "icon" 0.0; + inherit: "default" 0.0; + visible: 0; + minmul: 0 1; + } + } + part { name: "label2"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + color: 21 21 21 255; + color3: 255 255 255 25; + color_class: "button_text_disabled"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.5 0.5; + min: 1 1; + text_class: "button"; + } + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event"; type: RECT; + ignore_flags: ON_HOLD; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { + signal: "mouse,down,1"; source: "event"; + action: SIGNAL_EMIT "elm,action,press" ""; + after: "down_anim"; + } + program { + name: "down_anim"; + action: STATE_SET "clicked" 0.0; + target: "base"; + } + program { + signal: "mouse,up,1"; source: "event"; + action: SIGNAL_EMIT "elm,action,unpress" ""; + after: "up_anim"; + } + program { + name: "up_anim"; + action: STATE_SET "default" 0.0; + target: "base"; + } + program { + name: "button_pressed_anim"; + signal: "elm,anim,activate"; + source: "elm"; + action: STATE_SET "clicked" 0.0; + target: "base"; + } + program { + signal: "mouse,clicked,1*"; source: "event"; + action: SIGNAL_EMIT "elm,action,click" ""; + } + program { + signal: "elm,state,text,hidden"; source: "elm"; + action: STATE_SET "icon" 0.0; + target: "elm.swallow.content"; + target: "elm.text"; + + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event"; + target: "icon_clip"; + target: "label_clip"; + target: "label2"; + transition: DECELERATE 0.3; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event"; + target: "icon_clip"; + target: "label_clip"; + target: "label2"; + transition: DECELERATE 0.3; + } + } + } + + group { name: "elm/radio/base/conf2"; + images.image: "inset_shadow_circle_tiny.png" COMP; + images.image: "inset_circle_tiny.png" COMP; + images.image: "sym_radio_alum.png" COMP; + parts { + part { name: "inset"; mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: 2 2; + rel2.relative: 0.0 1.0; + rel2.offset: 2 -3; + image.normal: "inset_shadow_circle_tiny.png"; + align: 0.0 0.5; + min: 13 13; + max: 13 13; + fixed: 1 1; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + image.normal: "inset_circle_tiny.png"; + } + } + part { name: "clip"; type: RECT; + description { state: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 64; + } + } + part { name: "indicator"; mouse_events: 0; + clip_to: "clip"; + description { state: "default" 0.0; + rel1.to: "inset"; + rel2.to: "inset"; + image.normal: "sym_radio_alum.png"; + min: 11 11; + max: 11 11; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "elm.text"; type: TEXT; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 2; + rel1.to_x: "inset"; + rel1.relative: 1.0 0.0; + rel2.offset: -3 -3; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "radio_text"; + text { font: "Sans"; size: 10; + min: 1 1; + align: 0.0 0.5; + text_class: "radio_button"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 21 21 21 255; + color3: 255 255 255 25; + } + } + part { name: "event"; type: RECT; + ignore_flags: ON_HOLD; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { name: "click"; + signal: "mouse,up,1"; + source: "event"; + action: SIGNAL_EMIT "elm,action,radio,toggle" ""; + } + program { name: "radio_on"; + signal: "elm,state,radio,on"; + source: "elm"; + action: STATE_SET "selected" 0.0; + target: "indicator"; + } + program { name: "radio_off"; + signal: "elm,state,radio,off"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "indicator"; + } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "inset"; + target: "clip"; + target: "elm.text"; + target: "event"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "inset"; + target: "clip"; + target: "elm.text"; + target: "event"; + } + } + } + + group { name: "elm/bg/base/conf2"; + images.image: "vgrad_med_curved.png" COMP; + parts { + part { name: "base"; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "vgrad_med_curved.png"; + fill { + smooth: 0; + size { + relative: 0.0 1.0; + offset: 64 0; + } + } + } + } + part { name: "elm.swallow.rectangle"; + type: SWALLOW; + description { state: "default" 0.0; + } + } + part { name: "elm.swallow.background"; + type: SWALLOW; + description { state: "default" 0.0; + } + } + part { name: "elm.swallow.content"; + type: SWALLOW; + description { state: "default" 0.0; + } + } + } + } + + group { name: "elm/genlist/item/conf2_tag/default"; + alias: "elm/genlist/item_compress/conf2_tag/default"; + data.item: "stacking" "above"; + data.item: "selectraise" "on"; + data.item: "texts" "elm.text"; + data.item: "contents" "elm.swallow.icon elm.swallow.end"; + data.item: "treesize" "20"; + images.image: "bevel_curved_horiz_out.png" COMP; + images.image: "shadow_rounded_horiz.png" COMP; + images.image: "vgrad_med_dark.png" COMP; + images.image: "bevel_horiz_out.png" COMP; + images.image: "shine.png" COMP; + parts { + part { name: "base"; type: RECT; mouse_events: 0; + description { state: "default" 0.0; + color: 64 64 64 255; + color_class: "ilist_item_base"; + } + } + part { name: "bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_curved_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + } + } + part { name: "sel_shadow"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shadow_rounded_horiz.png"; + image.border: 0 0 9 9; + rel1.offset: 0 -4; + rel2.offset: -1 5; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_base"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "vgrad_med_dark.png"; + fill.smooth: 0; + TILED_HORIZ(120) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "elm.swallow.pad"; + type: SWALLOW; + description { state: "default" 0.0; + fixed: 1 0; + align: 0.0 0.5; + rel1 { + relative: 0.0 0.0; + offset: 4 4; + } + rel2 { + relative: 0.0 1.0; + offset: 4 -5; + } + } + } + part { name: "elm.swallow.icon"; type: SWALLOW; + description { state: "default" 0.0; + align: 0.0 0.5; + aspect: 1.0 1.0; aspect_preference: VERTICAL; + rel1.offset: 2 2; + rel2.relative: 0.0 1.0; + rel2.offset: 2 -3; + } + } + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 3; + rel1.relative: 1.0 0.0; + rel1.to_x: "elm.swallow.icon"; + rel2.offset: -3 -3; + rel2.relative: 0.0 1.0; + rel2.to_x: "elm.swallow.end"; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "ilist_item"; + text { font: "Sans"; size: 10; + min: 1 1; + ellipsis: 0.8; + align: 0.0 0.5; + text_class: "ilist_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "label2"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + color: 21 21 21 255; + color3: 255 255 255 25; + color_class: "ilist_item_disabled"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "label3"; type: TEXT; mouse_events: 0; + effect: GLOW; + scale: 1; + description { state: "default" 0.0; + rel1.offset: -2 -3; + rel1.to: "elm.text"; + rel2.offset: 2 1; + rel2.to: "elm.text"; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + color_class: "ilist_item_selected"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.swallow.end"; type: SWALLOW; + description { state: "default" 0.0; + align: 1.0 0.5; + aspect: 1.0 1.0; aspect_preference: VERTICAL; + rel1.offset: -3 2; + rel1.relative: 1.0 0.0; + rel2.offset: -3 -3; + } + } + part { name: "sel_shine"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shine.png"; + rel1.offset: 0 -2; + rel1.to: "sel_base"; + rel2.relative: 1.0 0.0; + rel2.offset: -1 2; + rel2.to: "sel_base"; + FIXED_SIZE(69, 5) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event"; type: RECT; + repeat_events: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + } + } + + group { name: "elm/genlist/item/conf2_double_label/default"; + alias: "elm/genlist/item_compress/conf2_double_label/default"; + data.item: "stacking" "above"; + data.item: "selectraise" "on"; + data.item: "texts" "elm.text elm.text.sub"; + data.item: "contents" "elm.swallow.icon elm.swallow.end"; + data.item: "treesize" "20"; + images.image: "bevel_curved_horiz_out.png" COMP; + images.image: "shadow_rounded_horiz.png" COMP; + images.image: "vgrad_med_dark.png" COMP; + images.image: "bevel_horiz_out.png" COMP; + images.image: "shine.png" COMP; + parts { + part { name: "base"; type: RECT; mouse_events: 0; + description { state: "default" 0.0; + color: 64 64 64 255; + color_class: "ilist_item_base"; + } + } + part { name: "bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_curved_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + } + } + part { name: "sel_shadow"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shadow_rounded_horiz.png"; + image.border: 0 0 9 9; + rel1.offset: 0 -4; + rel2.offset: -1 5; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_base"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "vgrad_med_dark.png"; + fill.smooth: 0; + TILED_HORIZ(120) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "elm.swallow.pad"; + type: SWALLOW; + description { state: "default" 0.0; + fixed: 1 0; + align: 0.0 0.5; + rel1 { + relative: 0.0 0.0; + offset: 4 4; + } + rel2 { + relative: 0.0 1.0; + offset: 4 -5; + } + } + } + part { name: "elm.swallow.icon"; type: SWALLOW; + description { state: "default" 0.0; + align: 0.0 0.5; + aspect: 1.0 1.0; aspect_preference: VERTICAL; + rel1.offset: 2 2; + rel2.relative: 0.0 1.0; + rel2.offset: 2 -3; + } + } + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 3; + rel1.relative: 1.0 0.0; + rel1.to_x: "elm.swallow.icon"; + rel2.offset: -3 -3; + rel2.relative: 0.0 1.0; + rel2.to_x: "elm.swallow.end"; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "ilist_item"; + text { font: "Sans"; size: 10; + min: 1 1; + ellipsis: 0.8; + align: 0.0 0.5; + text_class: "ilist_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "label2"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + color: 21 21 21 255; + color3: 255 255 255 25; + color_class: "ilist_item_disabled"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "label3"; type: TEXT; mouse_events: 0; + effect: GLOW; + scale: 1; + description { state: "default" 0.0; + rel1.offset: -2 -3; + rel1.to: "elm.text"; + rel2.offset: 2 1; + rel2.to: "elm.text"; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + color_class: "ilist_item_selected"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.0 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text.sub"; type: TEXT; mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; + rel1.offset: 2 3; + rel1.relative: 1.0 0.5; + rel1.to_x: "elm.swallow.icon"; + rel2.offset: -3 -3; + rel2.relative: 0.0 1.0; + rel2.to_x: "elm.swallow.end"; + color: 255 255 255 255; + color3: 0 0 0 128; + text { + font: "Sans"; + size: 8; + min: 1 1; + align: 0.0 0.5; + text_class: "list_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + } + } + part { name: "elm.swallow.end"; type: SWALLOW; + description { state: "default" 0.0; + align: 1.0 0.5; + aspect: 1.0 1.0; aspect_preference: VERTICAL; + rel1.offset: -3 2; + rel1.relative: 1.0 0.0; + rel2.offset: -3 -3; + } + } + part { name: "sel_shine"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shine.png"; + rel1.offset: 0 -2; + rel1.to: "sel_base"; + rel2.relative: 1.0 0.0; + rel2.offset: -1 2; + rel2.to: "sel_base"; + FIXED_SIZE(69, 5) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event"; type: RECT; + repeat_events: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "elm.text.sub"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "elm.text.sub"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + } + } + + group { name: "elm/genlist/item/conf2_thumb/default"; + data.item: "stacking" "above"; + data.item: "selectraise" "on"; + data.item: "texts" "elm.text"; + data.item: "contents" "elm.swallow.icon"; + data.item: "treesize" "20"; + images.image: "bevel_curved_horiz_out.png" COMP; + images.image: "shadow_rounded_horiz.png" COMP; + images.image: "vgrad_med_dark.png" COMP; + images.image: "bevel_horiz_out.png" COMP; + images.image: "shine.png" COMP; + parts { + part { name: "base"; type: RECT; mouse_events: 0; + description { state: "default" 0.0; + color: 64 64 64 255; + color_class: "ilist_item_base"; + } + } + part { name: "bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_curved_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + } + } + part { name: "sel_shadow"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shadow_rounded_horiz.png"; + image.border: 0 0 9 9; + rel1.offset: 0 -4; + rel2.offset: -1 5; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_base"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "vgrad_med_dark.png"; + fill.smooth: 0; + TILED_HORIZ(120) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "sel_bevel"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "bevel_horiz_out.png"; + image.border: 0 0 2 2; + image.middle: 0; + fill.smooth: 0; + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "elm.swallow.icon"; type: SWALLOW; mouse_events: 0; + description { state: "default" 0.0; + min: 150 150; + max: 170 150; + align: 0.5 0.0; + aspect: 1.0 1.0; aspect_preference: VERTICAL; + rel1.offset: 2 2; + rel2.offset: 2 -3; + } + } + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 3; + rel1.relative: 0.0 1.0; + rel1.to_y: "elm.swallow.icon"; + rel2.offset: -3 -3; + color: 255 255 255 255; + color3: 0 0 0 128; + color_class: "ilist_item"; + text { font: "Sans"; size: 10; + min: 1 1; + ellipsis: 0.8; + align: 0.5 0.5; + text_class: "ilist_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "label2"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + color: 21 21 21 255; + color3: 255 255 255 25; + color_class: "ilist_item_disabled"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.5 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "label3"; type: TEXT; mouse_events: 0; + effect: GLOW; + scale: 1; + description { state: "default" 0.0; + rel1.offset: -2 -3; + rel1.to: "elm.text"; + rel2.offset: 2 1; + rel2.to: "elm.text"; + color: 51 153 255 255; + color2: 51 153 255 24; + color3: 51 153 255 18; + color_class: "ilist_item_selected"; + text { font: "Sans"; size: 10; + text_source: "elm.text"; + align: 0.5 0.5; + text_class: "ilist_item"; + } + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "sel_shine"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "shine.png"; + rel1.offset: 0 -2; + rel1.to: "sel_base"; + rel2.relative: 1.0 0.0; + rel2.offset: -1 2; + rel2.to: "sel_base"; + FIXED_SIZE(69, 5) + visible: 0; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event"; type: RECT; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { + signal: "elm,state,selected"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,unselected"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "sel_shadow"; + target: "sel_base"; + target: "sel_bevel"; + target: "sel_shine"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,disabled"; source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + program { + signal: "elm,state,enabled"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "event"; + target: "elm.text"; + target: "label2"; + target: "label3"; + } + } + } + + group { name: "elm/check/base/conf2"; + images.image: "inset_shadow_tiny.png" COMP; + images.image: "bevel_in.png" COMP; + images.image: "sym_check_alum.png" COMP; + parts { + part { name: "base"; type: RECT; + description { state: "default" 0.0; + rel1.offset: 1 1; + rel1.to: "inset"; + rel2.offset: -2 -2; + rel2.to: "inset"; + color: 24 24 24 255; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 64 64 64 255; + } + } + part { name: "shadow"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "inset_shadow_tiny.png"; + rel1.to: "base"; + rel2.to: "base"; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "inset"; mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: 1 2; + rel2.offset: 1 -3; + image.normal: "bevel_in.png"; + image.border: 1 1 1 1; + image.middle: 0; + fill.smooth: 0; + min: 18 18; + max: 18 18; + fixed: 1 1; + } + } + part { name: "clip"; type: RECT; + description { state: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 64; + } + } + part { name: "check"; mouse_events: 0; + clip_to: "clip"; + description { state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "sym_check_alum.png"; + min: 16 16; + max: 16 16; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "event"; type: RECT; + ignore_flags: ON_HOLD; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { name: "click"; + signal: "mouse,clicked,1"; + source: "event"; + action: SIGNAL_EMIT "elm,action,check,toggle" ""; + } + program { name: "check_on"; + signal: "elm,state,check,on"; + source: "elm"; + action: STATE_SET "visible" 0.0; + target: "check"; + } + program { name: "check_off"; + signal: "elm,state,check,off"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "check"; + } + program { + signal: "elm,state,disabled"; source: "e"; + action: STATE_SET "disabled" 0.0; + target: "base"; + target: "shadow"; + target: "clip"; + target: "event"; + } + program { + signal: "e,state,enabled"; source: "e"; + action: STATE_SET "default" 0.0; + target: "base"; + target: "shadow"; + target: "clip"; + target: "event"; + } + } + } + + group { name: "elm/tooltip/base/conf2"; + min: 30 30; + data { + item: "pad_x" "20"; + item: "pad_y" "20"; + item: "pad_border_x" "10"; + item: "pad_border_y" "10"; + item: "hide_timeout" "0.3"; + } + images.image: "vgrad_med_curved.png" COMP; + + parts { + part { name: "pop"; + mouse_events: 0; + description { state: "default" 0.0; + min: 30 30; + rel1 { + to: "elm.swallow.content"; + offset: -15 -15; + } + rel2 { + to: "elm.swallow.content"; + offset: 14 14; + } + image { + normal: "vgrad_med_curved.png"; + border: 14 14 14 14; + } + image.middle: SOLID; + } + } + + part { name: "elm.swallow.content"; + type: SWALLOW; + description { state: "default" 0.0; } + } + } + } + +/////////////////////////////////////////////////////////////////////////////// + + + /* + Round volume knob. + 2012 - Raoul Hecky + + It's a new custom style for an elm_slider. + It uses embryo and hidden dragable part to set/get the position + of the volume knob. Another hidden dragable is used to move the + knob using the mouse/finger. All math are done using embryo. + */ + + group + { + name: "base/knob_volume"; + + images + { + image: "volume_knob.png" COMP; + image: "volume_knob_move.png" COMP; + image: "volume_knob_ledsoff.png" COMP; + + image: "volume_led_01.png" COMP; + } + + script + { + #define VOLUME_MIN_ANGLE 0.0 + #define VOLUME_MAX_ANGLE 264.0 + #define VOLUME_MAX_LEDS 45 + + public knob_angle; + public knob_offset; + public leds_on; + + public led_status; //edje list to keep track of each led status + + public Float:calc_angle(mx, my) + { + new px, py, pw, ph; + get_geometry(PART:"bg", px, py, pw, ph); + + new center_x, center_y; + center_x = px + pw / 2; + center_y = py + ph / 2; + + new dx, dy; + dx = center_x - mx; + dy = center_y - my; + + new Float:angle; + angle = atan2(-dx, dy) * 180.0 / PI + 180.0; + + return angle; + } + + public rotate_knob(Float:val) + { + custom_state(PART:"knob", "default", 0.0); + set_state_val(PART:"knob", STATE_MAP_ROT_Z, val); + set_state(PART:"knob", "custom", 0.0); + + //set needed leds on or off from current value + set_int(leds_on, round(val * VOLUME_MAX_LEDS / VOLUME_MAX_ANGLE)); + emit("leds,changed", "volume"); + } + } + + parts + { + part + { + name: "bg"; + type: RECT; + scale: 1; + description + { + state: "default" 0.0; + visible: 0; + rel1.to: "leds_off"; + rel2.to: "leds_off"; + } + } + + part + { + name: "knob_back"; + mouse_events: 0; + scale: 1; + description + { + state: "default" 0.0; + image.normal: "volume_knob.png"; + } + } + + part + { + name: "knob"; + mouse_events: 0; + scale: 1; + description + { + state: "default" 0.0; + image.normal: "volume_knob_move.png"; + map.on: 1; + } + } + + part + { + name: "leds_off"; + mouse_events: 0; + scale: 1; + description + { + state: "default" 0.0; + image.normal: "volume_knob_ledsoff.png"; + color: 255 255 255 50; + } + } + + #define VOLUME_LED_ON(num, inum) \ + part \ + { \ + name: "led_"num; \ + mouse_events: 0; \ + scale: 1; \ + description \ + { \ + state: "default" 0.0; \ + rel1.to: "leds_off"; \ + rel2.to: "leds_off"; \ + image.normal: "volume_led_01.png"; \ + map { \ + on: 1; \ + rotation { \ + center: "bg"; \ + z: (((inum-1)*VOLUME_MAX_ANGLE)/45); \ + } \ + } \ + visible: 0; \ + color: 255 255 255 0; \ + } \ + description \ + { \ + state: "visible" 0.0; \ + inherit: "default" 0.0; \ + visible: 1; \ + color: 255 255 255 255; \ + } \ + } \ + program \ + { \ + name: "show_led_"num; \ + action: STATE_SET "visible" 0.0; \ + transition: DECELERATE 0.6 CURRENT; \ + target: "led_"num; \ + } \ + program \ + { \ + name: "hide_led_"num; \ + action: STATE_SET "default" 0.0; \ + transition: DECELERATE 0.6 CURRENT; \ + target: "led_"num; \ + } \ + program \ + { \ + name: "sig_led_changed_"num; \ + signal: "leds,changed"; \ + source: "volume"; \ + script \ + { \ + new current_status = fetch_int(led_status, inum - 1); \ + new new_status; \ + if (get_int(leds_on) >= inum) \ + new_status = 1; \ + else \ + new_status = 0; \ + \ + if (current_status != new_status) \ + { \ + if (new_status == 1) \ + run_program(PROGRAM:"show_led_"num); \ + else if (new_status == 0) \ + run_program(PROGRAM:"hide_led_"num); \ + \ + replace_int(led_status, inum - 1, new_status); \ + } \ + } \ + } + + VOLUME_LED_ON("01", 1) + VOLUME_LED_ON("02", 2) + VOLUME_LED_ON("03", 3) + VOLUME_LED_ON("04", 4) + VOLUME_LED_ON("05", 5) + VOLUME_LED_ON("06", 6) + VOLUME_LED_ON("07", 7) + VOLUME_LED_ON("08", 8) + VOLUME_LED_ON("09", 9) + VOLUME_LED_ON("10", 10) + + VOLUME_LED_ON("11", 11) + VOLUME_LED_ON("12", 12) + VOLUME_LED_ON("13", 13) + VOLUME_LED_ON("14", 14) + VOLUME_LED_ON("15", 15) + VOLUME_LED_ON("16", 16) + VOLUME_LED_ON("17", 17) + VOLUME_LED_ON("18", 18) + VOLUME_LED_ON("19", 19) + VOLUME_LED_ON("20", 20) + + VOLUME_LED_ON("21", 21) + VOLUME_LED_ON("22", 22) + VOLUME_LED_ON("23", 23) + VOLUME_LED_ON("24", 24) + VOLUME_LED_ON("25", 25) + VOLUME_LED_ON("26", 26) + VOLUME_LED_ON("27", 27) + VOLUME_LED_ON("28", 28) + VOLUME_LED_ON("29", 29) + VOLUME_LED_ON("30", 30) + + VOLUME_LED_ON("31", 31) + VOLUME_LED_ON("32", 32) + VOLUME_LED_ON("33", 33) + VOLUME_LED_ON("34", 34) + VOLUME_LED_ON("35", 35) + VOLUME_LED_ON("36", 36) + VOLUME_LED_ON("37", 37) + VOLUME_LED_ON("38", 38) + VOLUME_LED_ON("39", 39) + VOLUME_LED_ON("40", 40) + + VOLUME_LED_ON("41", 41) + VOLUME_LED_ON("42", 42) + VOLUME_LED_ON("43", 43) + VOLUME_LED_ON("44", 44) + VOLUME_LED_ON("45", 45) + + part + { + name: "event"; + type: RECT; + description + { + state: "default" 0.0; + rel1.to: "knob"; + rel2.to: "knob"; + color: 0 0 0 0; + + } + dragable + { + x: 1 1 0; + y: 1 1 0; + } + } + + part + { + //The real slider for elm_slider + name: "elm.dragable.slider"; + type: RECT; + description + { + state: "default" 0.0; + visible: 0; + + } + dragable + { + x: 1 1 0; + y: 0 0 0; + } + } + + } + + programs + { + program + { + name: "on_drag_start"; + signal: "drag,start"; + source: "event"; + script + { + new mx, my; + get_mouse(mx, my); + + set_float(knob_offset, calc_angle(mx, my) - get_float(knob_angle)); + } + } + + program + { + name: "on_drag_move"; + signal: "drag"; + source: "event"; + script + { + new mx, my; + get_mouse(mx, my); + + new Float:angle = calc_angle(mx, my) - get_float(knob_offset); + + //Limits the button range + if (angle < VOLUME_MIN_ANGLE) angle = VOLUME_MIN_ANGLE; + if (angle > VOLUME_MAX_ANGLE) angle = VOLUME_MAX_ANGLE; + + set_float(knob_angle, angle); + + rotate_knob(angle); + set_drag(PART:"elm.dragable.slider", + get_float(knob_angle) / VOLUME_MAX_ANGLE, 0.0); + } + } + + + program + { + name: "on_drag_stop"; + signal: "drag,stop"; + source: "event"; + script + { + set_drag(PART:"event", 0.0, 0.0); + } + } + + program + { + name: "on_slider_set"; + signal: "drag,set"; + source: "elm.dragable.slider"; + script + { + new Float:dx, Float:dy; + get_drag(PART:"elm.dragable.slider", dx, dy); + + new Float:angle = dx * VOLUME_MAX_ANGLE; + set_float(knob_angle, angle); + + rotate_knob(angle); + } + } + + program + { + name: "on_init"; + signal: "show"; + script + { + while (count(led_status) < VOLUME_MAX_LEDS) + append_int(led_status, 0); + } + } + program + { + name: "on_wheel"; + signal: "mouse,wheel*"; + source: "event"; + after: "on_slider_set"; + } + } + } + + group + { + name: "elm/slider/horizontal/knob_volume"; + inherit: "base/knob_volume"; + parts + { + part + { + name: "knob_back"; + description + { + state: "default" 0.0; + rel1.to: "knob"; + rel2.to: "knob"; + aspect: 1.0 1.0; + aspect_preference: VERTICAL; + } + } + + part + { + name: "knob"; + description + { + state: "default" 0.0; + min: 24 24; + aspect: 1.0 1.0; + aspect_preference: VERTICAL; + rel1.offset: 1 1; + rel2.relative: 0.0 1.0; + rel2.offset: 1 -2; + align: 0.0 0.5; + } + } + + part + { + name: "leds_off"; + description + { + state: "default" 0.0; + rel1.to: "knob"; + rel2.to: "knob"; + aspect: 1.0 1.0; + aspect_preference: VERTICAL; + } + } + } + } + + +/* aaaaaaaaaand because the volume knob doesn't resize we need another group here */ + group + { + name: "elm/slider/horizontal/knob_volume_big"; + inherit: "base/knob_volume"; + min: 200 200; + + parts + { + part + { + name: "knob_back"; + description + { + state: "default" 0.0; + rel1 { relative: 0.5 0.5; offset: -100 -100; } + rel2 { relative: 0.5 0.5; offset: 99 99; } + } + } + + part + { + name: "knob"; + description + { + state: "default" 0.0; + rel1 { relative: 0.5 0.5; offset: -100 -100; } + rel2 { relative: 0.5 0.5; offset: 99 99; } + } + } + + part + { + name: "leds_off"; + description + { + state: "default" 0.0; + rel1 { relative: 0.5 0.5; offset: -100 -100; } + rel2 { relative: 0.5 0.5; offset: 99 99; } + } + } + } + } +} diff --git a/src/modules/conf2/e_conf2.c b/src/modules/conf2/e_conf2.c new file mode 100644 index 000000000..2c6daa70a --- /dev/null +++ b/src/modules/conf2/e_conf2.c @@ -0,0 +1,1326 @@ +#include "e.h" + +#include "e_mod_main.h" + +static Elm_Genlist_Item_Class *itc_cats = NULL; +static Elm_Genlist_Item_Class *itc_tags = NULL; +static Elm_Genlist_Item_Class *itc_opts = NULL; +static Elm_Genlist_Item_Class *itc_thumb = NULL; +static E_Configure_Option_Ctx *ctx_entry = NULL; +static E_Configure_Option_Ctx *ctx_click = NULL; +static E_Configure_Option_Ctx *ctx_active = NULL; +static Evas_Object *list[2] = {NULL, NULL}; +static Evas_Object *layout = NULL; +static Evas_Object *overlay = NULL; +static Evas_Object *back = NULL; +static Evas_Object *entry = NULL; +static Ecore_Timer *reset_timer = NULL; +static Eina_List *handlers = NULL; +static Eina_Bool overlay_locked = EINA_FALSE; + +static Eina_Bool buttons_visible = EINA_TRUE; + +static Eina_Bool _event_opt_changed(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Changed *ev); +static void _tag_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED); +static void _opt_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info); + +static double +_opt_overlay_value_update(E_Configure_Option *co, Evas_Object *obj) +{ + char buf[256]; + double d; + Elm_Object_Item *it; + Evas_Object *o; + + it = e_configure_option_data_get(co, "conf_item"); + if (overlay_locked) + o = elm_object_part_content_get(overlay, "e.swallow.content"); + else + o = elm_object_item_part_content_get(it, "elm.swallow.icon"); + d = elm_slider_value_get(obj); + + + elm_slider_value_set(o, d); + snprintf(buf, sizeof(buf), co->info, d); + elm_object_part_text_set(overlay, "e.text.value", buf); + return d; +} + +static void +_opt_item_update(E_Configure_Option *co) +{ + Elm_Object_Item *it; + Evas_Object *o, *o2 = NULL; + void *val; + + it = e_configure_option_data_get(co, "conf_item"); + if (!it) return; + o = elm_object_item_part_content_get(it, "elm.swallow.icon"); + if (overlay && (!overlay_locked) && (co == evas_object_data_get(overlay, "config_option"))) + o2 = elm_object_part_content_get(overlay, "e.swallow.content"); + val = (void*)e_configure_option_value_get(co); + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + elm_check_state_pointer_set(o, val); + elm_check_state_pointer_set(o, NULL); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + elm_slider_value_set(o, *(unsigned char*)val); + if (o2) + { + elm_slider_value_set(o2, *(unsigned char*)val); + _opt_overlay_value_update(co, o2); + } + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + elm_slider_value_set(o, *(double*)val); + if (o2) + { + elm_slider_value_set(o2, *(double*)val); + _opt_overlay_value_update(co, o2); + } + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: + elm_slider_value_set(o, *(int*)val); + if (o2) + { + elm_slider_value_set(o2, *(int*)val); + _opt_overlay_value_update(co, o2); + } + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: + elm_slider_value_set(o, *(unsigned int*)val); + if (o2) + { + elm_slider_value_set(o2, *(unsigned int*)val); + _opt_overlay_value_update(co, o2); + } + break; + case E_CONFIGURE_OPTION_TYPE_ENUM: + if (o2) evas_object_smart_callback_call(o2, "changed", NULL); + break; + case E_CONFIGURE_OPTION_TYPE_STR: + if (o2) evas_object_smart_callback_call(o2, "activated", NULL); + break; + case E_CONFIGURE_OPTION_TYPE_INT: + case E_CONFIGURE_OPTION_TYPE_UINT: + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + break; //not applicable + } + +} + +static Eina_Bool +_button_icon_set(Evas_Object *o, const char *name) +{ + Evas_Object *ob; + + ob = elm_icon_add(o); + if (!elm_icon_standard_set(ob, name)) + { + char buf[4096]; + const char *file; + + snprintf(buf, sizeof(buf), "e/icons/%s", name); + file = e_theme_edje_icon_fallback_file_get(buf); + if ((!file) || (!file[0])) return EINA_FALSE; + if (!elm_image_file_set(ob, file, buf)) + { + evas_object_del(ob); + return EINA_FALSE; + } + } + elm_object_content_set(o, ob); + elm_object_style_set(o, "conf2"); + return EINA_TRUE; +} + +static Evas_Object * +_e_conf2_opt_tooltip_cb(void *data, Evas_Object *owner EINA_UNUSED, Evas_Object *tt, void *item EINA_UNUSED) +{ + Evas_Object *o; + + /* FIXME: tooltip theme seems to be broken for sizing */ + //e = elm_layout_add(tt); + //elm_layout_theme_set(e, "tooltip", "base", "conf2"); + o = elm_label_add(tt); + elm_object_style_set(o, "conf2"); + elm_object_text_set(o, data); + evas_object_show(o); + //elm_object_part_content_set(e, "elm.swallow.content", o); + return o; +} + +static void +_e_conf2_opt_realize(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *it) +{ + E_Configure_Option *co; + + co = elm_object_item_data_get(it); + if (!co->help) return; + elm_object_item_tooltip_content_cb_set(it, _e_conf2_opt_tooltip_cb, co->help, NULL); + elm_object_item_tooltip_style_set(it, "conf2"); + elm_object_item_tooltip_window_mode_set(it, EINA_TRUE); +} + +static void +_e_conf2_opts_list(E_Configure_Option_Ctx *ctx) +{ + Eina_List *l; + E_Configure_Option *co; + Elm_Object_Item *it; + + elm_genlist_clear(list[1]); + EINA_LIST_FOREACH(ctx->opts, l, co) + { + it = elm_genlist_item_append(list[1], itc_opts, co, NULL, 0, _opt_sel, co); + e_configure_option_data_set(co, "conf_item", it); + } +} + +static void +_ctx_active_update(void) +{ + Eina_List *l; + Eina_Stringshare *tag; + + ctx_active->tags = eina_list_free(ctx_active->tags); + ctx_active->changed = EINA_TRUE; + if (ctx_entry && ctx_entry->tags) + ctx_active->tags = eina_list_clone(ctx_entry->tags); + else + { + if (ctx_click && ctx_click->tags) + ctx_active->tags = eina_list_clone(ctx_click->tags); + return; + } + if ((!ctx_click) || (!ctx_click->tags)) return; + EINA_LIST_FOREACH(ctx_click->tags, l, tag) + e_configure_option_ctx_tag_add(ctx_active, tag); +} + +static void +_tag_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + const Eina_List *l; + Eina_Stringshare *tag; + + E_FN_DEL(ecore_timer_del, reset_timer); + if (!ctx_click) ctx_click = e_configure_option_ctx_new(); + if (!e_configure_option_ctx_tag_add(ctx_click, data)) return; + _ctx_active_update(); + e_configure_option_ctx_option_list(ctx_active); + elm_object_disabled_set(back, 0); + if (!elm_genlist_items_count(list[1])) + elm_layout_signal_emit(layout, "e,action,expand", "e"); + _e_conf2_opts_list(ctx_active); + elm_genlist_clear(list[0]); + e_configure_option_ctx_match_tag_list(ctx_active); + EINA_LIST_FOREACH(ctx_active->match_tags, l, tag) + elm_genlist_item_append(list[0], itc_tags, tag, NULL, 0, _tag_sel, tag); +} + +static void +_cat_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eina_Stringshare *tag; + const Eina_List *l; + Eina_List *ll, *lll, *opts = NULL; + E_Configure_Option *co; + + elm_object_disabled_set(back, 0); + if (!ctx_click) ctx_click = e_configure_option_ctx_new(); + ctx_click->category = ctx_active->category = data; + E_FN_DEL(ecore_timer_del, reset_timer); + elm_genlist_clear(list[0]); + EINA_LIST_FOREACH(e_configure_option_category_list_tags(data), l, tag) + { + elm_genlist_item_append(list[0], itc_tags, tag, NULL, 0, _tag_sel, tag); + opts = eina_list_merge(opts, eina_list_clone(e_configure_option_tag_list_options(tag))); + } + EINA_LIST_FOREACH_SAFE(opts, ll, lll, co) + { + Eina_List *lc; + + while (1) + { + if (!lll) break; + lc = eina_list_data_find_list(lll, co); + if (!lc) break; + if (lc == lll) lll = eina_list_next(lll); + opts = eina_list_remove_list(opts, lc); + } + } + ctx_active->opts = opts; + if (!elm_genlist_items_count(list[1])) + elm_layout_signal_emit(layout, "e,action,expand", "e"); + _e_conf2_opts_list(ctx_active); +} + +static Eina_Bool +_reset_cb(void *d EINA_UNUSED) +{ + const Eina_List *l; + Eina_Stringshare *cat; + + elm_layout_signal_emit(layout, "e,action,collapse", "e"); + elm_genlist_clear(list[0]); + elm_genlist_clear(list[1]); + ctx_active->match_tags = eina_list_free(ctx_active->match_tags); + ctx_active->tags = eina_list_free(ctx_active->tags); + ctx_active->opts = eina_list_free(ctx_active->opts); + E_FN_DEL(e_configure_option_ctx_free, ctx_entry); + E_FN_DEL(e_configure_option_ctx_free, ctx_click); + EINA_LIST_FOREACH(e_configure_option_category_list(), l, cat) + elm_genlist_item_append(list[0], itc_cats, cat, NULL, 0, _cat_sel, cat); + elm_object_disabled_set(back, 1); + if (!e_configure_option_changed_list()) + { + elm_layout_signal_emit(layout, "e,action,apply_hide", "e"); + elm_layout_signal_emit(layout, "e,action,discard_hide", "e"); + buttons_visible = EINA_FALSE; + } + ctx_active->category = NULL; + reset_timer = NULL; + return EINA_FALSE; +} + +static void +_entry_change_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Eina_Stringshare *txt, *tag; + Eina_List *l; + + E_FN_DEL(ecore_timer_del, reset_timer); + txt = elm_entry_entry_get(obj); + E_FN_DEL(evas_object_del, overlay); + if (!ctx_entry) ctx_entry = e_configure_option_ctx_new(); + if (!e_configure_option_ctx_update(ctx_entry, txt)) return; + _ctx_active_update(); + if (!e_configure_option_ctx_option_list(ctx_active)) + { + if (!ctx_active->tags) _reset_cb(NULL); + else elm_genlist_clear(list[1]); + return; + } + if ((ctx_click && ctx_click->tags) || ctx_active->category) + elm_object_disabled_set(back, 0); + if (!elm_genlist_items_count(list[1])) + elm_layout_signal_emit(layout, "e,action,expand", "e"); + _e_conf2_opts_list(ctx_active); + elm_genlist_clear(list[0]); + e_configure_option_ctx_match_tag_list(ctx_active); + EINA_LIST_FOREACH(ctx_active->match_tags, l, tag) + elm_genlist_item_append(list[0], itc_tags, tag, NULL, 0, _tag_sel, tag); +} + +static void +_apply_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + e_configure_option_apply_all(); + if (buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_hide", "e"); + elm_layout_signal_emit(layout, "e,action,discard_hide", "e"); + } + buttons_visible = EINA_FALSE; +} + +static void +_discard_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + /* buttons hidden in event callback */ + if (overlay) + { + E_Configure_Option *co; + + co = evas_object_data_get(overlay, "config_option"); + if (co) + { + e_configure_option_reset(co); + return; + } + + } + e_configure_option_reset_all(); +} + +static Eina_Bool +_cat_back_cb(void *data EINA_UNUSED) +{ + ctx_active->tags = eina_list_free(ctx_active->tags); + ctx_active->opts = eina_list_free(ctx_active->opts); + _cat_sel((void*)ctx_active->category, NULL, NULL); + reset_timer = NULL; + return EINA_FALSE; +} + +static void +_back_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Elm_Object_Item *it; + const Eina_List *l; + Eina_Stringshare *tag; + Eina_Bool cat = EINA_FALSE; + + E_FN_DEL(ecore_timer_del, reset_timer); + if (overlay) + { + evas_object_del(overlay); + return; + } + if (!ctx_click) return; + E_FN_DEL(evas_object_del, overlay); + if (ctx_click->tags) + { + cat = EINA_TRUE; + if (!e_configure_option_ctx_tag_pop(ctx_click)) return; + _ctx_active_update(); + } + if ((!ctx_click->tags) && (!ctx_active->tags)) + { + if (cat) + reset_timer = ecore_timer_add(0.1, _cat_back_cb, NULL); + else + reset_timer = ecore_timer_add(0.01, _reset_cb, NULL); + return; + } + e_configure_option_ctx_option_list(ctx_active); + _e_conf2_opts_list(ctx_active); + e_configure_option_ctx_match_tag_list(ctx_active); + EINA_LIST_FOREACH(ctx_active->match_tags, l, tag) + elm_genlist_item_append(list[0], itc_tags, tag, NULL, 0, _tag_sel, tag); + it = elm_genlist_selected_item_get(list[0]); + if (it) elm_genlist_item_selected_set(it, EINA_FALSE); +} + +static void +_e_conf2_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_FN_DEL(elm_genlist_item_class_free, itc_cats); + E_FN_DEL(elm_genlist_item_class_free, itc_tags); + E_FN_DEL(elm_genlist_item_class_free, itc_opts); + E_FN_DEL(elm_genlist_item_class_free, itc_thumb); + E_FN_DEL(e_configure_option_ctx_free, ctx_entry); + E_FN_DEL(e_configure_option_ctx_free, ctx_click); + E_FN_DEL(e_configure_option_ctx_free, ctx_active); + E_FN_DEL(ecore_timer_del, reset_timer); + list[0] = list[1] = layout = overlay = back = entry = NULL; + E_FREE_LIST(handlers, ecore_event_handler_del); + e_configure_option_reset_all(); + buttons_visible = EINA_TRUE; + overlay_locked = EINA_FALSE; +} + +static char * +_e_conf2_text_get_opts(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED) +{ + E_Configure_Option *co = data; + char *txt = NULL; + + if (!strcmp(part, "elm.text")) + txt = strdup(co->desc); + else if (!strcmp(part, "elm.text.sub")) + txt = strdup(co->name); + + return txt; +} + +static void +_e_conf2_opt_change_double_int(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + int x; + + x = lround(elm_slider_value_get(obj)); + + if (e_config->cfgdlg_auto_apply) + *(int*)co->valptr = x; + else + eina_value_set(&co->val, x); + e_configure_option_changed(co); +} + +static void +_e_conf2_opt_change_double(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + + if (e_config->cfgdlg_auto_apply) + *(double*)co->valptr = elm_slider_value_get(obj); + else + eina_value_set(&co->val, elm_slider_value_get(obj)); + e_configure_option_changed(co); +} + +static void +_e_conf2_opt_change_double_uchar(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + int x; + unsigned char u; + + x = lround(elm_slider_value_get(obj)); + u = MAX(0, x); + + if (e_config->cfgdlg_auto_apply) + *(unsigned char*)co->valptr = u; + else + eina_value_set(&co->val, u); + e_configure_option_changed(co); +} + +static void +_e_conf2_opt_change_bool(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + + if (e_config->cfgdlg_auto_apply) + *(Eina_Bool*)co->valptr = elm_check_state_get(obj); + else + eina_value_set(&co->val, elm_check_state_get(obj)); + e_configure_option_changed(co); +} + +static void +_opt_overlay_slider_change(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + _opt_overlay_value_update(co, obj); + _e_conf2_opt_change_double(co, obj, NULL); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: + _opt_overlay_value_update(co, obj); + _e_conf2_opt_change_double_int(co, obj, NULL); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + _opt_overlay_value_update(co, obj); + _e_conf2_opt_change_double_uchar(co, obj, NULL); + default: + break; + } +} + +static void +_opt_overlay_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Elm_Object_Item *it; + + overlay = NULL; + it = elm_genlist_selected_item_get(list[1]); + if (it) elm_genlist_item_selected_set(it, EINA_FALSE); + elm_layout_signal_emit(layout, "e,action,overlay_hide", "e"); + elm_object_disabled_set(list[0], EINA_FALSE); + elm_object_disabled_set(list[1], EINA_FALSE); + elm_object_focus_allow_set(entry, EINA_TRUE); + elm_object_focus_allow_set(list[0], EINA_TRUE); + elm_object_focus_allow_set(list[1], EINA_TRUE); + elm_object_focus_set(list[1], EINA_TRUE); + _event_opt_changed(NULL, E_EVENT_CONFIGURE_OPTION_CHANGED, NULL); +} + +static void +_opt_overlay_list_change(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_Configure_Option_Info *oi = data; + + elm_object_part_text_set(overlay, "e.text.value", oi->name); + if (oi->co->type == E_CONFIGURE_OPTION_TYPE_STR) + { + if (e_config->cfgdlg_auto_apply) + eina_stringshare_replace(oi->co->valptr, oi->value); + else + eina_value_set(&oi->co->val, oi->value); + } + else + { + if (e_config->cfgdlg_auto_apply) + *(int*)oi->co->valptr = *(int*)oi->value; + else + eina_value_set(&oi->co->val, *(int*)oi->value); + } + + e_configure_option_changed(oi->co); +} + +static void +_opt_overlay_dismiss(void *d EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED) +{ + evas_object_del(overlay); +} + +static void +_opt_overlay_create(void) +{ + Evas_Object *o; + + overlay = o = elm_layout_add(layout); + evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _opt_overlay_del, NULL); + elm_layout_theme_set(o, "conf2", "option", "overlay"); +} + +static void +_e_conf2_item_del_thumb(void *data, Evas_Object *obj EINA_UNUSED) +{ + E_Configure_Option_Info *oi = data; + + eina_stringshare_del(oi->value); + e_configure_option_info_free(oi); +} + +static Evas_Object * +_e_conf2_content_get_thumb(void *data, Evas_Object *obj, const char *part EINA_UNUSED) +{ + E_Configure_Option_Info *oi = data; + Evas_Object *o; + Evas *e; + E_Zone *zone; + + e = evas_object_evas_get(obj); + o = e_configure_option_info_thumb_get(oi, e); + if (o) return o; + + if (!oi->thumb_file) return NULL; + zone = e_util_zone_current_get(e_manager_current_get()); + /* viva la revolucion de livethumb!!! */ + o = e_widget_preview_add(e, 170, (170 * zone->h) / zone->w); + if (oi->thumb_key) + e_widget_preview_edje_set(o, oi->thumb_file, oi->thumb_key); + else + e_widget_preview_file_set(o, oi->thumb_file, oi->thumb_key); + +/* I guess elm_image sucks, this looks like shit :/ + o = elm_image_add(obj); + elm_image_file_set(o, oi->thumb_file, oi->thumb_key); + if (elm_image_animated_available_get(o)) + { + elm_image_animated_set(o, EINA_TRUE); + elm_image_animated_play_set(o, EINA_TRUE); + } + elm_image_aspect_fixed_set(o, EINA_TRUE); + elm_image_prescale_set(o, 300); +*/ + return o; +} + +static char * +_e_conf2_text_get_thumb(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED) +{ + E_Configure_Option_Info *oi = data; + + return oi->name ? strdup(oi->name) : NULL; +} + +static void +_opt_overlay_entry_change(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + E_Configure_Option *co = data; + Eina_Stringshare *str; + + str = elm_entry_entry_get(obj); + if (str == *(Eina_Stringshare**)co->valptr) return; + if (e_config->cfgdlg_auto_apply) + eina_stringshare_replace(co->valptr, str); + else + eina_value_set(&co->val, str); + e_configure_option_changed(co); +} + +static void +_opt_overlay_radio_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + e_configure_option_info_free(data); +} + +static void +_opt_overlay_radio_change(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_Configure_Option_Info *oi = data; + + elm_object_part_text_set(overlay, "e.text.value", oi->name); + if (e_config->cfgdlg_auto_apply) + *(int*)oi->co->valptr = (long)(intptr_t)oi->value; + else + eina_value_set(&oi->co->val, (long)(intptr_t)oi->value); + + e_configure_option_changed(oi->co); +} + +static void +_opt_overlay_show(E_Configure_Option *co, Elm_Object_Item *it) +{ + Evas_Object *o, *sl; + Eina_Bool show = EINA_TRUE; + Eina_List *l; + double d; + char buf[256]; + + if (!it) it = e_configure_option_data_get(co, "conf_item"); + if (co->changed) + { + if (!buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_show", "e"); + elm_layout_signal_emit(layout, "e,action,discard_show", "e"); + } + buttons_visible = EINA_TRUE; + } + else + { + if (buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_hide", "e"); + elm_layout_signal_emit(layout, "e,action,discard_hide", "e"); + } + buttons_visible = EINA_FALSE; + } + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + EINA_SAFETY_ON_NULL_RETURN(co->info); + e_configure_registry_call(co->info, NULL, NULL); + if (it) elm_genlist_item_selected_set(it, EINA_FALSE); + break; + case E_CONFIGURE_OPTION_TYPE_ENUM: + if (!overlay) _opt_overlay_create(); + else show = EINA_FALSE; + o = overlay; + evas_object_data_set(overlay, "config_option", co); + elm_object_part_text_set(o, "e.text.label", co->desc); + l = e_configure_option_info_get(co); + if (l) + { + E_Configure_Option_Info *oi; + Evas_Object *bx, *g, *r; + + sl = elm_scroller_add(overlay); + EXPAND(sl); + FILL(sl); + elm_scroller_bounce_set(sl, 0, 0); + elm_scroller_policy_set(sl, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_AUTO); + bx = elm_box_add(o); + EXPAND(bx); + FILL(bx); + elm_object_content_set(sl, bx); + elm_box_homogeneous_set(bx, 1); + g = elm_radio_add(overlay); + elm_object_focus_allow_set(list[0], EINA_FALSE); + elm_object_focus_allow_set(list[1], EINA_FALSE); + elm_object_focus_allow_set(entry, EINA_FALSE); + EINA_LIST_FREE(l, oi) + { + if (!oi->name) continue; //FIXME sep + r = elm_radio_add(overlay); + elm_object_style_set(r, "conf2"); + EXPAND(r); + FILL(r); + elm_radio_group_add(r, g); + elm_object_text_set(r, oi->name); + elm_radio_state_value_set(r, (long)(intptr_t)oi->value); + evas_object_event_callback_add(r, EVAS_CALLBACK_DEL, _opt_overlay_radio_del, oi); + evas_object_smart_callback_add(r, "changed", _opt_overlay_radio_change, oi); + if (oi->current) + { + elm_radio_value_set(g, (long)(intptr_t)oi->value); + elm_object_part_text_set(overlay, "e.text.value", oi->name); + } + evas_object_show(r); + elm_object_focus_set(r, EINA_TRUE); + elm_box_pack_end(bx, r); + } + evas_object_show(bx); + } + else + { + /* FIXME? */ + evas_object_del(overlay); + return; + } + elm_object_part_content_set(o, "e.swallow.content", sl); + evas_object_show(sl); + evas_object_show(o); + elm_object_part_content_set(layout, "e.swallow.overlay", o); + if (show) + elm_layout_signal_emit(layout, "e,action,overlay_show", "e"); + elm_object_disabled_set(list[0], EINA_TRUE); + elm_object_disabled_set(list[1], EINA_TRUE); + break; + case E_CONFIGURE_OPTION_TYPE_STR: + if (!overlay) _opt_overlay_create(); + else show = EINA_FALSE; + o = overlay; + evas_object_data_set(overlay, "config_option", co); + elm_object_part_text_set(o, "e.text.label", co->desc); + l = e_configure_option_info_get(co); + if (l) + { + E_Configure_Option_Info *oi; + Elm_Object_Item *iit; + + sl = elm_genlist_add(overlay); + elm_scroller_bounce_set(sl, 0, 0); + elm_scroller_policy_set(sl, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); + EINA_LIST_FREE(l, oi) + { + if (!oi->name) continue; //FIXME sep + iit = elm_genlist_item_append(sl, itc_thumb, oi, NULL, 0, _opt_overlay_list_change, oi); + elm_genlist_item_selected_set(iit, oi->current); + if (oi->current) elm_genlist_item_show(iit, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); + } + } + else + { + Eina_Stringshare **s; + + sl = elm_entry_add(overlay); + s = (Eina_Stringshare**)e_configure_option_value_get(co); + if (s) + { + elm_entry_entry_set(sl, *s); + elm_entry_select_all(sl); + } + elm_entry_single_line_set(sl, EINA_TRUE); + elm_entry_scrollable_set(sl, EINA_TRUE); + elm_entry_cursor_begin_set(sl); + evas_object_smart_callback_add(sl, "activated", _opt_overlay_entry_change, co); + edje_extern_object_min_size_set(sl, 170, 20); + elm_object_part_text_set(overlay, "e.text.value", NULL); + } + elm_object_part_content_set(o, "e.swallow.content", sl); + evas_object_show(sl); + elm_object_focus_allow_set(list[0], EINA_FALSE); + elm_object_focus_allow_set(list[1], EINA_FALSE); + elm_object_focus_allow_set(entry, EINA_FALSE); + elm_object_focus_set(sl, EINA_TRUE); + evas_object_show(o); + elm_object_part_content_set(layout, "e.swallow.overlay", o); + if (show) + elm_layout_signal_emit(layout, "e,action,overlay_show", "e"); + elm_object_disabled_set(list[0], EINA_TRUE); + elm_object_disabled_set(list[1], EINA_TRUE); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + sl = elm_object_item_part_content_get(it, "elm.swallow.icon"); + if (!overlay) _opt_overlay_create(); + else show = EINA_FALSE; + o = overlay; + evas_object_data_set(overlay, "config_option", co); + elm_layout_signal_emit(overlay, "e,state,bg_hide", "e"); + elm_object_part_text_set(o, "e.text.label", co->desc); + d = elm_slider_value_get(sl); + snprintf(buf, sizeof(buf), co->info, d); + elm_object_part_text_set(overlay, "e.text.value", buf); + sl = elm_slider_add(layout); + elm_slider_min_max_set(sl, co->minmax[0], co->minmax[1]); + /* raoulh! :) */ + elm_slider_value_set(sl, d); + elm_object_style_set(sl, "knob_volume_big"); + evas_object_smart_callback_add(sl, "changed", _opt_overlay_slider_change, co); + evas_object_show(sl); + elm_object_part_content_set(o, "e.swallow.content", sl); + evas_object_show(o); + elm_object_part_content_set(layout, "e.swallow.overlay", o); + if (show) + elm_layout_signal_emit(layout, "e,action,overlay_show", "e"); + elm_object_disabled_set(list[0], EINA_TRUE); + elm_object_disabled_set(list[1], EINA_TRUE); + break; + default: + if (overlay) evas_object_del(overlay); + } +} + +static void +_opt_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + _opt_overlay_show(data, event_info); +} + +static void +_e_conf2_slider_drag_start(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + overlay_locked = EINA_TRUE; + _opt_overlay_show(data, NULL); +} + +static void +_e_conf2_slider_drag_stop(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + evas_object_del(overlay); + overlay_locked = EINA_FALSE; +} + +static Evas_Object * +_e_conf2_content_get_opts_slider_helper(E_Configure_Option *co) +{ + Evas_Object *o; + + o = elm_slider_add(layout); + /* raoulh! :) */ + elm_object_style_set(o, "knob_volume"); + elm_slider_min_max_set(o, co->minmax[0], co->minmax[1]); + evas_object_smart_callback_add(o, "changed", _opt_overlay_slider_change, co); + evas_object_smart_callback_add(o, "slider,drag,start", _e_conf2_slider_drag_start, co); + evas_object_smart_callback_add(o, "slider,drag,stop", _e_conf2_slider_drag_stop, co); + return o; +} + +static Evas_Object * +_e_conf2_content_get_opts(void *data, Evas_Object *obj, const char *part EINA_UNUSED) +{ + E_Configure_Option *co = data; + Evas_Object *o = NULL; + const void *val; + //char buf[PATH_MAX]; + + if (!strcmp(part, "elm.swallow.icon")) + { + switch (co->type) + { + case E_CONFIGURE_OPTION_TYPE_BOOL: + o = elm_check_add(obj); + elm_object_style_set(o, "conf2"); + val = e_configure_option_value_get(co); + elm_check_state_set(o, *(Eina_Bool*)val); + evas_object_smart_callback_add(o, "changed", _e_conf2_opt_change_bool, co); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UCHAR: + o = _e_conf2_content_get_opts_slider_helper(co); + val = e_configure_option_value_get(co); + elm_slider_value_set(o, *(unsigned char*)val); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE: + o = _e_conf2_content_get_opts_slider_helper(co); + val = e_configure_option_value_get(co); + elm_slider_value_set(o, *(double*)val); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_INT: + o = _e_conf2_content_get_opts_slider_helper(co); + val = e_configure_option_value_get(co); + elm_slider_value_set(o, *(int*)val); + break; + case E_CONFIGURE_OPTION_TYPE_DOUBLE_UINT: + o = _e_conf2_content_get_opts_slider_helper(co); + val = e_configure_option_value_get(co); + elm_slider_value_set(o, *(unsigned int*)val); + break; + case E_CONFIGURE_OPTION_TYPE_CUSTOM: + case E_CONFIGURE_OPTION_TYPE_STR: + case E_CONFIGURE_OPTION_TYPE_ENUM: + case E_CONFIGURE_OPTION_TYPE_INT: + case E_CONFIGURE_OPTION_TYPE_UINT: + { + Eina_Stringshare *icon; + char buf[4096]; + + icon = e_configure_option_data_get(co, "icon"); + if (!icon) break; + if (eina_str_has_extension(icon, ".edj")) + o = e_util_icon_add(icon, evas_object_evas_get(obj)); + else + { + snprintf(buf, sizeof(buf), "e/icons/%s", icon); + + o = e_icon_add(evas_object_evas_get(obj)); + e_util_icon_theme_set(o, icon); + } + } + break; + } + } + else if (!strcmp(part, "elm.swallow.end")) + { + if (!co->changed) return NULL; + o = edje_object_add(evas_object_evas_get(obj)); + e_theme_edje_object_set(o, "base/theme/widgets", "e/widgets/ilist/toggle_end"); + } + return o; +} + +static void +_e_conf2_item_del_opts(void *data, Evas_Object *obj EINA_UNUSED) +{ + e_configure_option_data_set(data, "conf_item", NULL); +} + +static char * +_e_conf2_text_get_tags(void *data, Evas_Object *obj EINA_UNUSED, const char *part) +{ + char *txt; + + if (strcmp(part, "elm.text")) return NULL; + txt = strdup(data); + txt[0] = toupper(txt[0]); + return txt; +} + +static Evas_Object * +_e_conf2_content_get_cats(void *data, Evas_Object *obj, const char *part) +{ + char buf[4096]; + Eina_Stringshare *icon; + Evas_Object *o; + + if (!strcmp(part, "elm.swallow.end")) return NULL; + icon = e_configure_option_category_icon_get(data); + if (!icon) return NULL; + snprintf(buf, sizeof(buf), "e/icons/%s", icon); + + o = e_icon_add(evas_object_evas_get(obj)); + e_util_icon_theme_set(o, icon); + return o; +} + +static Evas_Object * +_e_conf2_content_get_tags(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED) +{ + /* FIXME */ + return NULL; +} + +static void +_e_conf2_key(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + if (overlay) evas_object_del(overlay); + else evas_object_del(obj); +} + +static Eina_Bool +_event_tag_del(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Tag_Del *ev EINA_UNUSED) +{ + /* not even gonna fuck with this */ + _reset_cb(NULL); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_tag_add(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Tag_Add *ev) +{ + Eina_List *l; + Eina_Stringshare *tag; + + e_configure_option_ctx_match_tag_list(ctx_active); + if ((!ctx_active->match_tags) || (!eina_list_data_find(ctx_active->match_tags, ev->tag))) + return ECORE_CALLBACK_RENEW; + elm_genlist_clear(list[0]); + EINA_LIST_FOREACH(ctx_active->match_tags, l, tag) + elm_genlist_item_append(list[0], itc_tags, tag, NULL, 0, _tag_sel, tag); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_cat_del(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Category_Add *ev) +{ + Elm_Object_Item *it; + Eina_Stringshare *cat; + + if (ctx_active->category == ev->category) + { + _reset_cb(NULL); + return ECORE_CALLBACK_RENEW; + } + if (ctx_active->tags || ctx_active->opts) return ECORE_CALLBACK_RENEW; //not showing categories at present + //new categories are added at end, so go backward + for (it = elm_genlist_last_item_get(list[0]); it; it = elm_genlist_item_prev_get(it)) + { + cat = elm_object_item_data_get(it); + if (cat != ev->category) continue; + elm_object_item_del(it); + break; + } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_cat_add(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Category_Add *ev) +{ + if (ctx_active->category || ctx_active->tags || ctx_active->opts) return ECORE_CALLBACK_RENEW; //not showing categories at present + elm_genlist_item_append(list[0], itc_cats, ev->category, NULL, 0, _cat_sel, ev->category); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_opt_del(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Del *ev) +{ + Elm_Object_Item *it; + Eina_List *l; + + if (!ctx_active->opts) return ECORE_CALLBACK_RENEW; + l = eina_list_data_find(ctx_active->opts, ev->co); + if (!l) return ECORE_CALLBACK_RENEW; + ctx_active->opts = eina_list_remove_list(ctx_active->opts, l); + + if (ctx_click && ctx_click->opts) + ctx_click->opts = eina_list_remove(ctx_click->opts, ev->co); + if (ctx_entry && ctx_entry->opts) + ctx_entry->opts = eina_list_remove(ctx_entry->opts, ev->co); + + for (it = elm_genlist_last_item_get(list[1]); it; it = elm_genlist_item_prev_get(it)) + { + if (ev->co != elm_object_item_data_get(it)) continue; + elm_object_item_del(it); + break; + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_opt_add(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Add *ev) +{ + Eina_List *l; + Eina_Stringshare *tag; + + if (!ctx_active->opts) return ECORE_CALLBACK_RENEW; + /* FIXME: this will only add the item if we are NOT directly viewing a category */ + if (!ctx_active->tags) return ECORE_CALLBACK_RENEW; + EINA_LIST_FOREACH(ev->co->tags, l, tag) + if (eina_list_data_find(ctx_active->tags, tag)) + { + ctx_active->changed = EINA_TRUE; + break; + } + if (!ctx_active->changed) return ECORE_CALLBACK_RENEW; + e_configure_option_ctx_option_list(ctx_active); + _e_conf2_opts_list(ctx_active); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_event_opt_changed(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Configure_Option_Changed *ev) +{ + E_Configure_Option *co; + Elm_Object_Item *it; + + it = e_configure_option_data_get(ev->co, "conf_item"); + if (it) + elm_genlist_item_fields_update(it, "elm.swallow.end", ELM_GENLIST_ITEM_FIELD_CONTENT); + if (overlay) + { + co = evas_object_data_get(overlay, "config_option"); + if (ev->co != co) return ECORE_CALLBACK_RENEW; + if (co->changed) + { + if (!buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_show", "e"); + elm_layout_signal_emit(layout, "e,action,discard_show", "e"); + } + buttons_visible = EINA_TRUE; + } + else + { + if (buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_hide", "e"); + elm_layout_signal_emit(layout, "e,action,discard_hide", "e"); + } + buttons_visible = EINA_FALSE; + _opt_item_update(co); + } + return ECORE_CALLBACK_RENEW; + } + if (e_configure_option_changed_list()) + { + if (!buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_show", "e"); + elm_layout_signal_emit(layout, "e,action,discard_show", "e"); + } + buttons_visible = EINA_TRUE; + return ECORE_CALLBACK_RENEW; + } + if (buttons_visible) + { + elm_layout_signal_emit(layout, "e,action,apply_hide", "e"); + elm_layout_signal_emit(layout, "e,action,discard_hide", "e"); + } + buttons_visible = EINA_FALSE; + if (ev) _opt_item_update(ev->co); + return ECORE_CALLBACK_RENEW; +} + +static void +_theme_change(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + _reset_cb(NULL); + _entry_change_cb(NULL, entry, NULL); +} + +EINTERN void +e_conf2_show(E_Container *con EINA_UNUSED, const char *params) +{ + Evas_Object *box, *box2, *o, *win; + + if (list[0]) + { + elm_win_activate(elm_object_top_widget_get(list[0])); + return; + } + + win = elm_win_add(NULL, "conf2", ELM_WIN_DIALOG_BASIC); + elm_win_title_set(win, _("Control Panel")); + o = elm_bg_add(win); + elm_object_style_set(o, "conf2"); + EXPAND(o); + elm_win_resize_object_add(win, o); + evas_object_show(o); + 1 | evas_object_key_grab(win, "Escape", 0, 0, 1); + evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN, _e_conf2_key, NULL); + /* FIXME this is insane */ + ecore_evas_name_class_set(ecore_evas_ecore_evas_get(evas_object_evas_get(win)), "conf2", "_configure"); + elm_win_autodel_set(win, EINA_TRUE); + evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _e_conf2_del, NULL); + box = elm_box_add(win); + EXPAND(box); + FILL(box); + elm_win_resize_object_add(win, box); + evas_object_show(box); + + box2 = elm_box_add(win); + elm_box_horizontal_set(box2, EINA_TRUE); + WEIGHT(box2, EVAS_HINT_EXPAND, 0); + ALIGN(box2, EVAS_HINT_FILL, 0); + elm_box_pack_end(box, box2); + evas_object_show(box2); + + back = o = elm_button_add(win); + elm_object_focus_allow_set(back, EINA_FALSE); + evas_object_smart_callback_add(o, "clicked", _back_cb, NULL); + //elm_object_text_set(o, _("Back")); + if (!_button_icon_set(o, "back")) + _button_icon_set(o, "go-previous"); + WEIGHT(o, 0, 0); + FILL(o); + elm_object_disabled_set(o, (params && params[0])); + elm_box_pack_end(box2, o); + evas_object_show(o); + + o = elm_label_add(win); + elm_object_style_set(o, "conf2"); + elm_object_text_set(o, _("Search: ")); + WEIGHT(o, 0, EVAS_HINT_EXPAND); + ALIGN(o, 0, EVAS_HINT_FILL); + elm_box_pack_end(box2, o); + evas_object_show(o); + + entry = o = elm_entry_add(win); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_object_style_set(o, "conf2"); + if (params && params[0]) + { + elm_entry_entry_set(o, params); + _entry_change_cb(NULL, o, NULL); + } + else + reset_timer = ecore_timer_add(0.01, _reset_cb, NULL); + EXPAND(o); + FILL(o); + evas_object_smart_callback_add(o, "changed", _entry_change_cb, NULL); + evas_object_smart_callback_add(o, "activated", _entry_change_cb, NULL); + elm_box_pack_end(box2, o); + evas_object_show(o); + elm_object_focus_set(o, EINA_TRUE); + + o = layout = elm_layout_add(win); + EXPAND(o); + FILL(o); + elm_layout_freeze(o); + elm_layout_theme_set(o, "conf2", "tag", "list"); + evas_object_smart_callback_add(o, "theme,changed", _theme_change, NULL); + elm_layout_signal_callback_add(layout, "e,action,overlay_dismiss", "e", _opt_overlay_dismiss, NULL); + + o = list[0] = elm_genlist_add(win); + elm_genlist_homogeneous_set(o, EINA_TRUE); + elm_genlist_mode_set(o, ELM_LIST_COMPRESS); + EXPAND(o); + FILL(o); + + itc_cats = elm_genlist_item_class_new(); + itc_cats->item_style = "conf2_double_label"; + itc_cats->func.text_get = _e_conf2_text_get_tags; + itc_cats->func.content_get = _e_conf2_content_get_cats; + itc_cats->func.state_get = NULL; + itc_cats->func.del = NULL; + + itc_tags = elm_genlist_item_class_new(); + itc_tags->item_style = "conf2_tag"; + itc_tags->func.text_get = _e_conf2_text_get_tags; + itc_tags->func.content_get = _e_conf2_content_get_tags; + itc_tags->func.state_get = NULL; + itc_tags->func.del = NULL; + elm_object_part_content_set(layout, "e.swallow.tags", o); + evas_object_show(o); + + o = list[1] = elm_genlist_add(win); + evas_object_smart_callback_add(o, "realized", _e_conf2_opt_realize, NULL); + elm_genlist_homogeneous_set(o, EINA_TRUE); + EXPAND(o); + FILL(o); + itc_opts = elm_genlist_item_class_new(); + itc_opts->item_style = "conf2_double_label"; + itc_opts->func.text_get = _e_conf2_text_get_opts; + itc_opts->func.content_get = _e_conf2_content_get_opts; + itc_opts->func.state_get = NULL; + itc_opts->func.del = _e_conf2_item_del_opts; + elm_object_part_content_set(layout, "e.swallow.options", o); + evas_object_show(o); + + itc_thumb = elm_genlist_item_class_new(); + itc_thumb->item_style = "conf2_thumb"; + itc_thumb->func.text_get = _e_conf2_text_get_thumb; + itc_thumb->func.content_get = _e_conf2_content_get_thumb; + itc_thumb->func.state_get = NULL; + itc_thumb->func.del = _e_conf2_item_del_thumb; + + o = elm_button_add(win); + evas_object_smart_callback_add(o, "clicked", _discard_cb, NULL); + elm_object_text_set(o, _("Discard")); + if (!_button_icon_set(o, "dialog-cancel")) + _button_icon_set(o, "view-refresh"); + WEIGHT(o, 0, 0); + FILL(o); + elm_object_part_content_set(layout, "e.swallow.discard", o); + evas_object_show(o); + + o = elm_button_add(win); + evas_object_smart_callback_add(o, "clicked", _apply_cb, NULL); + elm_object_text_set(o, _("Apply")); + _button_icon_set(o, "dialog-ok-apply"); + WEIGHT(o, 0, 0); + FILL(o); + elm_object_part_content_set(layout, "e.swallow.apply", o); + evas_object_show(o); + + elm_layout_thaw(layout); + evas_object_show(layout); + elm_box_pack_end(box, layout); + elm_win_size_base_set(win, 360, 360); + evas_object_show(win); + evas_object_resize(win, 480, 480); + + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_CHANGED, _event_opt_changed, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_ADD, _event_opt_add, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_DEL, _event_opt_del, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_CATEGORY_ADD, _event_cat_add, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_CATEGORY_DEL, _event_cat_del, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_TAG_ADD, _event_tag_add, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_CONFIGURE_OPTION_TAG_DEL, _event_tag_del, NULL); + ctx_active = e_configure_option_ctx_new(); +} + +EINTERN void +e_conf2_hide(void) +{ + if (!back) return; + evas_object_del(elm_object_top_widget_get(back)); +} diff --git a/src/modules/conf2/e_mod_main.c b/src/modules/conf2/e_mod_main.c new file mode 100644 index 000000000..50e4f0b2e --- /dev/null +++ b/src/modules/conf2/e_mod_main.c @@ -0,0 +1,381 @@ +#include "e.h" +#include "e_mod_main.h" + +typedef struct _Instance Instance; +struct _Instance +{ + E_Gadcon_Client *gcc; + Evas_Object *o_toggle; +}; + +/* actual module specifics */ + +//static void _e_mod_conf_cb(void *data, E_Menu *m, E_Menu_Item *mi); +//static void _e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi); +//static void _config_pre_activate_cb(void *data, E_Menu *m); + +/* gadcon requirements */ +static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style); +static void _gc_shutdown(E_Gadcon_Client *gcc); +static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient); +static const char *_gc_label(const E_Gadcon_Client_Class *client_class); +static Evas_Object *_gc_icon(const E_Gadcon_Client_Class *client_class, Evas *evas); +static const char *_gc_id_new(const E_Gadcon_Client_Class *client_class); +static void _cb_action_conf(void *data, Evas_Object *obj, const char *emission, const char *source); + +static E_Module *conf_module = NULL; +static E_Action *act = NULL; +static E_Int_Menu_Augmentation *maug = NULL; +static Eina_List *instances = NULL; + +EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Conf2" }; + +/* and actually define the gadcon class that this module provides (just 1) */ +static const E_Gadcon_Client_Class _gadcon_class = +{ + GADCON_CLIENT_CLASS_VERSION, "configuration", + { + _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, + e_gadcon_site_is_not_toolbar + }, + E_GADCON_CLIENT_STYLE_PLAIN +}; + +static E_Gadcon_Client * +_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) +{ + Instance *inst; + + inst = E_NEW(Instance, 1); + inst->o_toggle = edje_object_add(gc->evas); + e_theme_edje_object_set(inst->o_toggle, + "base/theme/modules/conf2", + "e/modules/conf2/main"); + + inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->o_toggle); + inst->gcc->data = inst; + + edje_object_signal_callback_add(inst->o_toggle, "e,action,conf2", "", + _cb_action_conf, inst); + + instances = eina_list_append(instances, inst); + e_gadcon_client_util_menu_attach(inst->gcc); + + return inst->gcc; +} + +static void +_gc_shutdown(E_Gadcon_Client *gcc) +{ + Instance *inst; + + if (!(inst = gcc->data)) return; + instances = eina_list_remove(instances, inst); + if (inst->o_toggle) evas_object_del(inst->o_toggle); + E_FREE(inst); +} + +static void +_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED) +{ + Evas_Coord mw, mh; + + edje_object_size_min_get(gcc->o_base, &mw, &mh); + if ((mw < 1) || (mh < 1)) + edje_object_size_min_calc(gcc->o_base, &mw, &mh); + if (mw < 4) mw = 4; + if (mh < 4) mh = 4; + e_gadcon_client_aspect_set(gcc, mw, mh); + e_gadcon_client_min_size_set(gcc, mw, mh); +} + +static const char * +_gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED) +{ + return _("Settings"); +} + +static Evas_Object * +_gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas) +{ + Evas_Object *o; + char buf[PATH_MAX]; + + o = edje_object_add(evas); + snprintf(buf, sizeof(buf), "%s/e-module-conf.edj", + e_module_dir_get(conf_module)); + edje_object_file_set(o, buf, "icon"); + return o; +} + +static const char * +_gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED) +{ + return _gadcon_class.name; +} + +/* + static void + _cb_button_click(void *data EINA_UNUSED, void *data2 EINA_UNUSED) + { + E_Action *a; + + a = e_action_find("configuration"); + if ((a) && (a->func.go)) a->func.go(NULL, NULL); + } + */ + +static void +_cb_action_conf(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED) +{ + Instance *inst; + E_Action *a; + + if (!(inst = data)) return; + a = e_action_find("configuration"); + if ((a) && (a->func.go)) a->func.go(NULL, NULL); +} + +#if 0 +static void +_e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi EINA_UNUSED) +{ + Eina_List *l; + E_Configure_Cat *ecat; + + EINA_LIST_FOREACH(e_configure_registry, l, ecat) + { + if ((ecat->pri >= 0) && (ecat->items)) + { + E_Configure_It *eci; + Eina_List *ll; + + EINA_LIST_FOREACH(ecat->items, ll, eci) + { + char buf[1024]; + + if ((eci->pri >= 0) && (eci == data)) + { + snprintf(buf, sizeof(buf), "%s/%s", ecat->cat, eci->item); + e_configure_registry_call(buf, m->zone->container, NULL); + } + } + } + } +} + +static void +_config_pre_activate_cb(void *data, E_Menu *m) +{ + E_Configure_Cat *ecat = data; + E_Configure_It *eci; + Eina_List *l; + E_Menu_Item *mi; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + + EINA_LIST_FOREACH(ecat->items, l, eci) + { + if (eci->pri >= 0) + { + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, eci->label); + if (eci->icon) + { + if (eci->icon_file) + e_menu_item_icon_edje_set(mi, eci->icon_file, eci->icon); + else + e_util_menu_item_theme_icon_set(mi, eci->icon); + } + e_menu_item_callback_set(mi, _e_mod_run_cb, eci); + } + } +} + +static void +_config_item_activate_cb(void *data, E_Menu *m, E_Menu_Item *mi EINA_UNUSED) +{ + E_Configure_Cat *ecat = data; + e_configure_show(m->zone->container, ecat->cat); +} + +static void +_config_all_pre_activate_cb(void *data EINA_UNUSED, E_Menu *m) +{ + const Eina_List *l; + E_Configure_Cat *ecat; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + + EINA_LIST_FOREACH(e_configure_registry, l, ecat) + { + E_Menu_Item *mi; + E_Menu *sub; + + if ((ecat->pri < 0) || (!ecat->items)) continue; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, ecat->label); + if (ecat->icon) + { + if (ecat->icon_file) + e_menu_item_icon_edje_set(mi, ecat->icon_file, ecat->icon); + else + e_util_menu_item_theme_icon_set(mi, ecat->icon); + } + e_menu_item_callback_set(mi, _config_item_activate_cb, ecat); + sub = e_menu_new(); + e_menu_item_submenu_set(mi, sub); + e_object_unref(E_OBJECT(sub)); + e_menu_pre_activate_callback_set(sub, _config_pre_activate_cb, ecat); + } +} + +/* menu item add hook */ +void +e_mod_config_menu_add(void *data EINA_UNUSED, E_Menu *m) +{ + E_Menu_Item *mi; + E_Menu *sub; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + + sub = e_menu_new(); + e_menu_pre_activate_callback_set(sub, _config_all_pre_activate_cb, NULL); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("All")); + e_menu_item_submenu_set(mi, sub); + e_object_unref(E_OBJECT(sub)); +} +#endif +static void +_e_mod_action_conf_cb(E_Object *obj, const char *params) +{ + E_Zone *zone = NULL; + + if (obj) + { + if (obj->type == E_MANAGER_TYPE) + zone = e_util_zone_current_get((E_Manager *)obj); + else if (obj->type == E_CONTAINER_TYPE) + zone = e_util_zone_current_get(((E_Container *)obj)->manager); + else if (obj->type == E_ZONE_TYPE) + zone = ((E_Zone *)obj); + else + zone = e_util_zone_current_get(e_manager_current_get()); + } + if (!zone) zone = e_util_zone_current_get(e_manager_current_get()); + if ((zone) && (params)) + e_configure_registry_call(params, zone->container, params); + else if (zone) + e_conf2_show(zone->container, params); +} + +static void +_e_mod_menu_cb(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + e_conf2_show(NULL, NULL); +} + +static void +_e_mod_menu_add(void *data EINA_UNUSED, E_Menu *m) +{ + E_Menu_Item *mi; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Configuration")); + e_util_menu_item_theme_icon_set(mi, "preferences-system"); + e_menu_item_callback_set(mi, _e_mod_menu_cb, NULL); +} + +EAPI void * +e_modapi_init(E_Module *m) +{ + char buf[PATH_MAX]; + + if (!e_win_elm_available()) return NULL; + if (e_action_find("configuration")) + { + e_util_dialog_show(_("Error"), _("conf2 module cannot be loaded when conf module is already loaded!")); + return NULL; + } + conf_module = m; + + /* add module supplied action */ + act = e_action_add("configuration"); + if (act) + { + act->func.go = _e_mod_action_conf_cb; + e_action_predef_name_set(N_("Launch"), N_("Control Panel"), + "configuration", NULL, NULL, 0); + } + maug = + e_int_menus_menu_augmentation_add_sorted("config/0", _("Configuration"), + _e_mod_menu_add, NULL, NULL, NULL); + e_module_delayed_set(m, 1); + + snprintf(buf, sizeof(buf), "%s/e-module-conf2.edj", e_module_dir_get(conf_module)); + elm_theme_extension_add(NULL, buf); + + //e_configure_registry_category_add("settings", 80, _("Settings"), + //NULL, "preferences-settings"); + //e_configure_registry_item_add("settings/conf2", 110, _("Control Panel"), + //NULL, buf, e_int_config_conf2); +/* + if (conf->menu_augmentation) + { + conf->aug = + e_int_menus_menu_augmentation_add + ("config/2", e_mod_config_menu_add, NULL, NULL, NULL); + } +*/ + e_gadcon_provider_register(&_gadcon_class); + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m EINA_UNUSED) +{ + char buf[PATH_MAX]; + + e_conf2_hide(); + + snprintf(buf, sizeof(buf), "%s/e-module-conf2.edj", e_module_dir_get(conf_module)); + elm_theme_extension_del(NULL, buf); + + e_configure_registry_item_del("advanced/conf2"); + e_configure_registry_category_del("advanced"); + + e_gadcon_provider_unregister(&_gadcon_class); + + /* remove module-supplied menu additions */ + if (maug) + { + e_int_menus_menu_augmentation_del("config/0", maug); + maug = NULL; + } +/* + if (conf->aug) + { + e_int_menus_menu_augmentation_del("config/2", conf->aug); + conf->aug = NULL; + } +*/ + /* remove module-supplied action */ + if (act) + { + e_action_predef_name_del("Launch", "Control Panel"); + e_action_del("conf2"); + act = NULL; + } + conf_module = NULL; + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m EINA_UNUSED) +{ + return 1; +} diff --git a/src/modules/conf2/e_mod_main.h b/src/modules/conf2/e_mod_main.h new file mode 100644 index 000000000..40117c65e --- /dev/null +++ b/src/modules/conf2/e_mod_main.h @@ -0,0 +1,30 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +#include + +#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) + +/** + * @addtogroup Optional_Conf + * @{ + * + * @defgroup Module_Conf2 Improved Configuration Dialog + * + * Show the main configuration dialog used to access other + * configuration. + * + * @} + */ + +typedef struct Config +{ +} Config; + +EINTERN void e_conf2_show(E_Container *con, const char *params); +EINTERN void e_conf2_hide(void); + +#endif diff --git a/src/modules/conf2/images/volume_knob.png b/src/modules/conf2/images/volume_knob.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2dc8d4984f1d9dce47a73b695a92674119e62d GIT binary patch literal 16375 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 C4l4iv literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_knob_ledsoff.png b/src/modules/conf2/images/volume_knob_ledsoff.png new file mode 100644 index 0000000000000000000000000000000000000000..a721abddfa3e3ca4384731e94e36bfa670c59d32 GIT binary patch literal 4066 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 F{{co$#DM?+ literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_knob_move.png b/src/modules/conf2/images/volume_knob_move.png new file mode 100644 index 0000000000000000000000000000000000000000..c13e93ef367775837bc6c90f1479d64e97642d78 GIT binary patch literal 28115 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 E01Dr2YybcN literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_01.png b/src/modules/conf2/images/volume_led_01.png new file mode 100644 index 0000000000000000000000000000000000000000..d62ed27e1746c496c15d856494b3f69ae43f41dd GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?FfvM8d#WAGf z*4vwV^CqWD9Dn%#_4U5l2|^zOg)}BKIe2h{zPh$@?(VDJS1&RPMF(D8yZi!UA&W~# ztLEJZi5mjO+(8^norfcTB}bc+<4JqeL{XX}{uj;nXuTS6n^7iz6xxJa&>wQ1jtbOKS_v~xeS3Os`ZKrj7 z?{BSt`EI-T?XR!?o>42Gl(YP*jQ8>51yk-jYI*vp@0`TH{)PVJH%qS0IRQ$hc)_3j Yd)P$+Cb!)9zopr0EG%M761SM literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_02.png b/src/modules/conf2/images/volume_led_02.png new file mode 100644 index 0000000000000000000000000000000000000000..1b6ed351c98feec12d49f4f98655bb54854ce8bb GIT binary patch literal 757 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+KEOJeg7%wg=^9J>`2N>s7da3iJuHwg{Me9F{C#WHoulW>V0kutdYP?}1g|7GISe zPD+Z3j*SZsa7i?G7QXp<>*ft(XTeh?6LY+O+qnPOU-kTIz7Wt#x`78@*YJ7uAIQ`` zmtfeXvR9?sbJ?UEm76C|6)EfaMZM-(ckJktVEO5#hA(8E?>6~qa&qbaZf5nYS3Fab zwNCz?zWe#U9W`Iyp6@&M_}u>4{>C!B`|jx%Pf+?knaB0m6Va5?0=<*%*MI-LeLY{N z_QLzp=*y|v`^(ZlJ7=!H_x5|ct5O%*-}YT^ zJ6C0A;nTA=f2*yF4?nz=SL7JubB%YCmB!^K&uXSxf1dlzX}|g8n|{{$Q`Ux*&Rw<6 zxV~=PP3=$4lXMFWGr5CQUQYL2HlNqs(q`SIwXb{PLvC8iJnx@-ck$Z&+vLnr_j!JD ziSdbYTqW|eaQ)Q#w+}aGXTP3ZS^hEUSm@NRXY0%A>oygxwzR97kYcQT`ux$OnKcLf zf3wZ>{uKD$qC7q7>Cbb2azg#4XTQFEJ6^4F$`b|c)9s6rjQYP!-=DYtuKwqwkns8D z)#vy5PptN=^9+jSQ>%82Tjw!x$?O!flNKi(Crx|W5H7y#tspV6-5~r;e(J%g*<$}J QXMxmvy85}Sb4q9e0P%$y@c;k- literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_03.png b/src/modules/conf2/images/volume_led_03.png new file mode 100644 index 0000000000000000000000000000000000000000..6f898508a0ac907e2994a97409d28393685bba76 GIT binary patch literal 738 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+OxRSuv#&$3NbmQ#rpS%SSoWG2`Gnmsd*N>sa(1IyiRmw642dts!zGxF|v$ZvOPg)#`))Ld~@3M`On)k0xhKjcp#*+{>opL zb+c}Xax9*>+N<(CZC9}U{hh_HPtP{K{z|^| zcBZ+sh{QM^$`FqfXEvRR*+uEBx|2Oyqu1>X(OaK2v<+gkC7yi>1cijH9d)4#8 zN&7w;WSXBS3w`o^@}@sY)vM#<-zopr0P`6Z7XSbN literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_04.png b/src/modules/conf2/images/volume_led_04.png new file mode 100644 index 0000000000000000000000000000000000000000..d81eea62eb27446b2ba785db0ae1dcb2c2cef742 GIT binary patch literal 742 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?j61XL%zoi}?zO<2T_qdc-o4*G=Pl3khY$bn`{U09w3W7?#?QbB=;i@)>o`>y8j^V?RPEU9|E;-sUQS^fE6w_H@t_&J_?FA+Yu zro1-u<@2T5hi6}3$M<{s?&3_Vxl<;+*>mTeylj8HmwNx?Jp!DYO&s->p1ph2Z2!77 zb$8?UZkpq`e)i5~eqJYEoibSe{o7^(x%%o$C&Rf8xnBNx;{AO8qT+qQ-&bEsyYPCM z`TZp?LoBnsXYKM^wZu~YRfx=)C`Z4br|VZuF|wMIVl?;JkGq*}lPABC?b}@Z;n|zm z+j;U=f2y7gE;Pt?U-LMm(nRm=yF2&(O+R1F9Vw^xw7_QOyS(@NY6=ai0{oWq2S3fc zcKu#gbN92y?}46c*Zf)dQRn-sU3#ZaPyc^Us`s6G<)jqtlegEb7Y#J%7FO}(3wpYJ zv0A-a`dRzM7gwv?_Vm+be|TT`=zCRCVN3FMcVYMs zf(!O8p9~b?EbxddW?a}VAeO9%Z>i_qA_G1ECLo0BgKH$&g<+*vHo>HE#a@O?jty43e zaCYrVm9?iOR;e6TNu3n!Ic?G(uTQ$t*~irqjQoL;Zj-*HihLJ4{p_*d^1b`Em+!EV zxz4_LDw1W0jZoop^2iJ$zSrzW(ytI>CPaOEtQB!jD^8zFxlb|Kp1a zk)j-v#XM#f&YR|XQ8ztp(~Vi)%jft8imZHPwKvSzHE@Z{a$ApGY6+K^RtBXk4>Tz< zTVv#BwB~isE33m8Sf=fD!yOa2r4|6V+L@#De3{Pg{^e}0QO=e}5G z?wruw)$HwmA3pe-V3j|q#*Fd$&CtKkVtwa^bBkBrdsDjV=DFVa&5tja?_RE+Ke@(h z)7+E^DN}m4-s16zQZW8m%vfJg=~cUTPtSK&Mlz$T{;RZ}R%4{9_hAE&37)QgF6*2U FngF$F_}>5k literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_06.png b/src/modules/conf2/images/volume_led_06.png new file mode 100644 index 0000000000000000000000000000000000000000..352e669d06985bbcf931fe81df050f4a2e8c7d8d GIT binary patch literal 710 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?EaO)2jm@u-)`M#v~j~{J`W9Dk2ibSvZbZ1rG@nmXm9w)m9zDO zy3k@Jfq(?Dv@)F|62jhGrSq5DJbxmR|LNIjOHQCwGyosgYx%uhcHF;PCD`+qrbln@P3!`DWXrpJ(o?^QH%5{vO9Td=FEe=%~>U-S4`GlK6zM0fAhYm z?)m#;E4!X*OpfuJ9j$$M=hm4w4{m+<=T1SQh53uAspXH)x^1(o$=lxjX6cE)D$$S9 zi?}A8Nt<&!efFK*JNDe!S(9n`Ie71syLq=%9{+OU<8yc2xqEk5`DYi$8C#ls)OX&S z|Ehc$`{l@4b5Aa~@7<;JwPMcEosPTy#+@?zTw3Jz#V5+q&C_nnT&4D}{m)%(<(6mO zmbvPCYunk62Opl_JoUxQElqEhPkw&&;fr(Uj_dFBe=c@O`?QRy@2baEx2@w>uMgcC zTKY-jWZR3M;&Z;~Uz@t!103Mox*Y Uo}>O->pVN3FMcVYMs zf(!O8p9~b?EbxddW?h}&zH7|G^dglp4ql|-qO>5Tz7V(2B z5|ep8-@mMPM(~l+%=gWUR``nAR0M>m0xh8`DEKY<|8L9Q=CDcEuC6-wI=uHrtBV0 zMy_4IcI&OR-@fbH8`)UTpEJF3veIwQV~f(Kav5n%tE}FCweDX<`GmP^t6xreE8;q_ zYUddscm8D0QoGsvd?xa99a<&2)C%xc88knp1WrHTNT%|ZdbFayHi5dkCyye z;%Ro|+$zzO81?BZU-zVc)_IjWX-Vd!mq`xTCY4R9ob>YQpZEKoW{OiG0(QjyV+#FM VbMy0s8G<0=JYD@<);T3K0RS$m?%eVN3FMcVYMs zf(!O8p9~b?EbxddW?`0-NCn!UUS-4qwJMkXy@)A8th-lV%X zC3i<03FOZUd9&x7Vff;@=m2cyRG>&uq2OiEAd$S$k_wb?FrOzrS*$ zpB7FsPfO2ee3M&x^Zw4wv#ZVXQ+7)()t|J;|Jmu#wC(w+e+$ii#-;iz@EA@gj1`k! z{Bdi~?B1NdS0b(x_xbPoqG>++N~)#TuH4DSM;yd*udkohy*aILpV!PskJv0@x4rZ` zf4S_gQE1)FIf`sWM*7BU?P~3Q6qJ9zWPf7&&FN=O%cxr#S~~Nj+zPAwwDr`Jr>_^E qULW!FsP?rhPpA`IAX5&6ewALS8GUtKQUNIP89ZJ6T-G@yGywpX?ZZa^ literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_09.png b/src/modules/conf2/images/volume_led_09.png new file mode 100644 index 0000000000000000000000000000000000000000..a0369d616ed45de5c1355acb860a065339ed24dc GIT binary patch literal 655 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?^(gn<23fIDN zGZ!w&t?~Rd>G_gf3@;B%df#llv-y8JbNg(dH57vn`d!-9FQ2~7n)AwHNIrCYha_WSbJky<#Gj`D9351Q*={jK8-U6Dp{{J zSwypI$>p^{>vU8Pzx*ZokMsI6h4jr&5{zu_u6teB_BH5N=*&fzPv)4NezC{Tc-|7- zPo^hZf(vqf4xwp8tEe=k-aI(0eM9U2|J^ zD`sZZ0*Eem=Y+_lHwNX(kza7HuW!2ieQ>$X;|dRe&ZD@e-I L)z4*}Q$iB}Q%UfN literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_10.png b/src/modules/conf2/images/volume_led_10.png new file mode 100644 index 0000000000000000000000000000000000000000..867600416d4b9f5fcfd8ef17efa1c2c6dca6e7eb GIT binary patch literal 705 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?;b6j<*Wfp&{&@p?m#ZN|~on_xQ@37=_V*hSs`BU&nq=2Z- zKC@d{lbX-^3+_pL!Fw-3l%= zzR!B|UZhu%<;hl+&`Iw-tvq*micQi{l}ufISJZa7qvhkuaO0DQr+U7db34LbZ}Pbe zi;At)6+e_tKA-&6@V0ex&er3P((AZ3?G5%XdYv=1TKjeOSLxZ|mo-jr4GfLlZzgsB zz04n}J++_rU0%IPedW`So{NDI)(} z?T?zJufECgWL2(Hn8UVJ@?4Zp(Z(4*mvv72bT3(RbyLK&$h<4TBCfAapWXj`p6W&8 zd{#-7N=vCewdTcj-**3fBmcG7LgHCQ$(-hQfvYYS9&@czwG^=ZTz2Hu(rL@>yK2_f z-_Dl*Qe_?xkREt@Et^|GXsT+04hH%a6Xf@Axm~TD0f2&(F)>AN4+c zdb{=ChtD>wy0>(iyJuYb>e$ZtKebQn_YStcxwcCs`6<~kf>&e1%pbh`eC;QclQbGY O3O!x@T-G@yGywqri~(@~ literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_11.png b/src/modules/conf2/images/volume_led_11.png new file mode 100644 index 0000000000000000000000000000000000000000..8db2b3ae01c71ebcd22e75a2c62adba644fa7663 GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?jTr`=f~x2jwBon6H(T7$~(aw@Ik0qLqNo5YWs=PDZ5&-GBN}fdA!== zI7@}8apFeXZ!>=G+-L5Zkr8xs(#4wjCAWg#EM2;JDaZ+AfDcP0duL1bMzb;gkDXHH z_PDh9f%oMdTbxvOdw!cN;u%+OwcInxGfk3D>+$ndyVrb8R}Zb*Q#mp5`Rad*F2A2U zywTrLMp8j<5 z-p!xg^ZEJg=g809Q)B-7NARTklV!RaSFft%EMK?$+}*E>Zrs_ibLQRk`6<7DZLQgS z^ZeVnYrlQp{=Mwl?(F{Sr~drOWNn@rwei-<&CypwtM2+qd0L%K+vPgZFL244Raf4I z?eff@mebh~TJ88O^U2jc>(oC#HEO@yZ)r6@)ha$EGVV!*mG>&E&u-@?&FN@Zz2?XL z{F-lD&OCVd+SPb}*yf)PUp}cx-xN`HYKd{I&gbv(?~DF?t5sVWzjR{!r#CNMcw$0( zy?0ldLM0qt@jq3LV$=c7pVHy85}Sb4q9e E0PG4R2mk;8 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_12.png b/src/modules/conf2/images/volume_led_12.png new file mode 100644 index 0000000000000000000000000000000000000000..232167f14e67323898d62483ecadc45aee99e835 GIT binary patch literal 738 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?lR^PU`q0IaSW-r z_4dZjykJKO)(6G8$0Oeev^yv`HZVB4I=VKq_&2n8TXnlHT(oeB8Y{1mhLDGdNQj9I zV^dQs=j{!8ckzs=+K|NM|ynflbN z>yGcINEM#T9j4Q?o(GAzrWe@=pPjg6mhwxVo~IvDw2LoK{+hPd?Eby8UscqP9NZw9 zqU}0wYO~}16<0U^O4hdDc6v&)*4L918T5t!rL=_LEnaelJzm zzhD1Gf9<-br=#q(rDs>}{$qMudiKpVPb(*>78=C#f7yGyYGR7j$)AVUe!F_^%)irX zKVCf7F226IE^^&^^CI1ohrjHat(5qKYg71?s7bY+=a!vXnlynsRJT9qNnO?5)Ix(h ztT(m2Y)@uP3Y)a{&#y;ok1&!FNo1-0u>Ut_USEsX*Tp}(K?Zob`njxgN@xNAnrRdW literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_13.png b/src/modules/conf2/images/volume_led_13.png new file mode 100644 index 0000000000000000000000000000000000000000..727878125d349746c63ece235529728dc95bd4b2 GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?aSW-r z_4elZtdMe3nFRN8%Z^Of^aM%E>8eCk^I)JEG!Ku5dR_`DE6yozqhEQ|tUcl}~b<^ta@e z@@9j%jV0BolZuaOY!^Sa)8u;2l8t+I+h1?W1&R`w{D-lRHJ-UW#-yd zGHc~e7HyvQ`19E)(>uF^dWwuaPuuuJEBu!a`I%b(?nM0Gx8{q*n-k;Szj>Bm;uk1V zxzW@ka<=EB$jb(`jU~65Rrt-?o9F+l`SRp?{k(s_YyLjH_T=U@h5xyGPJK?7zA5?c zo&Tvj-kUPz_--fObv&i=Rpohf@3XC~*FIf+`}LoA^V+vLAv@-xwq1q)a_0M4?JxPBIBOWckDsD-Qep15eVIf?6Q#-?2v>7g`nB{r Sz0o)gGRxD|&t;ucLK6TDsw!## literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_14.png b/src/modules/conf2/images/volume_led_14.png new file mode 100644 index 0000000000000000000000000000000000000000..167253f0f25234c9a5bcd67ee18062e611fdef9c GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+SXZdBN!n#~yy4GkJza=iH79DpTBCrZyZ3P*i#LPBLK6hLVj{oVhPAZ1uj{DA~C% z(n^H0h;?tbS8HQghKSO?771Zt^^N}QZC#C`N?3R6M>3KZ)%FaNZ&)KhPWCMUU^Ey(&uac=2 zIa~JGxtWWiqBGC_-?3}Mhv-S`Cz)*CcymJM$3I7_s;gsWOFa8mw7Rq|FH=$6F8b7i ziW&9W=D)MOb?e_sJG-h0Pdu&OHpcYa<_%hMZs|1*?cQf4dTZ-u9o>0z&fM8&pI$Bg ze0_b)pPz4XK9^0>-@MUMSzP|s5qG=&ewU=hEa&8(^YQf$$()kv=Nr0ml~JgXY`UJu>p`6>;Db*J=HTBdgpYrwLTVBQZ zZc-6{{N3aImfxC1-#_k;HveDsGu8it7D(;7WrvA_nY=fiSvzr?5A8_sdjDk z;)nc`7w@VJcsgBV=kyfyxn;VNk8LMxSI$)VX>&4V(p#0?#~2C65cO1isQb^TJ*D&e T;w#0VRLtP%>gTe~DWM4fVN3FMcVYMs zf(!O8p9~b?EbxddW?@4@}x!5tmX-$`fm`n}3UQzdF-lpQ)x?e=6Txz=T_nxEJ z!J{{~Hb0nf?b^{>hq)f^aq%rWU)tdv@9_3ut=(hezYkAOf6qUU1!yN;(C|OfaI?Pj zn{AWUsPCMVqIfdjv+d>gzN5#UUz&BXNW@bwbr$<+^~x)@=N^kZE%)4Jd?Qvs`g81r z6w}LhUi)pj9Q$@%+?`z^^`)P0{ax$#yj{iI=*C*t*qf^ z_O#c;H@HlEwe`_^^3UVmy|15q@ZDw=_Ltw6C8gXGTe52T%aG8i*|VQ-+7ywRn`t;( zd+wuGU*AT@uUXGO>5kW>pCx?`E-Ero8X!*+*8JC`7p-!y015}!++MZ0ZJo>Q@$HSMR} z$;)4=e=DWz<1UJt)T(mY^IYApPilYfE&TD|zBd!zNTGqG!R~*IpYGMOAKR2|0W#jx L)z4*}Q$iB}kG?XG literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_16.png b/src/modules/conf2/images/volume_led_16.png new file mode 100644 index 0000000000000000000000000000000000000000..1d86e3db503cdff3fe62738f6212b22736118331 GIT binary patch literal 716 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+SX3eP5 zn(HAAcB3%Opw<5C&QF{heQAw<$}YQ!*Umhvd$@?2>`vZ4k!Qs literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_17.png b/src/modules/conf2/images/volume_led_17.png new file mode 100644 index 0000000000000000000000000000000000000000..3e5077bf0857c2cf00cb004aeb3e0abac65f6fe7 GIT binary patch literal 753 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW??UQ4C>kU-%)V3=8er&XV`?+nawZ)$o z?Yryq{7lKNxoLX3U)G(Sn^`x1$?Sg%)QZ$rD;)pcKUZXDeD)Rjcm1n++(KWaPAp5- zx?8q+&xP6Xerx~5PMUUN=9(rQ{octTo?-L$)zv;edF*uky*F>uD-66QnPjD|dU&wp z?S@?wQ|^f*e(H-jt{=kgSr;35`$u7I_U{i@&&6#k`?hJJ^MfYxOu++|F7ylx8=1X>o-mNzI*rkwyk$OHz^kRJ^J$3>^pnvq@#;Y z?Y(9ZzgK_rB%|`ledMB?PKe=(W47MntkJ$fWd4{@u6U<}{ R)?|Qe^mO%eS?83{1OS)jA>;r6 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_18.png b/src/modules/conf2/images/volume_led_18.png new file mode 100644 index 0000000000000000000000000000000000000000..f49645e26e014f237b68de17143a7d3306210e62 GIT binary patch literal 752 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+Ox*Sux=ftPf1ZGfgI~@etf~L+xOj1CvrF&pIYW&C4r;JeDf8**F}~e{hUHam}q` zD~hL@d#qv!(GZv@=+S%Z+Ko#wrs+W*#}azv4?O>U>Tssnnxp^z&jnhF3FH@gW%}*f z9PPVlLdw%urwg~4pLc2CUpZ}wOs`6O>ZEw>$2P0`KbxG~e)HyBF~(E1%`wv+zZR+7 z5fZX*_RQI9eccYnm@NBm^>Xh2IVt+LXA1{DsC}hs@i?aI&hL^r@?v@GQgd@HPhU?f zF1mI%^X!_rGi~3VT4U+?>!1F5wDnFz)QZ}TyFNuv%HOm( zTAcM%_=LH4y(ZCuUE2^S}C1UBQ)iJ$=^cKX;eT*;^m=a(~ra zmGzT+_N0AWXQaFQaF6~xdAUE^uUg61%#YGNe6Zlg%BSB$K5LxJE_@LCR7z7Xe)YSM zV>|6vrcBD3r}oqMWa2h+_D2poxr-tvtyDSf*`*?T6f-vHD5A0QKOp=fS?83{1OVxU8|VN4 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_19.png b/src/modules/conf2/images/volume_led_19.png new file mode 100644 index 0000000000000000000000000000000000000000..6796baa122f5b420bdfdc64ca6195dc8237a06bd GIT binary patch literal 733 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?Q0i(^Q| zt+zM#=1oqQV0-X;^IUoLJ|T5Rr^^eoTtgd=9O-B|a;CvtMNFPaJ6d%bpX}|0(aYAw z-DW;GIh2g4a90+Em?V0osWQe#{q9+OgsC zYSm1&NS{xdCk^hN^D(%3EubfEVv6ZWbIoG))VyUU^18lEl93RUUh<0drq9gZy^;H3 zeK*csbRxyR$*O%>zMubkWmlF~7TacPd#}8jeY!oLPwp-6 zuX+_ruSE)6L6M)gF4EY(ZTqLM;^CL0X88Yqyqw4VakS)@_12qLtyOEXiN7CFTlMl( z)ikkZm*(WBtlc@`yx#il+onbHPg;|@++1Cab>*tV;p)rn=hjKgoA1BObJ9*XTW#** z%=|6yRd-HvaTHmyXxCh$%`e|w{P+8M^F@oppFPu3XS%JO_UuuTwd>z?!6A;T-hJ)< z_mSUSJ^k{*f+^+Am;dZ6pRqSxzdOlj@7$D^kLI^@eLVBKf9}2B^Ve_fzt)|!TW9je zf+?FHZm17C|5)Uw<=u0g6ILC6`CbP0l+XkK@zNB` literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_20.png b/src/modules/conf2/images/volume_led_20.png new file mode 100644 index 0000000000000000000000000000000000000000..d9d9610439acf7af5c584a015cdcbdbda6331feb GIT binary patch literal 716 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+OxbdC{c|#~yyap?-sZ8Y5k-*clefxopMOK>ZkUzDs|HG zxnb3|=H@HAYfQC1yH@>`=Q-k#c6agF*)===IBt)*7jgcPle+KS68`?a`8>z3p5K05 zmnS8y_qMk8*LUyyc7A@C7Ueo|a(CgX&lev*-0{ooWWLbdcwNqSB^z$U{$0L%+oYrC zV#1zVN5;=Mf9u+@vPtcpQk^_0(|Faz#qY z>DdP<+9%swVN3FMcVYMs zf(!O8p9~b?EbxddW?m)HSFu8iVIEGZ* zdV9;)Pnc2W*u(M{KAKw{LO7&McNrO~t-Jg381n6ZW_l1Zsy## zD;=H(YaX20e$lhY_~hO*pA1fhb?xz;IQ{0`-xE?SI~yfV9NIN8a^5=g$}2B*!ax7i zx%{i-_X;0-*SL%vh3E?aazpu4wXYW-x**`h3&!6qPkwlJ~rP!-KQIj68EM)dd zUR(aT>Q;)??9_Qnv`$~!n)iL5@iprci?lEKeDD9Y|JB#2PtSc^;a6{P=DI(-rOegx zNn0jgF_Ju?Wd3K<|9^)c_WxafeKogsrrL7Jzi*c3Jq?~VCxUI$4K+`@@9LA&zvg^W zQCDBP%cDN-S!kEd_b(RjpEIU!-+kR{)66GTll=bG-1VN3FMcVYMs zf(!O8p9~b?EbxddW?+LP;JmElw)`!Km!nZpQbcx1svVO^Fn%6a}tx5O7X3i?BQz9WE9kC4)7zA0E)@XP+ z3E3OXTiBr6p!BEK+amnGM|imq&;~eY`0rwP(EdYCx$a4elT%fiRoXq(JkNdlP?x@- zd$rlY`2J+ulXJIJhU~htcG79zleeeX_?}#?a@ca%xU}l-8;28HvIwL zrc0}~oIZTAzd3bx#;c&OMzha;etTLabGLTAUC`Q@ESq*Us@%7)zhQ0t;=B9RV+Ln) z=G`o@^PlTKFN<~4t63`V{Z`r7*~Z(PxR`Wf>YJtKx~J^%+hj7)AVN3FMcVYMs zf(!O8p9~b?EbxddW?S4@g*Y;>J}9n_F^?4LXr18JyU}3k+VvBIETQ|?an8Z&-nQ_C&Krg-?Gp? zQ5Q!KxBUD2Pj@%}eZ%wW&&=|lA3qt)x2u=zbaV7DTJySx&3}{eir{4@Hk6snULbNX zZADi~q>5``O5~br8XVc(Do2eX^};_psc<<>>OO7cnU*^}?cTDP=P#eRedgA?`L%l- zw}nnzvUA_BStmC)U)g=QmdKI;Vst0Jl!nf&c&j literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_24.png b/src/modules/conf2/images/volume_led_24.png new file mode 100644 index 0000000000000000000000000000000000000000..ef349ce4a3ff618287674187a4e4ff63ca1913de GIT binary patch literal 692 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?YTdde*|+A%&bPC8 zwdv~D&pIc~J9$#(t@QlZrrb@Yva~m&%b51d6!@4b<6dy z-z}I`>v5^$NvG-gt}SCHFlO3YgV01 z3E*STJh$wp@oe9qXVpUNyBg1Yw+VXk)^p}^_06w514F-0_Ssz*r&>Av?MC%$OY8RS zmdKI;Vst0Ekri A_W%F@ literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_25.png b/src/modules/conf2/images/volume_led_25.png new file mode 100644 index 0000000000000000000000000000000000000000..e7509cbddf8b9df5a90cb5dbde5cc61ae0bbc770 GIT binary patch literal 726 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?#WAGf z*4yj$c_Qfy#~zlarCl4bHcq#uN;|?~_TCMvB*cUV? zFDT*AoW$x>R$#UHcJybdxz;U;l>)-Kp5C z5_-$#*RFG)&qb}*Ijwa0iWUYA}5s_NuF4xH96-kui5-J@83;({r79kS#inv z^Gav$|5sNLn0DV`o%r zg7#{^O~yBF$>gjpz5Kp3SbzGQWRF_{GDC*|9M6=&XU@DI^lY)q_5aL;pVvo)PFg?d&d=}G nzMt$CKU`^n2=swt{r}1H)2l=4{{OwpK#uTq^>bP0l+XkK$O0G9 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_26.png b/src/modules/conf2/images/volume_led_26.png new file mode 100644 index 0000000000000000000000000000000000000000..66d78501170a311084f66042a7e64a8d5e258057 GIT binary patch literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?|^J5xiEV|SiM9`f|N_r8V`XbCd-6Q|fT?M6+Iiss}w9z}DOoH|yeJj4EV z*8sT42mj3N&Q5Q?yJ@z(dnn(&{_s<8@BX%)YZE5Gn)&;y#r|Cz3Vwe& zYHYdHz~ipTPm5b8S9^x07G<>mb984}Tafzm%SmqSzj4#5QrVt%@=O;umeA{+oby-e zgNBFp)X%B!f4wSLdH?mfr5as6udOD(H2He);AfThf73KQX0M$a9k(y~Txr)LjiQ+A zEBlt;ylK5=+qduY)hq=j@?LuOcjLFzEw#JuzhA!dN=oX!`FlO5Ufe$Su1fx-D@{QY zwq;Fv6Y6U#Rr{kR>;DJ$St>Kn8qJfj{k-Rw_2W1H_bYjOu3LJpxo)oX-4p}gWA1nF zcz;roejTi+>2cfpl6R5X$)zgYp4%qxIeYBayaMDf9vJoy@xLq%_gkLz^Z&jCa)GC- KpUXO@geCxiQv@*p literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_27.png b/src/modules/conf2/images/volume_led_27.png new file mode 100644 index 0000000000000000000000000000000000000000..3881283c521bc88db725433e5293db42744a09a7 GIT binary patch literal 721 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?sxB0a`dC6;`bJxz@`^B!_a+~qZz1EtaV;nO!tDStg zbL!L0$HS*>GI){x>2tW*uf1>b_GC?3cKum_)jjvs*HM+{_<3% zru_C>NXm3)yFvwVT&V$;R-9`Hg?on>X*??*F;1*#6}4ZR{@A z%a4~#%IkV}bmqY?NjG0E$(!}(&ic)NABUUS*Hz8lRWILHLS6jcoUf*Pu0)0(^Q=G4s&S-)-HJ?~HJ-ZK8w$oVcZ(|dCE=Fq(JyyUSaLJixPk!I~`tt5xVN3FMcVYMs zf(!O8p9~b?EbxddW?JD=!fB((3kq-4!Q= zoc5%1-}F{==4ut=@s&!x`N>_?^4r8+5>_`q>cn0zJNDi3{n^83X9F$81i>o|nAW9c zS6h1iew1x~vT)bjk6Yw-e|f&s&El2kz7?UBF(H+cJnKA)%%gAfO1DJvyU%>`So-Wy z_pO)9=Zk&*+Vf8~g#GE0%2R)4JW1U(_j0Cf-C5oTwzFJw|NVPwz5V@KebdXJB8y($We=B~VH@8fp(vr6z? z=MsT+n=a+))_uR|R$aUFrpIc#`B9O}b_V#reimh)I!{e9C40AkKw56Kj>^wJhrj(Y z_de@(amM=8NuF-+&s~=9Irca1ed471lR{pWsWBZ|lbJdvpa1@sX>H5XSFS2#Tb^zy z(YI;y=U-p%75vaR8Mte1)~xmg%>^?(CpBNZSQz(r&|4ZBnnw z{M0$?yFI&3#?*O!%HB1%n6dGH^QNMUk>Ar)WiX?Hej*2^{N`V@AMpSH literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_29.png b/src/modules/conf2/images/volume_led_29.png new file mode 100644 index 0000000000000000000000000000000000000000..259c70f16b151bc64fecd3a139ddb730ed9d9f5e GIT binary patch literal 764 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?)V2R7c?> zqr}V^5>Z_&D_ItD`9~EZM;C;LxOU-uV907kB2LtG;K>2(%O%Xz)MK8||8R zM~g2ivi002#zPmqKgCWen{?dspVy|T|BCkB_s)Ky_g=Ek?^VnU{o?AnS+iZIPF1m2 zkF?+rUb^z|9(Ri<&$>TpFRy%EFD|~zwR)N9>|^0yD?S}wazbA7lg0M%WxsbGnWne- zc!9~}Irf)d$J&vtoSpyO zbbG{}-SKs6PbvMsZhiTE`L^S4#b@hpww-zHwg3G4Kl5#NO-tEuU;TJ=-o_i literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_30.png b/src/modules/conf2/images/volume_led_30.png new file mode 100644 index 0000000000000000000000000000000000000000..67f1ad49a2a26f5cb34f508372236e0e54d9b7ad GIT binary patch literal 740 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?-A+8h)$d|Wy&M5uzL*3LD#)19FkVqguc3>w9GFjcY0ZR@{4mU z&f;b&Dr#m9icTv%q^7F$IeW>>zsnfsq;&P{^Ue3Z*!=(P_5Hdk&`zA-gZ=daR+-tm zzjvv4d+Mo3s#Q)+vEKVGC8{rAhSG6~<3D{q{e2nuFXL+E1kZh*pKi9N2QM`8>{IO1 zI(g_&&gmN36z1_d!`~vHfr`l&MbIM#MGc((qFF0kdT<`uY8JT(a?#Mk+ zn7k+Mc0}aeTfg*9UjDM{aHiEH`Bs^)dPeh~WQ9JTzO!)Oi|M`3HP!4@DyPJKpPy;n z=U~z2am#a`Pm$Tlc+a?H*YB1a;*1JfN*t)axj*q@&#P;z+NOc*@pScbS?83{1OS$= B8J_?E literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_31.png b/src/modules/conf2/images/volume_led_31.png new file mode 100644 index 0000000000000000000000000000000000000000..0e089e62ccba02f9a0007d263ecf28b92b4a1924 GIT binary patch literal 751 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?*x}WWAR!gq`zkBgc~;`X0J`&c5bQwv(sDwX&#S`jgs1> zCxTXHtJ^Ux0IG4?;`w-jgt|kHeEG@n0}?f{mo0DW-u-2JX|XyZ&{DkMhtb;nny)*1 zqHc&O_bsmba@D8E@MPko{gZRjbGJ%uFU&SO#_`yqtVBb9xkmonH&6TB?Dwb7ke@u~ z^si$#WN!p-JJ#`Nh3ZVdO`A;2%c~P#{@J?y?cGhk%l60ZySaO3_%j99I?qkY0&2Q_ zN}kFmmp=XZv-wP@qGPe<(s^1#-={XCk@L5)Gh`^ihdVAud{7m-WiYrpQ&5Fu!r)ohxX04 zDZHWkS>Yr%&>%6X=ET)|Z~BFXO7gT@{ZlpZ|aIRO{uJysK<(-+5`vseEul)3AyxOn3}!}(9V3{UhL&3rd~ z=j11Wlg{lprYPVhd(vl8>*D=;Rqht{G25l;@TKF885&6Lv-!`g-#g{po=KA)fQbP0l+XkK^P(be literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_32.png b/src/modules/conf2/images/volume_led_32.png new file mode 100644 index 0000000000000000000000000000000000000000..b6dbe0485d18472f18a13ea7ef857248be1bd5fe GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+Q{hSuv>+Y!AMlvCPbwt(JRB#3y&-TPNDU307jqE7hTdCj^bq>52j zWc`6q$AIv>DYLu|hRvBZGsQ@K@*K<9lHeDIo=Tqh9CPsa|Bs()|NmD9T1yxlNc#D& zZexb3=&nOeEsLiw@hP%8*{L#F<+tRQ+j^&8z2xB*>U*kUe(71+#V5PB{4_b~c0G9M zC0Q{Anbn?lHNXG-Tt7Rqc(L5uX_uG%%vgU)-1D8PWb{UhzK0rY`ETB3yzkGRGrK+OJe3q=w8OjA?&syi{CIHcS5#r%)0BG=t1g|pJ!jRa zIkuZ8B~FaI)wBCfam=NcrdPmc5anylBY^R?5j zrYze^f79h_oBR3Izka&+#$fSF$Gv}#f4i&x_~Kj@`_v2eFLwC|x2$`!>;!*xs-LW{ zTJ--vJNMt#nR!m&8|#1ny9AY b!T&uB{>}4}r|(}e0c5DBtDnm{r-UW|gI_UO literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_33.png b/src/modules/conf2/images/volume_led_33.png new file mode 100644 index 0000000000000000000000000000000000000000..096d13a5add2cb5fa9ef059ee1096e460096964b GIT binary patch literal 752 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?7a=az^1TfC2Oe!& z%KDLwYn@kkYm!-$##E0>D$8b_IWzlA$}!iyZ7(m_oEQCL@w~>O9pn;X!H4>=2qv*> z&Fx>mrYh~id#}^M;(elsr<7;dq@1)_`jbt9Pybb^Uv^)bv*ojtyRoPC$>pop zew&-O{rA^`_YaCpC7y1Wc0Vn3pXa8jb@^8Pg|Et5Sa+FDo3uu}_t@M1>(}=E&Pe|I z>Q&J0u-uv%%g=8QzJ2d+PQBT0CD(smpWGDYsIOI-9e!)>`}~@szt^s6PnVi*{dUXj zuRhD>%J8iU`M*cE`{9RkYtHC@=30^#A0cq}kxu#Pi!Yzwo%-|``{}tcZ%i(0ofg@g zlAEeI`J+Xuk*Cqz>j6xO3-cyM?VZ=W*s*KTi6=R;wqNz+V_W=2p8x!@wa?@y8{JpC zIrqB5ya=7H>zj@2!>*oOyZ7$(-nZP|FSpFLT<4d5KK|XC{XeST-%F|arEzlem+Gkw z7WrTXH$)p>kUIax68{OTj-`rS_s9uAu{d*-v% zD&oPX&wJMS7fq?l{}bP%A|R$a$?f0YcedU^OYhH)5Fs{_C{x#9S;;=rwa0MQ>^F8G OlRRDhT-G@yGywqF`yns@ literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_34.png b/src/modules/conf2/images/volume_led_34.png new file mode 100644 index 0000000000000000000000000000000000000000..7a3dcb90dc2c161ddd3bf5836445032157945755 GIT binary patch literal 723 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+KEOtdK+zwg=zu{p^%nJoAVAhy4QFjxh~W*ZLlby0n|o`k?9yHWq1X?(l?#8e(Bd ziXAJCtmy2V<*7D#X0`5?EgL&ro>iI^*zxU|Q@oD_XctM~hjh8T$Sj6>KKIA*($=p= znM&U$>C9H>Nw&D@T`ohvu zSX7oZCHn2AH|Ng1Il1p#idxkEcb|=1cLmR_@eEvY?x)C2RfV3}*9;`XN{uAKGN-t< zh0b03P-C_9?3JgL7H3`YR`#FFBlEInc5B_t@WWsK9sS1T_+N%cRf{Z`H96U>nGKC2c_5LZMo|&AW&B1a7tzOVN3FMcVYMs zf(!O8p9~b?EbxddW?+KEO{NQqlV-J7J^u0Y&I61&2I!>i6OlQsA2tn>3RsS{57Jm@@#k;5U@T&tH!aO`@ zcxGxia)eC!q1x#$^xNRTAwK61rJm_^OWc3Gy!cZcXcsvkUb?S~$Gz3{!1cr}MlzxI zt9w3K#9vp+RF71<=~MLf^mdO;lT*x_|GnHU6M56>xkAq;ZwY(Vo%5dbuikraZ&vc- zcPGDOyiT#neII+mAXQH7W~pPuR)=kq{``D>>sRx;qie1A|1Em?{B7L!t1DOeq`BX` zSvmLb-sa}WslPqvrCf;Lp|EDs?CkWP>3cVq{k-8=l0Cdm!(lJ*Op$=I&I=Rd6&ke-0hoU^d>8X2Q7Ij-x6xP zuKUcU95cSYXE$GLDZVsksaVN3FMcVYMs zf(!O8p9~b?EbxddW?%V(#t**$yuyUi154FzCQ4$tcxp40zt>{_9>+(2Nj%4d~s zmFJUUe2XkS=cX8++`eYL@4usgy;;SptXzvUPp(xlpLA!()?L3=R4@C!z?W@*T}~OH5_@&XV-r{@v+Kcr_;9U-kk62&$he$amo4VX|8^Nm_S@CV_up6jIWa~1WSCdkWS>p@w*3%i|Hb~W zVN3FMcVYMs zf(!O8p9~b?EbxddW?+wS?UG$Xw5Mabvh2OIOP3m%+*Xw3<iQ}ZRD%!92-a8x@c~ATFxo`cG z@87-nV*HW#!AlGs9!Nerb=!AW73T)ztzVmxojYOe)u}mrzi!@$IsfUE zg6rhvp4ZmjI>YvGm*!-iTc^DzS{tuI9}9STQN9Vp3(%j3+J*5hnYCQtFM?&6BOO+;#D_{_>Tt zf9{y&x7yQGn%8~u{I7qaFQ2-t;tmXnl|fJLZa8!LVaAUauYdEid%Ag^)61Sy)>pjI z(Jegp*_qQ{H*b%B^5{T_%F4~VgQY>qh??L7e?3E;ZLPohy!huJb3I-CT-G@yGywn> CECgZz literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_38.png b/src/modules/conf2/images/volume_led_38.png new file mode 100644 index 0000000000000000000000000000000000000000..9960ad017d7d5b1a45224321082647c4bdbac081 GIT binary patch literal 600 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?F! zZ*SOUPfiqJd+__O$1JlbL6-}TUau1lUX`D;amSP8rG@YI7YMdDDRl52UAkq#rCZB< zXYEtKuc9eWvfG;DziWoRHuKKdJ@5J5w7|FfsyUQuT9t>dxme3>`FYcvZ~S7Lt!1`IQ7-`hpUvOpmmn<4ygdvQBc85)F6*2UngFLh B%~JpX literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_39.png b/src/modules/conf2/images/volume_led_39.png new file mode 100644 index 0000000000000000000000000000000000000000..a98e37b412d921d3363f4372f99406313fa60e38 GIT binary patch literal 673 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+KEytl&V2V-LSSTbB9jxR~pdrT|eE*uR3$ypcKm+d=mI2Q4{)_D~i4`LCt@AgJo=w#|E{%Gl^KHGVc& zrBba~Ips;*Dj9W2wV5hE_uAM`nxi5aXEJYHZ}G`5!JjI&pX`3SdiUSm-`}TP)VuXE z$L_!JT(iaTk6%t-zx=qb`uX6eca7v4HyD)#e_FDC}+KgcU6)bq05r)o3*TV}aNQTyCk4tYsV@r&zE-`swm z?eN=oRqJoRzqZmU)JxOS*7Ed|=LSp9{Z>h5O1#<={PgUO+5YYB?$tmXo|ltn7qR;F z-+NK{|KD6+A$RrX9KSdVN3FMcVYMs zf(!O8p9~b?EbxddW?};uunK z>+Q{rS;2`C#~=PbY3X@6Bl`BD8wu>OB_$vDSiU!iPdIw^sAKwi$2|=C4j=erSlGkG z=Wbnb_0l5G*;_21S*(~nTWN~TdEPxAKK*T*uFnXxi3Z@`O7-(y|4mnI$n}eqnX9sT z|Gjq_Cp{;nSj^yVaqVC1Rb=}4POR2x?Y-|V&2Bz)0mW=f(A92K%E*~*TY~1_@wg<)(VaF+W%FXsS<6m7Ntxysx=g1o zj%)HRzsp*ao;Xi>TyGelFh|Y$a+qBIvdh-*%f6c*f31BtZ@1TS9plxnWomAnE-A9{ zw$`5{V|6L=h;yx_r~S#TTTZ=wYrJ>%+`R9(jdK@sig>gTe~DWM4f DI1>Op literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_41.png b/src/modules/conf2/images/volume_led_41.png new file mode 100644 index 0000000000000000000000000000000000000000..d67371f97493ba218d01261e7641254456720d7c GIT binary patch literal 702 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?5FN)7%v8lZm(13O5#9d%Qw*XDr|6oJ~Pz^mSr>TzmaCw}kKa`bjlDpDf>AYjm(! z-Kg_i#a};l(bf&Srd-{6REFPw)8E?f$KUyV&raXI{i5xg{XU=6Jk{S`d$Gk$eA{`6 zh?V_C>8~EegoWv)ue6*zb?4`uTdS597XSU#`*d}-+%M{w^i1{l@pcxFXiQO zwrrO3nz&?Uis{LqNsm?DPtI9-S1Lm2PuEd(;XhATGm#Zz|EJFnyjWDqQ2NCUq~Fuk K&t;ucLK6Uag#RZ1 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_42.png b/src/modules/conf2/images/volume_led_42.png new file mode 100644 index 0000000000000000000000000000000000000000..54346861a8092df08ad58a6865a31cf58d8f6c35 GIT binary patch literal 730 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?cY8Af15=czi(^Q| zt+zLgB=YboZQ@v&I-K;d%2vubQCfe8K>&)VG=)BUGP%Li|etU z>o$RcOS85deBhw6q$f?yc=7K)^|Nvu`yN%!6it1iRK5FZyVSyGB0COW3wnAxY2M$E%2`hWCry1Lf90-%&abx@ zeLtO5H?O>zYgRpbetziY&!;bD6#Tk;G3S@n$=fRKH*e47=IEA~@OH}2#J!iR_te!Z z^P62S3Z6DIChqx%3Ipl+Jav`!a{E0#Wlwti=IylYhHi&F3*2+JoUXa}YTM?YH&t{a#%rHOX8p7~>B62kF~)q7Ti24n_33e8nOC|>qI$nr zduy&TS{t=@dWyQIw`cmrJ+rTUz8f0(uhQaAb)C`7)RMA^pI6VG6C0myV(A?i8rrqT zx2Q1Mxgx1Byf^sC)rT2Bp1s)qGW@poU-i|}tG`dLzWc1e;M|WVCYx8;_)VNYd5-o= zovg@w^-Q&$)1N#H+yB4BVor_a{PW$Jw&#PN9DnnckEO+x-|O*xuMHDZj8FPbxVN3FMcVYMs zf(!O8p9~b?EbxddW?+OyGS+m1sjz4_A+J0J!_dj*Zyt~&fOjzRi;!@8-ffEyQSSK#LtL62=wIpYG-rE?C zHlN0Zlcgyc9Et)Q3ojg98_3hEb9<9&YC+zDZowaw>mD4pd|rHSI>;q-0Vlf!Sk)GO#Us;cX^e{nJF`t%!&K{V9l{rHzd1NmSVs`)e?3Mg5ankIYxAM4JKEKE)Dw=flSSe#!tW%8CucTT8$ zpLAyV6#Gdw-s`Quur^)}@RE00sUo@Ly6q+n;-mJ%{ypqU4HffO&u&-`(&g#u=d#Wz Gp$P!W`y@F4 literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_44.png b/src/modules/conf2/images/volume_led_44.png new file mode 100644 index 0000000000000000000000000000000000000000..238a6f4750e48e49ba9220a4abae2f7fdeb1ee4c GIT binary patch literal 751 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+Q|Gc_HBvZ5PYalB$!cj~NQLe@LJ3_K3nFjUX;5sVFONLDANojFY%JLozcIaP$)pqy-WGH;>Pqd5yzg(NNMFg=y|er-Gj;7ln(v$otVcST$A!eh~kC#IO4oT=jO`OmXx#?`5|jS78FQdZSm*DLy-yZNI2 zv8eCCGJmH%xv#<=8N1SEqs6*q!B2mcOsw7<9K2j#?~H!^<}DviKc5_IuliHzYo(jeQB+=P-DP!;k#O&A5VU( zGv}9y@#ME>O4W+Lxooe@tbDloXmNVI@6_3zcETLTFMf+t_D@gS9U3@I^ORBY+BB=T zonMyOpYy4HG&t@bytI>r855w&yg-|yd!J$rq3yLEHoH-5h0DXDGluK(V@ zUmlujU%$=h&Hj^d#`Vi4 z-k&T|+WT_$^s2RM%_sY)@2pyQy*fZf>@@rCzt=YC{FAPkB0nkT%1&`Xj>ST!A|{<) zS+qFt+3i&`+cTdOPMT}=U6CpAO5WtWNoAAjCYdkZpu<8;EGty9KbqCKSLN4XVA5k? N@O1TaS?83{1ORM@8lM0F literal 0 HcmV?d00001 diff --git a/src/modules/conf2/images/volume_led_45.png b/src/modules/conf2/images/volume_led_45.png new file mode 100644 index 0000000000000000000000000000000000000000..505cd5bb2e32226eb9378895491963a0e9b190b0 GIT binary patch literal 719 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VN3FMcVYMs zf(!O8p9~b?EbxddW?+OxRUQ-e!jz9cwZJcGbc+xk+wkZ*UF0-T9OSv}Z2ygB-bG_ZCppkK1>x64{`CO+h zD{?2!6cX(Wd**&_%KFQJCLG1F?ghp6e|9|d1X@IA@Nf4at{1agk6u(cJ}G2Uj@nJn z-Jx>NCThp^+8s5V`6MdvS!Cd|%1Ns|k8R!%QS2!3#p0FcI(f~{TLRabzJC0br~i7r zUTyU5+0CC^C#~HQT^}pJb~PsO*}*F}A~svrTZONSIrH=9&BfE7J)bAy>})>CNB)|( zlEANpmW30z7eDTenKS$3$IhxWH7QH`>P>||@BBHu@!`a1&osVd6{dyq*Q~E5Wxje+ z(zVEAtA>%8(Ujz`7w6a+mOeT2X65gfPs1iXW=a&OeG^tye(n0T`}uF)ecfh#_sw+n zm7&^_D?=~ey(ODBW#{ZCJq{8!Z?E}Hn!Z|E`t8&5)9dZ>^S;-;d6&BT^4Uw<-~Zfv z{bb$5xhnOnhZeYfvOYQc>e;imwck&RU$f@FM*RNRledcqWsv*eba*sKzNDeo)Gp#|a