experimental-legacy/ecdb/trunk/src/ecdb_widgets.c

530 lines
14 KiB
C

/* vim: set sw=3 ts=3 sts=3 expandtab: */
#include "ecdb.h"
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 (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);
edje_object_file_set(b, em->theme_path, "ecdb/button");
edje_object_signal_callback_add(b, "ecdb,button,clicked", "ecdb",
_button_click_cb_call, b);
return b;
}
void
ecdb_button_label_set(Evas_Object *b, const char *label)
{
edje_object_part_text_set(b, "ecdb.label", label);
}
void
ecdb_button_icon_set(Evas_Object *b, const char *group)
{
Evas_Object *icon;
icon = ecdb_widget_add(b, "ecdb.swallow.icon");
edje_object_file_set(icon, em->theme_path, group);
evas_object_show(icon);
}
/************************* CHECK *********************************************/
Evas_Object *
ecdb_check_add(Evas_Object *parent, const char *name)
{
Evas_Object *c;
c = ecdb_widget_add(parent, name);
edje_object_file_set(c, em->theme_path, "ecdb/check");
return c;
}
void
ecdb_check_label_set(Evas_Object *c, const char *label)
{
edje_object_part_text_set(c, "ecdb.label", label);
}
void
ecdb_check_states_set(Evas_Object *c, const char *ystate, const char *nstate)
{
edje_object_part_text_set(c, "ecdb.ystate", ystate);
edje_object_part_text_set(c, "ecdb.nstate", nstate);
}
void
ecdb_check_state_set(Evas_Object *c, int state)
{
if (state)
{
edje_object_signal_emit(c, "ecdb,check,on", "ecdb");
}
else
{
edje_object_signal_emit(c, "ecdb,check,off", "ecdb");
}
}
/************************** 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;
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;
}
Evas_Object *
ecdb_entry_add(Evas_Object *parent, const char *name)
{
Evas_Object *e;
e = ecdb_widget_add(parent, name);
edje_object_file_set(e, em->theme_path, "ecdb/entry");
em->dnd_candidates = eina_list_append(em->dnd_candidates, e);
evas_object_data_set(e, "dnd_call_func", ecdb_dnd_entry_dnd_set);
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;
const char *name;
};
static void
_combo_min_size(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
{
Eina_List *l;
Evas_Object_Box_Option *opt;
int offset_x, offset_y;
int w, h, y;
int wt, ht, xt, yt;
if (eina_list_count(p->children) <= 0)
return;
evas_object_geometry_get(o, &offset_x, &offset_y, &w, &h);
y = offset_y + (h / 2);
EINA_LIST_FOREACH(p->children, l, opt)
{
edje_object_size_min_get(eina_list_nth(p->children, 0), NULL, &h);
evas_object_geometry_get(opt->obj, &xt, &yt, &wt, &ht);
if ((wt != w) || (ht != h))
evas_object_resize(opt->obj, w, h);
if ((xt != 0) || (yt != y))
evas_object_move(opt->obj, offset_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 ((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);
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)
{
printf("object clicked...");
}
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);
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));
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);
evas_object_data_set(c, "cd", cd);
return c;
}
void
ecdb_combo_header_set(Evas_Object *c, const char *text)
{
edje_object_part_text_set(c, "ecdb.header", text);
}
void
ecdb_combo_append(Evas_Object *c, Evas_Object *o)
{
Combo_Data *cd;
cd = evas_object_data_get(c, "cd");
cd->count++;
edje_object_part_box_append(cd->popup, "ecdb.box", o);
evas_object_smart_callback_add(o, "clicked", _combo_clicked, c);
}
void
ecdb_combo_expand(Evas_Object *c)
{
Combo_Data *cd;
const char *location;
char buf[1024];
int x, y, w, h, h2;
int box_height = 30;
cd = evas_object_data_get(c, "cd");
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);
h2 = box_height * cd->count;
if (!strcmp(location, "top"))
evas_object_move(cd->popup, x, y - h2);
else
evas_object_move(cd->popup, x, y + h);
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];
// If we close the window
if ((!em) || (!em->main_win_ee))
return;
cd = evas_object_data_get(c, "cd");
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");
cd->expanded = 0;
}