AC_DEFINE(ELEMENTARY_BUILD, 1, [Define to mention that evas is built])
lt_enable_auto_import="-Wl,--enable-auto-import"
ELM_WINCE_DEF="#define"
- ;;
+dnl managed by evil
+ AC_DEFINE(HAVE_DLADDR)
+ ;;
mingw*)
PKG_CHECK_MODULES([EVIL], [evil])
AC_DEFINE(HAVE_EVIL, 1, [Set to 1 if evil package is installed.])
;;
*)
ELM_UNIX_DEF="#define"
+ AC_CHECK_FUNCS(dlopen, res=yes, res=no)
+ if test "x$res" = "xyes"; then
+ AC_CHECK_FUNCS(dladdr, AC_DEFINE(HAVE_DLADDR))
+ else
+ AC_CHECK_LIB(dl, dlopen, res=yes, res=no)
+ if test "x$res" = "xyes"; then
+ AC_CHECK_LIB(dl, dladdr, AC_DEFINE(HAVE_DLADDR))
+ dlopen_libs=-ldl
+ else
+ AC_MSG_ERROR(Cannot find dlopen)
+ fi
+ fi
;;
esac
+AC_SUBST(dlopen_libs)
AC_SUBST(lt_enable_auto_import)
AC_SUBST(ELM_UNIX_DEF)
AC_SUBST(ELM_WIN32_DEF)
Requires: evas ecore ecore-x ecore-evas ecore-job ecore-txt ecore-file eet edje
Version: @VERSION@
Libs: -L${libdir} -lelementary
-Libs.private: @my_libs@ @ELEMENTARY_LIBS@ @ELEMENTARY_X_LIBS@ @ELEMENTARY_FB_LIBS@ @ELEMENTARY_WINCE_LIBS@ @ELEMENTARY_EDBUS_LIBS@
+Libs.private: @dlopen_libs@ @my_libs@ @ELEMENTARY_LIBS@ @ELEMENTARY_X_LIBS@ @ELEMENTARY_FB_LIBS@ @ELEMENTARY_WINCE_LIBS@ @ELEMENTARY_EDBUS_LIBS@
Cflags: -I${includedir} -I${includedir}/elementary @ELEMENTARY_CFLAGS@ @ELEMENTARY_X_CFLAGS@ @ELEMENTARY_FB_CFLAGS@ @ELEMENTARY_WINCE_CFLAGS@ @ELEMENTARY_EDBUS_CFLAGS@
* "selected" - when the user selected an item
* "unselected" - when the user selected an item
*/
-
+
+ typedef struct _Elm_Carousel_Item Elm_Carousel_Item;
+ EAPI Evas_Object *elm_carousel_add(Evas_Object *parent);
+ EAPI Elm_Carousel_Item *elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data);
+ EAPI void elm_carousel_item_del(Elm_Carousel_Item *item);
+ EAPI void elm_carousel_item_select(Elm_Carousel_Item *item);
+ /* smart callbacks called:
+ * "clicked" - when the user clicks on a carousel item and becomes selected
+ */
+
////////////////////////////////////////////////////////////////////////////
/// FIXME: TODO LIST ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
elm_photo.c \
elm_toolbar.c \
elm_list.c \
+elm_carousel.c \
\
elc_notepad.c \
elc_anchorview.c \
libelementary_la_CFLAGS =
-libelementary_la_LIBADD = @ELEMENTARY_LIBS@ @ELEMENTARY_X_LIBS@ @ELEMENTARY_FB_LIBS@ @ELEMENTARY_WINCE_LIBS@ @ELEMENTARY_EDBUS_LIBS@ @my_libs@
+libelementary_la_LIBADD = @my_libs@ @dlopen_libs@ @ELEMENTARY_LIBS@ @ELEMENTARY_X_LIBS@ @ELEMENTARY_FB_LIBS@ @ELEMENTARY_WINCE_LIBS@ @ELEMENTARY_EDBUS_LIBS@
libelementary_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+
+// FIXME: this is NOT the carousel - yet!
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Item Item;
+
+struct _Widget_Data
+{
+ Evas_Object *scr, *bx;
+ Eina_List *items;
+ int icon_size;
+ Evas_Bool scrollable : 1;
+};
+
+struct _Item
+{
+ Evas_Object *obj;
+ Evas_Object *base;
+ const char *label;
+ Evas_Object *icon;
+ void (*func) (void *data, Evas_Object *obj, void *event_info);
+ const void *data;
+ Evas_Bool selected : 1;
+};
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+
+static void
+_item_show(Item *it)
+{
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Coord x, y, w, h, bx, by;
+
+ evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
+ evas_object_geometry_get(it->base, &x, &y, &w, &h);
+ elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
+}
+
+static void
+_item_select(Item *it)
+{
+ Item *it2;
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Object *obj2;
+ Eina_List *l;
+ if (it->selected) return;
+ for (l = wd->items; l; l = l->next)
+ {
+ it2 = l->data;
+ if (it2->selected)
+ {
+ it2->selected = 0;
+ edje_object_signal_emit(it2->base, "elm,state,unselected", "elm");
+ break;
+ }
+ }
+ it->selected = 1;
+ edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+ _item_show(it);
+ obj2 = it->obj;
+ if (it->func) it->func((void *)(it->data), it->obj, it);
+ evas_object_smart_callback_call(obj2, "clicked", it);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Item *it;
+ Evas_Coord mw, mh;
+ for (l = wd->items; l; l = l->next)
+ {
+ it = l->data;
+ if (it->selected)
+ edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+ _elm_theme_set(it->base, "carousel", "item", "default");
+ if (it->icon)
+ {
+ edje_extern_object_min_size_set(it->icon,
+ (double)wd->icon_size * _elm_config->scale,
+ (double)wd->icon_size * _elm_config->scale);
+ edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+ }
+ edje_object_part_text_set(it->base, "elm.text", it->label);
+ edje_object_size_min_calc(it->base, &mw, &mh);
+ evas_object_size_hint_min_set(it->base, mw, mh);
+ evas_object_size_hint_max_set(it->base, 9999, mh);
+ }
+ _sizing_eval(obj);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+ Evas_Coord vw = 0, vh = 0;
+
+ edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh);
+ evas_object_resize(wd->scr, 500, 500);
+ evas_object_size_hint_min_get(wd->bx, &minw, &minh);
+ evas_object_resize(wd->bx, minw, minh);
+ elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+ if (wd->scrollable)
+ {
+ minw = 500 - vw;
+ minh = minh + (500 - vh);
+ }
+ else
+ {
+ minw = minw + (500 - vw);
+ minh = minh + (500 - vh);
+ }
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Coord mw, mh, vw, vh, w, h;
+ Eina_List *l;
+ Item *it;
+
+ elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+ evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+ evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
+ if (vw >= mw)
+ {
+ if (w != vw) evas_object_resize(wd->bx, vw, h);
+ }
+ for (l = wd->items; l; l = l->next)
+ {
+ it = l->data;
+ if (it->selected)
+ {
+ _item_show(it);
+ break;
+ }
+ }
+
+}
+
+static void
+_select(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ _item_select(data);
+}
+
+EAPI Evas_Object *
+elm_carousel_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_data_set(obj, wd);
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_theme_hook_set(obj, _theme_hook);
+ elm_widget_can_focus_set(obj, 0);
+
+ wd->scr = elm_smart_scroller_add(e);
+ elm_smart_scroller_theme_set(wd->scr, "carousel", "base", "default");
+ elm_widget_resize_object_set(obj, wd->scr);
+ elm_smart_scroller_policy_set(wd->scr,
+ ELM_SMART_SCROLLER_POLICY_AUTO,
+ ELM_SMART_SCROLLER_POLICY_OFF);
+
+ wd->icon_size = 32;
+ wd->scrollable = 1;
+
+ wd->bx = _els_smart_box_add(e);
+ _els_smart_box_orientation_set(wd->bx, 1);
+ _els_smart_box_homogenous_set(wd->bx, 1);
+ elm_widget_sub_object_add(obj, wd->bx);
+ elm_smart_scroller_child_set(wd->scr, wd->bx);
+ evas_object_show(wd->bx);
+
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
+ _resize, obj);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+EAPI Elm_Carousel_Item *
+elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord mw, mh;
+ Item *it = calloc(1, sizeof(Item));
+ if (!it) return NULL;
+ wd->items = eina_list_append(wd->items, it);
+ it->obj = obj;
+ it->label = eina_stringshare_add(label);
+ it->icon = icon;
+ it->func = func;
+ it->data = data;
+ it->base = edje_object_add(evas_object_evas_get(obj));
+ _elm_theme_set(it->base, "carousel", "item", "default");
+ edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
+ _select, it);
+ elm_widget_sub_object_add(obj, it->base);
+ if (it->icon)
+ {
+ edje_extern_object_min_size_set(it->icon,
+ (double)wd->icon_size * _elm_config->scale,
+ (double)wd->icon_size * _elm_config->scale);
+ edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+ evas_object_show(it->icon);
+ elm_widget_sub_object_add(obj, it->icon);
+ }
+ edje_object_part_text_set(it->base, "elm.text", it->label);
+ edje_object_size_min_calc(it->base, &mw, &mh);
+ evas_object_size_hint_weight_set(it->base, 0.0, 0.0);
+ evas_object_size_hint_align_set(it->base, -1.0, -1.0);
+ evas_object_size_hint_min_set(it->base, mw, mh);
+ evas_object_size_hint_max_set(it->base, 9999, mh);
+ _els_smart_box_pack_end(wd->bx, it->base);
+ evas_object_show(it->base);
+ _sizing_eval(obj);
+ return (Elm_Carousel_Item *)it;
+}
+
+EAPI void
+elm_carousel_item_del(Elm_Carousel_Item *item)
+{
+ Item *it = (Item *)item;
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Object *obj2 = it->obj;
+ wd->items = eina_list_remove(wd->items, it);
+ eina_stringshare_del(it->label);
+ if (it->icon) evas_object_del(it->icon);
+ evas_object_del(it->base);
+ free(it);
+ _theme_hook(obj2);
+}
+
+EAPI void
+elm_carousel_item_select(Elm_Carousel_Item *item)
+{
+ _item_select(item);
+}
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <dlfcn.h> /* dlopen,dlclose,etc */
+
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include "elm_priv.h"
+
static int _elm_signal_exit(void *data, int ev_type, void *ev);
#ifdef HAVE_ELEMENTARY_X
static int _elm_window_property_change(void *data, int ev_type, void *ev);
char *_elm_appname = NULL;
Elm_Config *_elm_config = NULL;
-Ecore_Event_Handler *_elm_event_property_change = NULL;
+const char *_elm_data_dir = NULL;
+
+static Ecore_Event_Handler *_elm_event_property_change = NULL;
#ifdef HAVE_ELEMENTARY_X
-Ecore_X_Atom _elm_atom_enlightenment_scale = 0;
+static Ecore_X_Atom _elm_atom_enlightenment_scale = 0;
#endif
static int
elm_init(int argc, char **argv)
{
int i;
- const char *elm_engine, *elm_scale;
+ const char *elm_engine, *elm_scale, *elm_theme, *elm_prefix, *elm_data_dir;
+ char buf[PATH_MAX];
eet_init();
ecore_init();
elm_engine = getenv("ELM_ENGINE");
elm_scale = getenv("ELM_SCALE");
+ elm_theme = getenv("ELM_THEME");
+ elm_prefix = getenv("ELM_PREFIX");
+ elm_data_dir = getenv("ELM_DATA_DIR");
+ if (!_elm_data_dir)
+ {
+ _elm_data_dir = eina_stringshare_add(elm_data_dir);
+ }
+ if (!_elm_data_dir)
+ {
+ if (elm_prefix)
+ {
+ snprintf(buf, sizeof(buf), "%s/share/elementary", elm_prefix);
+ _elm_data_dir = eina_stringshare_add(buf);
+ }
+ }
+#ifdef HAVE_DLADDR
+ if (!_elm_data_dir)
+ {
+ Dl_info elementary_dl;
+ // libelementary.so/../../share/elementary/
+ if (dladdr(elm_init, &elementary_dl))
+ {
+ char *dir, *dir2;
+
+ dir = ecore_file_dir_get(elementary_dl.dli_fname);
+ if (dir)
+ {
+ dir2 = ecore_file_dir_get(dir);
+ if (dir2)
+ {
+ snprintf(buf, sizeof(buf), "%s/share/elementary", dir2);
+ if (ecore_file_is_dir(buf))
+ _elm_data_dir = eina_stringshare_add(buf);
+ free(dir2);
+ }
+ free(dir);
+ }
+ }
+ }
+#endif
+ if (!_elm_data_dir)
+ {
+ _elm_data_dir = eina_stringshare_add(PACKAGE_DATA_DIR);
+ }
+ if (!_elm_data_dir)
+ {
+ _elm_data_dir = eina_stringshare_add("/");
+ }
+
// FIXME: actually load config
_elm_config = ELM_NEW(Elm_Config);
_elm_config->engine = ELM_SOFTWARE_X11;
}
if (elm_scale)
- {
- _elm_config->scale = atof(elm_scale);
- }
+ _elm_config->scale = atof(elm_scale);
+
+ if (elm_theme)
+ _elm_theme_parse(elm_theme);
+ else
+ _elm_theme_parse("default");
+
/* FIXME: implement quickstart below */
/* if !quickstart return
* else
ecore_x_shutdown();
#endif
}
+
+ eina_stringshare_del(_elm_data_dir);
+ _elm_data_dir = NULL;
free(_elm_config);
free(_elm_appname);
int _elm_theme_set(Evas_Object *o, const char *clas, const char *group, const char *style);
int _elm_theme_icon_set(Evas_Object *o, const char *group, const char *style);
-
+int _elm_theme_parse(const char *theme);
+
/* FIXME: should this be public? for now - private (but public symbols) */
EAPI Evas_Object *elm_widget_add(Evas *evas);
EAPI void elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
EAPI int elm_widget_scroll_hold_get(Evas_Object *obj);
extern char *_elm_appname;
-
extern Elm_Config *_elm_config;
+extern const char *_elm_data_dir;
#endif
#include <Elementary.h>
#include "elm_priv.h"
+static Eina_List *themes = NULL;
+static Eina_Hash *cache = NULL;
+
+static const char *
+_elm_theme_group_file_find(const char *group)
+{
+ Eina_List *l;
+ char buf[PATH_MAX];
+ char *p;
+ static const char *home = NULL;
+ const char *file = eina_hash_find(cache, group);
+ if (file) return file;
+ if (!home)
+ {
+ home = getenv("HOME");
+ if (!home) home = "";
+ }
+ for (l = themes; l; l = l->next)
+ {
+ snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, l->data);
+ if (edje_file_group_exists(buf, group))
+ {
+ file = eina_stringshare_add(buf);
+ if (file)
+ {
+ eina_hash_add(cache, group, file);
+ return file;
+ }
+ }
+ snprintf(buf, sizeof(buf), "%s/themes/%s.edj", PACKAGE_DATA_DIR, l->data);
+ if (edje_file_group_exists(buf, group))
+ {
+ file = eina_stringshare_add(buf);
+ if (file)
+ {
+ eina_hash_add(cache, group, file);
+ return file;
+ }
+ }
+ }
+ return NULL;
+}
+
int
_elm_theme_set(Evas_Object *o, const char *clas, const char *group, const char *style)
{
- char buf[PATH_MAX];
+ const char *file;
char buf2[1024];
int ok;
- // FIXME: actually handle themes for real
- snprintf(buf, sizeof(buf), "%s/themes/%s.edj", PACKAGE_DATA_DIR, "default");
snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
- ok = edje_object_file_set(o, buf, buf2);
- if (ok) return 1;
+ file = _elm_theme_group_file_find(buf2);
+ if (file)
+ {
+ ok = edje_object_file_set(o, file, buf2);
+ if (ok) return 1;
+ }
snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
- ok = edje_object_file_set(o, buf, buf2);
+ file = _elm_theme_group_file_find(buf2);
+ if (!file) return 0;
+ ok = edje_object_file_set(o, file, buf2);
return ok;
}
int
_elm_theme_icon_set(Evas_Object *o, const char *group, const char *style)
{
- char buf[PATH_MAX];
+ const char *file;
char buf2[1024];
int w, h;
int ok;
- // FIXME: actually handle themes for real
- snprintf(buf, sizeof(buf), "%s/themes/%s.edj", PACKAGE_DATA_DIR, "default");
snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
- _els_smart_icon_file_edje_set(o, buf, buf2);
- _els_smart_icon_size_get(o, &w, &h);
- if (w > 0) return 1;
+ file = _elm_theme_group_file_find(buf2);
+ if (file)
+ {
+ _els_smart_icon_file_edje_set(o, file, buf2);
+ _els_smart_icon_size_get(o, &w, &h);
+ if (w > 0) return 1;
+ }
snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
- _els_smart_icon_file_edje_set(o, buf, buf2);
+ file = _elm_theme_group_file_find(buf2);
+ if (!file) return 0;
+ _els_smart_icon_file_edje_set(o, file, buf2);
_els_smart_icon_size_get(o, &w, &h);
return (w > 0);
}
+
+static Eina_Bool
+_cache_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
+{
+ eina_stringshare_del(data);
+}
+
+int
+_elm_theme_parse(const char *theme)
+{
+ Eina_List *names = NULL;
+ const char *p, *pe;
+
+ p = theme;
+ pe = p;
+ for (;;)
+ {
+ if ((*pe == '/') || (*pe == 0))
+ { // p -> pe == 'name/'
+ if (pe > p)
+ {
+ char *n = malloc(pe - p + 1);
+ if (n)
+ {
+ const char *nn;
+ strncpy(n, p, pe - p);
+ n[pe - p] = 0;
+ nn = eina_stringshare_add(n);
+ if (nn)
+ names = eina_list_append(names, nn);
+ free(n);
+ }
+ }
+ if (*pe == 0) break;
+ p = pe + 1;
+ pe = p;
+ }
+ else
+ pe++;
+ }
+ p = eina_list_data_get(eina_list_last(names));
+ if ((!p) || ((p) && (strcmp(p, "default"))))
+ {
+ p = eina_stringshare_add("default");
+ if (p)
+ names = eina_list_append(names, p);
+ }
+ if (cache)
+ {
+ eina_hash_foreach(cache, _cache_free_cb, NULL);
+ eina_hash_free(cache);
+ cache = NULL;
+ }
+ cache = eina_hash_string_superfast_new(NULL);
+
+ while (themes)
+ {
+ eina_stringshare_del(themes->data);
+ themes = eina_list_remove_list(themes, themes);
+ }
+
+ themes = names;
+ return 1;
+}
edje_object_signal_emit(it->base, "elm,state,selected", "elm");
_item_show(it);
obj2 = it->obj;
- if (it->func) it->func(it->data, it->obj, it);
+ if (it->func) it->func((void *)(it->data), it->obj, it);
evas_object_smart_callback_call(obj2, "clicked", it);
}