Added e_configure2

This commit is contained in:
Marcel Hollerbach 2015-01-30 19:47:03 +01:00
parent 68eb5eeb5a
commit f8519aa6cd
4 changed files with 582 additions and 0 deletions

434
src/bin/e_configure2.c Normal file
View File

@ -0,0 +1,434 @@
#include "e.h"
static Eina_List *items; // list of E_Config_Panel_Item
static Evas_Object *win; // if a window is opened this one is the opened one ;)
EAPI void
e_config_panel_init()
{
/* Init standart structure of items*/
/*Init internal "config modules" )*/
e_int_config_modules_init();
}
static int
_insert_sorted_item(const void *data1, const void *data2)
{
const E_Config_Panel_Item *part1, *part2;
part1 = data1;
part2 = data2;
if (part1->priority > part2->priority)
return -1;
else
return 1;
}
EAPI void
e_config_panel_item_add(const char *path, const char *icon, const char *label, const char *help, int priority, const char *keyword)
{
E_Config_Panel_Item *it;
it = E_NEW(E_Config_Panel_Item, 1);
it->path = eina_stringshare_add(path);
it->icon = eina_stringshare_add(icon);
it->label = eina_stringshare_add(label);
it->help = eina_stringshare_add(help);
it->keywords = eina_stringshare_add(keyword);
it->priority = priority;
items = eina_list_sorted_insert(items, _insert_sorted_item, it);
}
EAPI void
e_config_panel_item_del(const char *path)
{
Eina_List *node;
E_Config_Panel_Item *it;
EINA_LIST_FOREACH(items, node, it)
{
if (!!strcmp(it->path, path)) continue;
items = eina_list_remove_list(items, node);
eina_stringshare_del(it->path);
eina_stringshare_del(it->icon);
eina_stringshare_del(it->label);
eina_stringshare_del(it->help);
eina_stringshare_del(it->keywords);
free(it);
return;
}
}
static E_Config_Panel_Item*
_item_search(const char *path)
{
Eina_List *node;
E_Config_Panel_Item *val = NULL;
EINA_LIST_FOREACH(items, node, val)
{
if (!!strcmp(val->path, path)) continue;
return val;
}
ERR("Item not found");
return NULL;
}
static int
_insert_sorted_part(const void *data1, const void *data2)
{
const E_Config_Panel_Part *part1, *part2;
part1 = data1;
part2 = data2;
if (part1->priority > part2->priority)
return -1;
else
return 1;
}
/*
* If you pass NULL as free_cb, a simple free will be called on the result of create_cb (if it isnt NULL)
*
*/
EAPI void
e_config_panel_part_add(const char *path, const char *part_name, const char *title, const char *help,
int priority, const char *keywords,
E_Config_Panel_Create_Cb create_cb,
E_Config_Panel_Apply_Cb apply_cb,
E_Config_Panel_Data_Create_Cb data_cb,
E_Config_Panel_Data_Free_Cb free_cb,
void *data)
{
E_Config_Panel_Part *part = NULL;
E_Config_Panel_Item *item = NULL;
item = _item_search(path);
if (!item)
return;
part = E_NEW(E_Config_Panel_Part, 1);
part->name = eina_stringshare_add(part_name);
part->title = eina_stringshare_add(title);
part->help = eina_stringshare_add(help);
part->keywords = eina_stringshare_add(keywords);
part->priority = priority;
part->create_func = create_cb;
part->apply_func = apply_cb;
part->data_func = data_cb;
part->free_func = free_cb;
part->data = data;
item->parts = eina_list_sorted_insert(item->parts, _insert_sorted_part, part);
}
EAPI void
e_config_panel_part_changed_set(const char *path, const char *part, Eina_Bool val)
{
E_Config_Panel_Item *item;
Eina_List *node;
E_Config_Panel_Part *ppart;
item = _item_search(path);
if (!item) return;
elm_settingspane_item_changed_set(item->item, val);
EINA_LIST_FOREACH(item->parts, node, ppart)
{
if (!!strcmp(ppart->name, part)) continue;
ppart->changed = val;
return;
}
}
EAPI void
e_config_panel_part_del(const char *path, const char *part)
{
E_Config_Panel_Item *item = NULL;
Eina_List *node;
E_Config_Panel_Part *ppart = NULL;
item = _item_search(path);
if (!item)
return;
EINA_LIST_FOREACH(item->parts, node, ppart)
{
if (!!strcmp(ppart->name, part)) continue;
item->parts = eina_list_remove_list(item->parts, node);
eina_stringshare_del(ppart->name);
eina_stringshare_del(ppart->title);
eina_stringshare_del(ppart->help);
eina_stringshare_del(ppart->keywords);
free(ppart);
}
}
static void
string_path_item_split(const char *str, char **path, const char **item)
{
int len = strlen(str);
int i = 0;
char buf[PATH_MAX];
if (len < 2)
return;
for(i = len -2 ; i > 0; i--)
{
if (str[i] == '/')
break;
}
if (i == 0)
*path = NULL;
else
{
*path = calloc(i +1, sizeof(char));
memcpy(*path, str, i);
(*path)[i] = '\0';
}
*item = str+i+1;
}
static Evas_Object*
settingswidget_part_gen(Evas_Object *par, Evas_Object *content, const char *title, const char *help)
{
Evas_Object *frame, *pane, *table, *lb, *ic, *bx;
frame = elm_frame_add(par);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_text_set(frame, title);
evas_object_show(frame);
table = elm_table_add(par);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_content_set(frame, table);
bx = elm_box_add(frame);
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_box_horizontal_set(bx, EINA_TRUE);
evas_object_show(bx);
ic = elm_icon_add(bx);
evas_object_size_hint_align_set(ic, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(ic, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_icon_standard_set(ic, "system-help");
elm_box_pack_end(bx, ic);
evas_object_show(ic);
lb = elm_label_add(bx);
elm_label_line_wrap_set(lb, ELM_WRAP_WORD);
evas_object_size_hint_align_set(lb, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_text_set(lb, help);
elm_box_pack_end(bx, lb);
evas_object_show(lb);
pane = elm_panel_add(frame);
evas_object_size_hint_align_set(pane, EVAS_HINT_FILL, 0.0);
evas_object_size_hint_weight_set(pane, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_panel_orient_set(pane, ELM_PANEL_ORIENT_TOP);
elm_panel_hidden_set(pane, EINA_TRUE);
elm_object_content_set(pane, bx);
evas_object_show(pane);
elm_table_pack(table, content, 0, 0, 1, 1);
elm_table_pack(table, pane, 0, 0, 1, 1);
return frame;
}
static Evas_Object*
content_cb(Evas_Object *par, Eo *item, void *data)
{
E_Config_Panel_Item *it;
E_Config_Panel_Part *part;
Eina_List *node;
Evas_Object *box, *res;
it = data;
box = elm_box_add(par);
evas_object_size_hint_align_set(box, 0.5, 0.0);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
EINA_LIST_FOREACH(it->parts, node, part)
{
Evas_Object *content, *result;
if (part->data_func)
part->cbdata = part->data_func(it->path, part->name, part->data);
if (part->create_func) //WTF - what does a part should do if there is nor create_func ?
part->tmp = content = part->create_func(it->path, part->name, par, part->cbdata, part->data);
evas_object_show(content);
result = settingswidget_part_gen(par, content, it->label, it->help);
elm_box_pack_end(box, result);
}
res = elm_scroller_add(par);
evas_object_size_hint_weight_set(res, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_content_set(res, box);
evas_object_show(res);
return res;
}
static void
reset_cb(void *data, Evas_Object *obj, void *event_info)
{
E_Config_Panel_Item *it = data;
elm_settingspane_item_recreate(it->item);
}
static void
apply_cb(void *data, Evas_Object *obj, void *event_info)
{
E_Config_Panel_Item *it = data;
E_Config_Panel_Part *part;
Eina_List *node;
EINA_LIST_FOREACH(it->parts, node, part)
{
part->apply_func(it->path, part->name, part->tmp, part->cbdata, part->data);
}
}
static void
settingswidget_fill(Evas_Object *obj)
{
Eina_Hash *table;
Eina_List *node;
E_Config_Panel_Item *it;
table = eina_hash_string_superfast_new(NULL);
EINA_LIST_FOREACH(items, node, it)
{
const char *file;
char *path;
Evas_Object *icon;
char buf[PATH_MAX], tmp[PATH_MAX];
string_path_item_split(it->path, &path, &file);
Elm_Settingspane_Item *item = NULL;
if (path)
{
item = eina_hash_find(table, path);
if (!item)
{
ERR("This is bad, dangling category %s", it->path);
continue;
}
}
icon = elm_icon_add(obj);
elm_icon_standard_set(icon, it->icon);
evas_object_show(icon);
it->item = item = elm_settingspane_item_append(obj, it, it->label, it->help,
icon, item);
snprintf(buf, sizeof(buf), "%s", it->keywords);
if (it->parts)
{
elm_settingspane_item_attach_panel(item, content_cb, reset_cb, apply_cb);
/* assembling the keywords from every part and every item */
{
Eina_List *node, *node2;
E_Config_Panel_Part *p;
EINA_LIST_FOREACH(it->parts, node2, p)
{
/* attach keywords */
strcpy(tmp, buf);
snprintf(buf, sizeof(buf), "%s,%s", tmp, p->keywords);
}
}
elm_settingspane_item_keywords_set(item, eina_stringshare_add(buf));
}
else
eina_hash_add(table, it->path, item);
}
}
static void
_e_config_panel_close(void *data, Evas_Object *obj, void *event)
{
Eina_List *node, *node2;
E_Config_Panel_Item *it;
E_Config_Panel_Part *p;
EINA_LIST_FOREACH(items, node, it)
{
EINA_LIST_FOREACH(it->parts, node2, p)
{
if (p->free_func)
p->free_func(it->path, p->name, p->cbdata, p->data);
else
if (p->cbdata)
free(p->cbdata);
p->cbdata = NULL;
}
}
win = NULL;
}
EAPI void
e_config_panel_show(const char *itemname)
{
Evas_Object *settings;
E_Config_Panel_Item *item;
if (win)
{
elm_win_raise(win);
elm_win_urgent_set(win, EINA_TRUE);
return;
}
win = elm_win_util_standard_add("Settings", "E - Settings");
evas_object_smart_callback_add(win, "delete,request", _e_config_panel_close, NULL);
settings = elm_settingspane_add(win);
evas_object_size_hint_weight_set(settings, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(settings, EVAS_HINT_FILL, EVAS_HINT_FILL);
settingswidget_fill(settings);
evas_object_show(settings);
elm_win_resize_object_add(win, settings);
evas_object_resize(win, 200, 200);
evas_object_show(win);
if (!itemname) return;
item = _item_search(itemname);
if (!item) return;
elm_settingspane_item_focus(item->item);
}

131
src/bin/e_configure2.h Normal file
View File

@ -0,0 +1,131 @@
#ifndef E_CONFIGURE2_H
#define E_CONFIGURE2_H
/**
* How does this work ?:
* An Item is a "voice" in the panel tree menu
* A Panel is the whole page associated with a given Item
* A Part is single "piece" of a page
*
* Example:
* Item: "Look"
* Item: "Look/Theme"
* Part: "Look/Theme" "gtk_theme"
* Part: "Look/Theme" "icon_theme"
*
* TODO: need_save callback?
*
*/
typedef Evas_Object* (*E_Config_Panel_Create_Cb)(const char *path, const char *part, Evas_Object *parent, void *cbdata, void *data);
typedef Eina_Bool (*E_Config_Panel_Apply_Cb)(const char *path, const char *part, Evas_Object *obj, void *cbdata, void *data);
typedef void* (*E_Config_Panel_Data_Create_Cb)(const char *path, const char *part, void *data);
typedef void (*E_Config_Panel_Data_Free_Cb)(const char *path,const char *part, void *cbdata, void *data);
typedef struct
{
const char *path;
const char *icon;
const char *label;
const char *help;
const char *keywords;
int priority;
Eina_List *parts;
Elm_Settingspane_Item *item; //< if the ui is opened this is a item from the settingspane
} E_Config_Panel_Item;
typedef struct
{
const char *name;
const char *title;
const char *help;
const char *keywords;
int priority;
E_Config_Panel_Create_Cb create_func;
E_Config_Panel_Apply_Cb apply_func;
E_Config_Panel_Data_Create_Cb data_func;
E_Config_Panel_Data_Free_Cb free_func;
void *data;
void *cbdata;
Eina_Bool changed;
Evas_Object *tmp;
} E_Config_Panel_Part;
/*
* Init the config panel
*/
EAPI void e_config_panel_init();
/*
* Will add a item to the configuration tree
*
* @param path
* Should be in the form:
* /someitem1/someitem2/someitem3/path
* The parent items should exists, otherwise they will not be displayed.
*
* @param icon
* Name of the icon which is displayed
*
* @param label
* Name of the item which will be displayed
*
* @param help
* The text which is displayed in the help section
*
* @param priority
* The higher the priority is the higher is the item in the list of items in a parent.
*
* @param search
* A list of eina_stringshare´s you want to add as search-key-words for the search from all items
*/
EAPI void e_config_panel_item_add(const char *path, const char *icon, const char *label, const char *help, int priority, const char *keywords);
/*
* Delete the given item
*
* @param path
* The path you have added the item
*/
EAPI void e_config_panel_item_del(const char *path);
EAPI void e_config_panel_part_add(const char *path, const char *part, const char *title, const char *help,
int priority, const char *keywords,
E_Config_Panel_Create_Cb create_cb,
E_Config_Panel_Apply_Cb apply_cb,
E_Config_Panel_Data_Create_Cb data_cb,
E_Config_Panel_Data_Free_Cb free_cb,
void *data);
/*
* Set if the part has unsaved changes (= is changed) or not
*
* @param path
* The path where to find the part
*
* @param part
* The part name of the part to change the auto changed value
*
* @param val
* The value, - EINA_FALSE = nothing changed, EINA_TRUE = something changed!!
*/
EAPI void e_config_panel_part_changed_set(const char *path, const char *part, Eina_Bool val);
/*
* Delete the given part
*
* @param path
* The path of the item you want to delete from the part
*
* @param part
* The name of the part you want to delete
*/
EAPI void e_config_panel_part_del(const char *path, const char *part);
EAPI void e_config_panel_show(const char *item); // NULL to start in the main menu
#endif

View File

@ -1117,6 +1117,12 @@ _e_e_int_menus_conf_comp_cb(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Men
e_int_config_comp(NULL, NULL);
}
static void
_e_e_int_menus_conf_cb(void *data EINA_UNUSED, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
{
e_config_panel_show(NULL);
}
static void
_e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
{
@ -1125,6 +1131,12 @@ _e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
e_menu_pre_activate_callback_set(m, NULL, NULL);
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, "Config 2");
e_util_menu_item_theme_icon_set(mi, "preferences");
e_menu_item_callback_set(mi, _e_e_int_menus_conf_cb, NULL);
l = _e_int_menus_augmentation_find("config/0");
if (l)
{

View File

@ -509,6 +509,11 @@ main(int argc, char **argv)
e_configure_init();
TS("E_Configure Init Done");
TS("E_Configure2 Init");
e_config_panel_init();
TS("E_Configure2 Init Done");
TS("E Directories Init");
/* setup directories we will be using for configurations storage etc. */
if (!_e_main_dirs_init())