1. add carousel start - does nothnig. ignore. copy of toolbar atm to start with

2. make elementary be able to determine theme from
  PREFIX/share/elementary/themes or ~/.elementary/themes (~/ takes preference)
  currently using a delimited list of theme names in order to check like:
    mytheme/fallback/morestuff/default
  (if the last theme entry is on default it is added explicitly).
  this allows multiple theme files bascially to work a bit like a fontset - try
  the first one - if not there, try the next and so on. set $ELM_THEME to your
  theme setting
3. determine prefix and thus data dir - where system themes go. if it can't
  rely on dladdr, or the compiled-in prefix/data dir, you can set $ELM_PREFIX
  and/or $ELM_DATA_DIR accordingly.
  


SVN revision: 38568
This commit is contained in:
Carsten Haitzler 2009-01-13 09:20:53 +00:00
parent 478ebffb67
commit 90f79c27db
9 changed files with 492 additions and 26 deletions

View File

@ -45,7 +45,9 @@ case "$host_os" in
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.])
@ -56,8 +58,21 @@ case "$host_os" in
;;
*)
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)

View File

@ -8,5 +8,5 @@ Description: Mobile device touchscreen widget library
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@

View File

@ -432,7 +432,16 @@ extern "C" {
* "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 ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

View File

@ -41,6 +41,7 @@ elm_bubble.c \
elm_photo.c \
elm_toolbar.c \
elm_list.c \
elm_carousel.c \
\
elc_notepad.c \
elc_anchorview.c \
@ -60,5 +61,5 @@ els_icon.h
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@

View File

@ -0,0 +1,259 @@
#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);
}

View File

@ -1,3 +1,9 @@
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <dlfcn.h> /* dlopen,dlclose,etc */
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
@ -9,6 +15,7 @@
#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);
@ -17,9 +24,11 @@ static void _elm_rescale(void);
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
@ -68,7 +77,8 @@ EAPI void
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();
@ -84,7 +94,56 @@ elm_init(int argc, char **argv)
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;
@ -157,9 +216,13 @@ elm_init(int argc, char **argv)
}
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
@ -200,6 +263,9 @@ elm_shutdown(void)
ecore_x_shutdown();
#endif
}
eina_stringshare_del(_elm_data_dir);
_elm_data_dir = NULL;
free(_elm_config);
free(_elm_appname);

View File

@ -52,7 +52,8 @@ void _elm_win_rescale(void);
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));
@ -92,7 +93,7 @@ EAPI void elm_widget_scroll_hold_pop(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

View File

@ -1,39 +1,154 @@
#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;
}

View File

@ -60,7 +60,7 @@ _item_select(Item *it)
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);
}