1111 lines
27 KiB
C
1111 lines
27 KiB
C
/* vim: set sw=3 ts=3 sts=3 expandtab: */
|
|
#include "ecdb.h"
|
|
|
|
static void
|
|
_widget_focus_handle(void *data, Evas_Object *o)
|
|
{
|
|
static char *old_source;
|
|
const char *name;
|
|
Evas_Object *eo;
|
|
|
|
name = data;
|
|
// Some widgets aren't named (such as when in combo), so check
|
|
if (!name)
|
|
return;
|
|
|
|
if ((old_source) && (strcmp(old_source, name)))
|
|
{
|
|
eo = evas_object_name_find(ecore_evas_get(em->main_win_ee), old_source);
|
|
edje_object_signal_emit(eo, "ecdb,focus,out", "ecdb");
|
|
FREE(old_source);
|
|
old_source = strdup(name);
|
|
}
|
|
else if (!old_source)
|
|
{
|
|
old_source = strdup(name);
|
|
}
|
|
|
|
// Send focus to the freshly clicked widget
|
|
evas_object_focus_set(o, 1);
|
|
}
|
|
|
|
static void
|
|
_mouse_down_edje(void *data, Evas_Object *o, const char *emission,
|
|
const char *source)
|
|
{
|
|
_widget_focus_handle(data, o);
|
|
}
|
|
|
|
static void
|
|
_mouse_down_evas(void *data, Evas *e __UNUSED__, Evas_Object *eo,
|
|
void *ev_data __UNUSED__)
|
|
{
|
|
_widget_focus_handle(data, eo);
|
|
}
|
|
|
|
void
|
|
ecdb_widget_focus_callback_add(Evas_Object *o, const char *name)
|
|
{
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
|
|
_mouse_down_evas, (void *)name);
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_widget_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *o;
|
|
int x, y, w, h;
|
|
|
|
o = edje_object_add(evas_object_evas_get(parent));
|
|
if (!o)
|
|
{
|
|
printf("ecdb_widget_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
|
|
edje_object_signal_callback_add(o, "mouse,down,*", "*",
|
|
_mouse_down_edje,
|
|
(void *)name);
|
|
|
|
if (name)
|
|
{
|
|
evas_object_name_set(o, name);
|
|
edje_object_part_geometry_get(parent, name, &x, &y, &w, &h);
|
|
evas_object_move(o, x, y);
|
|
evas_object_resize(o, w, h);
|
|
edje_object_part_swallow(parent, name, o);
|
|
}
|
|
|
|
return o;
|
|
}
|
|
|
|
/************************** BUTTON ******************************************/
|
|
|
|
void
|
|
_button_click_cb_call(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
evas_object_smart_callback_call(obj, "clicked", NULL);
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_button_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *b;
|
|
|
|
b = ecdb_widget_add(parent, name);
|
|
if (!b)
|
|
{
|
|
printf("ecdb_button_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
|
|
edje_object_file_set(b, em->theme_path, "ecdb/button");
|
|
edje_object_signal_callback_add(b, "clicked", "ecdb", _button_click_cb_call,
|
|
b);
|
|
|
|
return b;
|
|
}
|
|
|
|
void
|
|
ecdb_button_label_set(Evas_Object *b, const char *label)
|
|
{
|
|
if (!b)
|
|
{
|
|
printf("ecdb_button_label_set: NULL object!\n");
|
|
return;
|
|
}
|
|
edje_object_part_text_set(b, "ecdb.label", label);
|
|
}
|
|
|
|
void
|
|
ecdb_button_icon_set(Evas_Object *b, const char *group)
|
|
{
|
|
Evas_Object *icon;
|
|
|
|
if (!b)
|
|
{
|
|
printf("ecdb_button_icon_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
icon = ecdb_widget_add(b, "ecdb.swallow.icon");
|
|
if (!icon)
|
|
{
|
|
printf("ecdb_button_icon_set: NULL icon!\n");
|
|
return;
|
|
}
|
|
edje_object_file_set(icon, em->theme_path, group);
|
|
evas_object_show(icon);
|
|
}
|
|
|
|
const char *
|
|
ecdb_button_label_get(Evas_Object *b)
|
|
{
|
|
if (!b)
|
|
{
|
|
printf("ecdb_button_label_get: NULL object!\n");
|
|
return NULL;
|
|
}
|
|
return edje_object_part_text_get(b, "ecdb.label");
|
|
}
|
|
|
|
/************************* COMBO ITEM ****************************************/
|
|
void
|
|
_combo_item_click_cb_call(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
evas_object_smart_callback_call(obj, "clicked", NULL);
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_combo_item_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *ci;
|
|
|
|
ci = ecdb_widget_add(parent, name);
|
|
if (!ci)
|
|
{
|
|
printf("ecdb_combo_item_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
edje_object_file_set(ci, em->theme_path, "ecdb/combo_item");
|
|
edje_object_signal_callback_add(ci, "clicked", "ecdb",
|
|
_combo_item_click_cb_call, ci);
|
|
|
|
return ci;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_item_label_set(Evas_Object *ci, const char *label)
|
|
{
|
|
if (!ci)
|
|
{
|
|
printf("ecdb_combo_label_set: NULL ci!\n");
|
|
return;
|
|
}
|
|
edje_object_part_text_set(ci, "ecdb.label", label);
|
|
}
|
|
|
|
void
|
|
ecdb_combo_item_icon_set(Evas_Object *ci, const char *group)
|
|
{
|
|
Evas_Object *icon;
|
|
|
|
if (!ci)
|
|
{
|
|
printf("ecdb_combo_item_icon_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
icon = ecdb_widget_add(ci, "ecdb.swallow.icon");
|
|
if (!icon)
|
|
{
|
|
printf("ecdb_combo_item_icon_set: NULL icon!\n");
|
|
return;
|
|
}
|
|
edje_object_file_set(icon, em->theme_path, group);
|
|
evas_object_show(icon);
|
|
}
|
|
|
|
const char *
|
|
ecdb_combo_item_label_get(Evas_Object *ci)
|
|
{
|
|
return edje_object_part_text_get(ci, "ecdb.label");
|
|
}
|
|
|
|
/************************* CHECK *********************************************/
|
|
|
|
typedef struct _Check_Data Check_Data;
|
|
struct _Check_Data
|
|
{
|
|
unsigned int checked;
|
|
};
|
|
|
|
static void
|
|
_check_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
{
|
|
Check_Data *cd;
|
|
cd = evas_object_data_get(data, "cd");
|
|
FREE(cd);
|
|
}
|
|
|
|
static void
|
|
_check_toggle_cb_call(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
Check_Data *cd;
|
|
|
|
cd = evas_object_data_get(obj, "cd");
|
|
if (!strcmp(emission, "ecdb,check,checked"))
|
|
{
|
|
evas_object_smart_callback_call(obj, "checked", NULL);
|
|
cd->checked = 1;
|
|
}
|
|
else
|
|
{
|
|
evas_object_smart_callback_call(obj, "unchecked", NULL);
|
|
cd->checked = 0;
|
|
}
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_check_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *c;
|
|
Check_Data *cd;
|
|
|
|
c = ecdb_widget_add(parent, name);
|
|
if (!c)
|
|
{
|
|
printf("ecdb_check_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
|
|
edje_object_file_set(c, em->theme_path, "ecdb/check");
|
|
edje_object_signal_callback_add(c, "ecdb,check,*", "ecdb",
|
|
_check_toggle_cb_call, c);
|
|
evas_object_event_callback_add(c, EVAS_CALLBACK_DEL, _check_del, c);
|
|
|
|
cd = calloc(1, sizeof(Check_Data));
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_check_add: NULL data!\n");
|
|
return NULL;
|
|
}
|
|
evas_object_data_set(c, "cd", cd);
|
|
|
|
return c;
|
|
}
|
|
|
|
void
|
|
ecdb_check_label_set(Evas_Object *c, const char *label)
|
|
{
|
|
if (!c)
|
|
{
|
|
printf("ecdb_check_label_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
edje_object_part_text_set(c, "ecdb.label", label);
|
|
}
|
|
|
|
void
|
|
ecdb_check_states_set(Evas_Object *c, const char *ystate, const char *nstate)
|
|
{
|
|
if (!c)
|
|
{
|
|
printf("ecdb_check_states_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
edje_object_part_text_set(c, "ecdb.ystate", ystate);
|
|
edje_object_part_text_set(c, "ecdb.nstate", nstate);
|
|
}
|
|
|
|
void
|
|
ecdb_check_checked_set(Evas_Object *c, int state)
|
|
{
|
|
Check_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_check_checked_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_check_checked_set: NULL data!\n");
|
|
return;
|
|
}
|
|
|
|
if (state)
|
|
{
|
|
cd->checked = 1;
|
|
edje_object_signal_emit(c, "ecdb,check,on", "ecdb");
|
|
}
|
|
else
|
|
{
|
|
cd->checked = 0;
|
|
edje_object_signal_emit(c, "ecdb,check,off", "ecdb");
|
|
}
|
|
}
|
|
|
|
int
|
|
ecdb_check_checked_get(Evas_Object *c)
|
|
{
|
|
Check_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_check_checked_get: NULL object!\n");
|
|
return 0;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_check_checked_get: NULL data!\n");
|
|
return 0;
|
|
}
|
|
|
|
return cd->checked;
|
|
}
|
|
|
|
/************************** ENTRY *******************************************/
|
|
|
|
/* Shamelessly stolen from Elementary... */
|
|
static char *
|
|
_entry_str_append(char *str, const char *txt, int *len, int *alloc)
|
|
{
|
|
int txt_len = strlen(txt);
|
|
if (txt_len <= 0) return str;
|
|
if ((*len + txt_len) >= *alloc)
|
|
{
|
|
char *str2;
|
|
int alloc2;
|
|
|
|
alloc2 = *alloc + txt_len + 128;
|
|
str2 = realloc(str, alloc2);
|
|
if (!str2) return str;
|
|
*alloc = alloc2;
|
|
str = str2;
|
|
}
|
|
strcpy(str + *len, txt);
|
|
*len += txt_len;
|
|
return str;
|
|
}
|
|
|
|
static char *
|
|
_entry_markup_to_text(const char *mkup)
|
|
{
|
|
char *str = NULL;
|
|
int str_len = 0, str_alloc = 0;
|
|
// FIXME: markup -> text
|
|
char *s, *p;
|
|
char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
|
|
|
|
tag_start = tag_end = esc_start = esc_end = NULL;
|
|
if (!mkup)
|
|
return NULL;
|
|
|
|
p = (char *)mkup;
|
|
s = p;
|
|
for (;;)
|
|
{
|
|
if ((*p == 0) ||
|
|
(tag_end) || (esc_end) ||
|
|
(tag_start) || (esc_start))
|
|
{
|
|
if (tag_end)
|
|
{
|
|
char *ttag;
|
|
|
|
ttag = malloc(tag_end - tag_start);
|
|
if (ttag)
|
|
{
|
|
strncpy(ttag, tag_start + 1, tag_end - tag_start - 1);
|
|
ttag[tag_end - tag_start - 1] = 0;
|
|
/*
|
|
if (!strcmp(ttag, "br"))
|
|
str = _str_append(str, "\n", &str_len, &str_alloc);
|
|
*/
|
|
if (!strcmp(ttag, "\n"))
|
|
str = _entry_str_append(str, "\n", &str_len,
|
|
&str_alloc);
|
|
else if (!strcmp(ttag, "\\n"))
|
|
str = _entry_str_append(str, "\n", &str_len,
|
|
&str_alloc);
|
|
else if (!strcmp(ttag, "\t"))
|
|
str = _entry_str_append(str, "\t", &str_len,
|
|
&str_alloc);
|
|
else if (!strcmp(ttag, "\\t"))
|
|
str = _entry_str_append(str, "\t", &str_len,
|
|
&str_alloc);
|
|
free(ttag);
|
|
}
|
|
tag_start = tag_end = NULL;
|
|
}
|
|
else if (esc_end)
|
|
{
|
|
ts = malloc(esc_end - esc_start + 1);
|
|
if (ts)
|
|
{
|
|
const char *esc;
|
|
strncpy(ts, esc_start, esc_end - esc_start);
|
|
ts[esc_end - esc_start] = 0;
|
|
esc = evas_textblock_escape_string_get(ts);
|
|
if (esc)
|
|
str = _entry_str_append(str, esc, &str_len,
|
|
&str_alloc);
|
|
free(ts);
|
|
}
|
|
esc_start = esc_end = NULL;
|
|
}
|
|
else if (*p == 0)
|
|
{
|
|
ts = malloc(p - s + 1);
|
|
if (ts)
|
|
{
|
|
strncpy(ts, s, p - s);
|
|
ts[p - s] = 0;
|
|
str = _entry_str_append(str, ts, &str_len, &str_alloc);
|
|
free(ts);
|
|
}
|
|
s = NULL;
|
|
}
|
|
if (*p == 0)
|
|
break;
|
|
}
|
|
if (*p == '<')
|
|
{
|
|
if (!esc_start)
|
|
{
|
|
tag_start = p;
|
|
tag_end = NULL;
|
|
ts = malloc(p - s + 1);
|
|
if (ts)
|
|
{
|
|
strncpy(ts, s, p - s);
|
|
ts[p - s] = 0;
|
|
str = _entry_str_append(str, ts, &str_len, &str_alloc);
|
|
free(ts);
|
|
}
|
|
s = NULL;
|
|
}
|
|
}
|
|
else if (*p == '>')
|
|
{
|
|
if (tag_start)
|
|
{
|
|
tag_end = p;
|
|
s = p + 1;
|
|
}
|
|
}
|
|
else if (*p == '&')
|
|
{
|
|
if (!tag_start)
|
|
{
|
|
esc_start = p;
|
|
esc_end = NULL;
|
|
ts = malloc(p - s + 1);
|
|
if (ts)
|
|
{
|
|
strncpy(ts, s, p - s);
|
|
ts[p - s] = 0;
|
|
str = _entry_str_append(str, ts, &str_len, &str_alloc);
|
|
free(ts);
|
|
}
|
|
s = NULL;
|
|
}
|
|
}
|
|
else if (*p == ';')
|
|
{
|
|
if (esc_start)
|
|
{
|
|
esc_end = p;
|
|
s = p + 1;
|
|
}
|
|
}
|
|
p++;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
static void
|
|
_entry_click_cb_call(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
evas_object_focus_set(obj, 1);
|
|
evas_object_smart_callback_call(obj, "clicked", NULL);
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_entry_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *e;
|
|
|
|
e = ecdb_widget_add(parent, name);
|
|
if (!e)
|
|
{
|
|
printf("ecdb_entry_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
edje_object_file_set(e, em->theme_path, "ecdb/entry");
|
|
em->evas_dnd_candidates = eina_list_append(em->evas_dnd_candidates, e);
|
|
evas_object_data_set(e, "dnd_call_func", ecdb_dnd_entry_dnd_set);
|
|
edje_object_signal_callback_add(e, "clicked", "ecdb", _entry_click_cb_call,
|
|
e);
|
|
|
|
return e;
|
|
}
|
|
|
|
void
|
|
ecdb_entry_text_set(Evas_Object *e, const char *text)
|
|
{
|
|
edje_object_part_text_set(e, "ecdb.text", text);
|
|
}
|
|
|
|
char *
|
|
ecdb_entry_text_get(Evas_Object *e)
|
|
{
|
|
return _entry_markup_to_text(edje_object_part_text_get(e, "ecdb.text"));
|
|
}
|
|
|
|
/****************************** COMBO ****************************************/
|
|
|
|
typedef struct _Combo_Data Combo_Data;
|
|
struct _Combo_Data
|
|
{
|
|
Evas_Object *parent;
|
|
Evas_Object *back;
|
|
Evas_Object *popup;
|
|
unsigned int expanded;
|
|
unsigned int count;
|
|
int selected;
|
|
const char *name;
|
|
const char *header;
|
|
void *data;
|
|
void (*create_header)(Evas_Object *, const char *name, void *data,
|
|
Evas_Object *, int);
|
|
};
|
|
|
|
static void
|
|
_combo_min_size(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
|
|
{
|
|
Eina_List *l;
|
|
Evas_Object_Box_Option *opt;
|
|
int x, y, w, h;
|
|
int xc, yc, wc, hc;
|
|
|
|
if (eina_list_count(p->children) <= 0)
|
|
return;
|
|
|
|
evas_object_geometry_get(o, &x, &y, &w, &h);
|
|
p->children = eina_list_nth_list(p->children, 0);
|
|
h /= eina_list_count(p->children);
|
|
if (h < 1) h = 1;
|
|
EINA_LIST_FOREACH(p->children, l, opt)
|
|
{
|
|
evas_object_geometry_get(opt->obj, &xc, &yc, &wc, &hc);
|
|
if ((wc != w) || (hc != h))
|
|
evas_object_resize(opt->obj, w, h);
|
|
if ((xc != x) || (yc != y))
|
|
evas_object_move(opt->obj, x, y);
|
|
y += h;
|
|
}
|
|
}
|
|
|
|
// Axis preferential -- for now vertical
|
|
const char *
|
|
_combo_best_location(Evas_Object *c)
|
|
{
|
|
int x, y, w, h;
|
|
int ww, wh;
|
|
|
|
ecore_evas_geometry_get(em->main_win_ee, NULL, NULL, &ww, &wh);
|
|
evas_object_geometry_get(c, &x, &y, &w, &h);
|
|
|
|
if ((y + h) > (wh - y - h))
|
|
{
|
|
return "top";
|
|
}
|
|
else
|
|
{
|
|
return "bottom";
|
|
}
|
|
}
|
|
|
|
static void
|
|
_combo_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
{
|
|
Combo_Data *cd;
|
|
cd = evas_object_data_get(data, "cd");
|
|
|
|
eina_stringshare_del(cd->name);
|
|
eina_stringshare_del(cd->header);
|
|
FREE(cd);
|
|
}
|
|
|
|
|
|
static void
|
|
_combo_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
cd = evas_object_data_get(data, "cd");
|
|
if (cd->expanded)
|
|
ecdb_combo_collapse(data);
|
|
}
|
|
|
|
static void
|
|
_combo_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
cd = evas_object_data_get(data, "cd");
|
|
if (cd->expanded)
|
|
ecdb_combo_collapse(data);
|
|
}
|
|
|
|
static void
|
|
_combo_clicked(void *data, Evas_Object *obj, void *event_info)
|
|
{
|
|
Combo_Data *cd;
|
|
Evas_Object *swallow, *header;
|
|
Eina_Iterator *it;
|
|
int i = 0;
|
|
|
|
cd = evas_object_data_get(data, "cd");
|
|
swallow = edje_object_part_swallow_get(data, "ecdb.header.swallow");
|
|
if (swallow)
|
|
evas_object_del(swallow);
|
|
|
|
it = evas_object_box_iterator_new(edje_object_part_object_get(cd->popup,
|
|
"ecdb.box"));
|
|
if (!it)
|
|
{
|
|
printf("_combo_clicked: NULL iterator!\n");
|
|
return;
|
|
}
|
|
|
|
while (eina_iterator_next(it, (void **)&swallow))
|
|
{
|
|
if (swallow == obj)
|
|
break;
|
|
i++;
|
|
}
|
|
eina_iterator_free(it);
|
|
|
|
cd->selected = i;
|
|
|
|
header = edje_object_part_swallow_get(data, "ecdb.header.swallow");
|
|
if (header)
|
|
{
|
|
edje_object_part_unswallow(data, header);
|
|
evas_object_del(header);
|
|
}
|
|
|
|
if (cd->create_header)
|
|
cd->create_header(data, "ecdb.header.swallow", cd->data, swallow, i);
|
|
|
|
edje_object_signal_emit(data, "ecdb,combo,header,swallow", "ecdb");
|
|
ecdb_combo_collapse(data);
|
|
}
|
|
|
|
static void
|
|
_combo_item_hide(void *data, Evas_Object *obj, void *event_info)
|
|
{
|
|
edje_object_signal_emit(obj, "ecdb,focus,out", "ecdb");
|
|
}
|
|
|
|
static void
|
|
_combo_moveable_click_cb(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
cd = evas_object_data_get(data, "cd");
|
|
if (cd->expanded)
|
|
ecdb_combo_collapse(data);
|
|
}
|
|
|
|
static void
|
|
_combo_click_cb(void *data, Evas_Object *obj, const char *emission,
|
|
const char *source)
|
|
{
|
|
Evas_Object *c;
|
|
Combo_Data *cd;
|
|
|
|
c = data;
|
|
cd = evas_object_data_get(c, "cd");
|
|
if ((cd) && (!cd->expanded))
|
|
ecdb_combo_expand(c);
|
|
else
|
|
ecdb_combo_collapse(c);
|
|
evas_object_smart_callback_call(c, "clicked", NULL);
|
|
}
|
|
|
|
Evas_Object *
|
|
ecdb_combo_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *c;
|
|
Combo_Data *cd;
|
|
|
|
c = ecdb_widget_add(parent, name);
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
edje_object_file_set(c, em->theme_path, "ecdb/combo");
|
|
evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _combo_resize,
|
|
c);
|
|
evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE, _combo_hide, c);
|
|
evas_object_event_callback_add(c, EVAS_CALLBACK_DEL, _combo_del, c);
|
|
edje_object_signal_callback_add(c, "ecdb,combo,clicked", "ecdb",
|
|
_combo_click_cb, c);
|
|
|
|
cd = calloc(1, sizeof(Combo_Data));
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_add: NULL data!\n");
|
|
return NULL;
|
|
}
|
|
|
|
cd->back = edje_object_add(evas_object_evas_get(parent));
|
|
edje_object_file_set(cd->back, em->theme_path, "ecdb/combo/background");
|
|
edje_object_signal_callback_add(cd->back, "ecdb,combo,back,dismiss", "ecdb",
|
|
_combo_moveable_click_cb, c);
|
|
evas_object_pass_events_set(cd->back, 1);
|
|
evas_object_show(cd->back);
|
|
|
|
cd->popup = edje_object_add(evas_object_evas_get(parent));
|
|
edje_object_file_set(cd->popup, em->theme_path, "ecdb/combo/popup");
|
|
edje_object_signal_callback_add(cd->back, "ecdb,combo,back,dismiss", "ecdb",
|
|
_combo_moveable_click_cb, c);
|
|
edje_box_layout_register("min_size", _combo_min_size, NULL, NULL, NULL,
|
|
NULL);
|
|
evas_object_pass_events_set(cd->popup, 1);
|
|
evas_object_show(cd->popup);
|
|
|
|
cd->parent = parent;
|
|
cd->name = eina_stringshare_add(name);
|
|
cd->selected = -1;
|
|
evas_object_data_set(c, "cd", cd);
|
|
|
|
return c;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_header_set(Evas_Object *c, const char *text)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_header_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_header_set: NULL data!\n");
|
|
return;
|
|
}
|
|
|
|
edje_object_part_text_set(c, "ecdb.header", text);
|
|
eina_stringshare_del(cd->header);
|
|
cd->header = eina_stringshare_add(text);
|
|
}
|
|
|
|
void
|
|
ecdb_combo_append(Evas_Object *c, Evas_Object *o)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_append: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_append: NULL data!\n");
|
|
return;
|
|
}
|
|
cd->count++;
|
|
edje_object_part_box_append(cd->popup, "ecdb.box", o);
|
|
evas_object_smart_callback_add(o, "clicked", _combo_clicked, c);
|
|
evas_object_smart_callback_add(o, "hidden", _combo_item_hide, c);
|
|
}
|
|
|
|
void
|
|
ecdb_combo_expand(Evas_Object *c)
|
|
{
|
|
Combo_Data *cd;
|
|
Eina_Iterator *it;
|
|
Evas_Object *o;
|
|
const Evas_Object *box;
|
|
const char *location, *min_size;
|
|
char buf[1024];
|
|
int x, y, w, h, h2, padding;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_expand: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_expand: NULL data!\n");
|
|
return;
|
|
}
|
|
|
|
if ((cd->count == 0) || (cd->expanded))
|
|
return;
|
|
|
|
edje_object_signal_emit(c, "ecdb,combo,active", "ecdb");
|
|
|
|
evas_object_move(cd->back, 0, 0);
|
|
ecore_evas_geometry_get(em->main_win_ee, NULL, NULL, &w, &h);
|
|
evas_object_resize(cd->back, w, h);
|
|
evas_object_pass_events_set(cd->back, 0);
|
|
evas_object_layer_set(cd->back, evas_object_layer_get(c) + 1);
|
|
edje_object_signal_emit(cd->back, "ecdb,combo,back,show", "ecdb");
|
|
|
|
location = _combo_best_location(c);
|
|
snprintf(buf, sizeof(buf), "ecdb,combo,popup,show,%s", location);
|
|
evas_object_geometry_get(c, &x, &y, &w, &h);
|
|
|
|
box = edje_object_part_object_get(cd->popup, "ecdb.box");
|
|
evas_object_box_padding_get(box, NULL, &padding);
|
|
h2 = -padding;
|
|
|
|
it = evas_object_box_iterator_new(edje_object_part_object_get(cd->popup,
|
|
"ecdb.box"));
|
|
if (!it)
|
|
{
|
|
printf("ecdb_combo_expand: NULL iterator!\n");
|
|
return;
|
|
}
|
|
|
|
while (eina_iterator_next(it, (void **)&o))
|
|
{
|
|
min_size = edje_object_data_get(o, "ecdb/combo_item/minh");
|
|
if (min_size)
|
|
{
|
|
h2 += atoi(min_size);
|
|
}
|
|
else
|
|
{
|
|
printf("THEME ERROR! MISSING REQUIRED MINIMUM DATA VALUE\n");
|
|
}
|
|
h2 += padding;
|
|
}
|
|
|
|
if (!strcmp(location, "top"))
|
|
evas_object_move(cd->popup, x, y - h2);
|
|
else
|
|
evas_object_move(cd->popup, x, y + h);
|
|
|
|
eina_iterator_free(it);
|
|
evas_object_resize(cd->popup, w, h2);
|
|
evas_object_pass_events_set(cd->popup, 0);
|
|
evas_object_layer_set(cd->popup, evas_object_layer_get(cd->back) + 1);
|
|
edje_object_signal_emit(cd->popup, buf, "ecdb");
|
|
|
|
cd->expanded = 1;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_collapse(Evas_Object *c)
|
|
{
|
|
Combo_Data *cd;
|
|
const char *location;
|
|
char buf[1024];
|
|
Eina_Iterator *it;
|
|
Evas_Object *o;
|
|
|
|
// If we close the window
|
|
if ((!em) || (!em->main_win_ee))
|
|
return;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_collapse: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_collapse: NULL data!\n");
|
|
return;
|
|
}
|
|
|
|
edje_object_signal_emit(cd->back, "ecdb,combo,back,hide", "ecdb");
|
|
evas_object_pass_events_set(cd->back, 1);
|
|
edje_object_signal_emit(c, "ecdb,combo,default", "ecdb");
|
|
|
|
location = _combo_best_location(c);
|
|
snprintf(buf, sizeof(buf), "ecdb,combo,popup,hide,%s", location);
|
|
evas_object_pass_events_set(cd->popup, 1);
|
|
edje_object_signal_emit(cd->popup, buf, "ecdb");
|
|
|
|
it = evas_object_box_iterator_new(edje_object_part_object_get(cd->popup,
|
|
"ecdb.box"));
|
|
if (!it)
|
|
{
|
|
printf("ecdb_combo_collapse: NULL iterator!\n");
|
|
return;
|
|
}
|
|
|
|
while ((eina_iterator_next(it, (void **)&o)))
|
|
evas_object_smart_callback_call(o, "hidden", c);
|
|
eina_iterator_free(it);
|
|
|
|
cd->expanded = 0;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_header_create_set(Evas_Object *c, void (*func)
|
|
(Evas_Object *c, const char *name,
|
|
void *data, Evas_Object *clicked, int idx))
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_header_create_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_header_create_set: NULL data!\n");
|
|
return;
|
|
}
|
|
|
|
cd->create_header = func;
|
|
}
|
|
|
|
int
|
|
ecdb_combo_selected_get(Evas_Object *c)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_selected_get: NULL object!\n");
|
|
return -1;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_selected_get: NULL data!\n");
|
|
return -1;
|
|
}
|
|
|
|
return cd->selected;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_data_set(Evas_Object *c, void *data)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_data_set: NULL object!\n");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
if (!cd)
|
|
{
|
|
printf("ecdb_combo_data_set: NULL data!\n");
|
|
return;
|
|
}
|
|
cd->data = data;
|
|
}
|
|
|
|
void
|
|
ecdb_combo_clear(Evas_Object *c)
|
|
{
|
|
Combo_Data *cd;
|
|
|
|
if (!c)
|
|
{
|
|
printf("ecdb_combo_clear: NULL object!");
|
|
return;
|
|
}
|
|
|
|
cd = evas_object_data_get(c, "cd");
|
|
edje_object_part_box_remove_all(cd->popup, "ecdb.box", 1);
|
|
cd->selected = 1;
|
|
cd->count = 0;
|
|
}
|
|
|
|
/******************************* Label ***************************************/
|
|
|
|
Evas_Object *
|
|
ecdb_label_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *l;
|
|
|
|
l = ecdb_widget_add(parent, name);
|
|
if (!l)
|
|
{
|
|
printf("ecdb_label_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
edje_object_file_set(l, em->theme_path, "ecdb/label");
|
|
|
|
return l;
|
|
}
|
|
|
|
void
|
|
ecdb_label_text_set(Evas_Object *l, const char *text)
|
|
{
|
|
if (!l)
|
|
{
|
|
printf("ecdb_label_text_set: NULL object!\n");
|
|
return;
|
|
}
|
|
edje_object_part_text_set(l, "ecdb.label", text);
|
|
}
|
|
|
|
/************************* Config Inwin **************************************/
|
|
Evas_Object *
|
|
ecdb_config_inwin_add(Evas_Object *parent, const char *name)
|
|
{
|
|
Evas_Object *iw;
|
|
|
|
iw = ecdb_widget_add(parent, name);
|
|
if (!iw)
|
|
{
|
|
printf("ecdb_config_inwin_add: NULL return!\n");
|
|
return NULL;
|
|
}
|
|
edje_object_file_set(iw, em->theme_path, "ecdb/config_inwin");
|
|
|
|
/*
|
|
evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _combo_resize,
|
|
iw);
|
|
evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE, _combo_hide, iw);
|
|
evas_object_event_callback_add(c, EVAS_CALLBACK_DEL, _combo_del, iw);
|
|
*/
|
|
|
|
return iw;
|
|
}
|
|
|
|
void
|
|
ecdb_config_inwin_child_add(Evas_Object *inwin, Evas_Object *child,
|
|
int sc, int ec, int sr, int er)
|
|
{
|
|
if (!inwin)
|
|
{
|
|
printf("ecdb_config_inwin_child_add: NULL parent!\n");
|
|
return;
|
|
}
|
|
if (!child)
|
|
return;
|
|
|
|
if (!edje_object_part_table_pack(inwin, "ecdb.table", child, sc, sr, ec, er))
|
|
{
|
|
printf("ecdb_config_inwin_child_add: Couldn't append to table!\n");
|
|
}
|
|
}
|
|
|