theme -> can specify a new theme for an object andit gets inherited. need to
authorCarsten Haitzler <raster@rasterman.com>
Wed, 12 May 2010 01:03:46 +0000 (01:03 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Wed, 12 May 2010 01:03:46 +0000 (01:03 +0000)
add tests.

SVN revision: 48771

43 files changed:
src/lib/Elementary.h.in
src/lib/elc_fileselector_button.c
src/lib/elm_bg.c
src/lib/elm_bubble.c
src/lib/elm_button.c
src/lib/elm_carousel.c
src/lib/elm_check.c
src/lib/elm_clock.c
src/lib/elm_config.c
src/lib/elm_conform.c
src/lib/elm_entry.c
src/lib/elm_frame.c
src/lib/elm_genlist.c
src/lib/elm_hover.c
src/lib/elm_icon.c
src/lib/elm_index.c
src/lib/elm_label.c
src/lib/elm_layout.c
src/lib/elm_list.c
src/lib/elm_map.c
src/lib/elm_menu.c
src/lib/elm_notify.c
src/lib/elm_pager.c
src/lib/elm_panel.c
src/lib/elm_photo.c
src/lib/elm_photocam.c
src/lib/elm_priv.h
src/lib/elm_progressbar.c
src/lib/elm_radio.c
src/lib/elm_scrolled_grid.c
src/lib/elm_scroller.c
src/lib/elm_separator.c
src/lib/elm_slider.c
src/lib/elm_slideshow.c
src/lib/elm_spinner.c
src/lib/elm_theme.c
src/lib/elm_thumb.c
src/lib/elm_toggle.c
src/lib/elm_toolbar.c
src/lib/elm_widget.c
src/lib/elm_win.c
src/lib/els_scroller.c
src/lib/els_scroller.h

index 909ef88..6ede697 100644 (file)
@@ -195,19 +195,21 @@ extern "C" {
        ELM_THUMB_ANIMATION_STOP,
        ELM_THUMB_ANIMATION_LAST
     } Elm_Thumb_Animation_Setting;
-
-  typedef enum _Elm_Clock_Digedit
-    {
-       ELM_CLOCK_NONE          = 0,
-       ELM_CLOCK_HOUR_DECIMAL  = 1 << 0,
-       ELM_CLOCK_HOUR_UNIT     = 1 << 1,
-       ELM_CLOCK_MIN_DECIMAL   = 1 << 2,
-       ELM_CLOCK_MIN_UNIT      = 1 << 3,
-       ELM_CLOCK_SEC_DECIMAL   = 1 << 4,
-       ELM_CLOCK_SEC_UNIT      = 1 << 5,
-       ELM_CLOCK_ALL           = (1 << 6) - 1
-    } Elm_Clock_Digedit;
-
+   
+   typedef struct _Elm_Theme Elm_Theme;
+   
+   typedef enum _Elm_Clock_Digedit
+     {
+        ELM_CLOCK_NONE         = 0,
+        ELM_CLOCK_HOUR_DECIMAL = 1 << 0,
+        ELM_CLOCK_HOUR_UNIT    = 1 << 1,
+        ELM_CLOCK_MIN_DECIMAL  = 1 << 2,
+        ELM_CLOCK_MIN_UNIT     = 1 << 3,
+        ELM_CLOCK_SEC_DECIMAL  = 1 << 4,
+        ELM_CLOCK_SEC_UNIT     = 1 << 5,
+        ELM_CLOCK_ALL         = (1 << 6) - 1
+     } Elm_Clock_Digedit;
+   
 #ifndef ELM_LIB_QUICKLAUNCH
 #define ELM_MAIN() int main(int argc, char **argv) {elm_init(argc, argv); return elm_main(argc, argv);}
 #else
@@ -270,13 +272,22 @@ extern "C" {
 
    EAPI void         elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h);
 
-   EAPI void         elm_theme_overlay_add(const char *item);
-   EAPI void         elm_theme_overlay_del(const char *item);
-   EAPI void         elm_theme_extension_add(const char *item);
-   EAPI void         elm_theme_extension_del(const char *item);
-   EAPI void         elm_theme_flush(void);
+   EAPI Elm_Theme   *elm_theme_new(void);
+   EAPI void         elm_theme_free(Elm_Theme *th);
+   EAPI void         elm_theme_overlay_add(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_overlay_del(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_extension_add(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_extension_del(Elm_Theme *th, const char *item);
+   EAPI void         elm_theme_set(Elm_Theme *th, const char *theme);
+   EAPI const char  *elm_theme_get(Elm_Theme *th);
+   EAPI void         elm_theme_flush(Elm_Theme *th);
+   EAPI void         elm_theme_full_flush(void);
+   
    EAPI void         elm_theme_all_set(const char *theme);
-       
+
+   EAPI void         elm_object_theme_set(Evas_Object *obj, Elm_Theme *th);
+   EAPI Elm_Theme   *elm_object_theme_get(Evas_Object *obj);
+   
    EAPI Evas_Object *elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type);
    EAPI void         elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj);
    EAPI void         elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj);
index 7606436..f753588 100644 (file)
@@ -94,7 +94,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->btn, "button", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
    if (wd->btn_label)
@@ -345,7 +345,7 @@ elm_fileselector_button_add(Evas_Object *parent)
    elm_widget_can_focus_set(obj, 1);
 
    wd->btn = edje_object_add(e);
-   _elm_theme_set(wd->btn, "button", "base", "default");
+   _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
                                    _signal_clicked, obj);
    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
index 1871526..6e08c41 100644 (file)
@@ -34,7 +34,7 @@ static void
 _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   _elm_theme_set(wd->img, "bg", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->img, "bg", "base", elm_widget_style_get(obj));
 }
 
 static void
@@ -86,7 +86,7 @@ elm_bg_add(Evas_Object *parent)
    elm_widget_can_focus_set(obj, 0);
 
    wd->img = edje_object_add(e);
-   _elm_theme_set(wd->img, "bg", "base", "default");
+   _elm_theme_object_set(obj, wd->img, "bg", "base", "default");
    elm_widget_resize_object_set(obj, wd->img);
    return obj;
 }
index b14225c..264fe87 100644 (file)
@@ -39,7 +39,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->bbl, "bubble", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->bbl, "bubble", "base", elm_widget_style_get(obj));
    edje_object_part_text_set(wd->bbl, "elm.text", wd->label);
    edje_object_part_text_set(wd->bbl, "elm.info", wd->info);
    edje_object_scale_set(wd->bbl, elm_widget_scale_get(obj) * _elm_config->scale);
@@ -106,7 +106,7 @@ elm_bubble_add(Evas_Object *parent)
    elm_widget_theme_hook_set(obj, _theme_hook);
 
    wd->bbl = edje_object_add(e);
-   _elm_theme_set(wd->bbl, "bubble", "base", "default");
+   _elm_theme_object_set(obj, wd->bbl, "bubble", "base", "default");
    elm_widget_resize_object_set(obj, wd->bbl);
 
    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
@@ -299,7 +299,7 @@ elm_bubble_corner_set(Evas_Object *obj, const char *corner)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->bbl, "bubble", corner, elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->bbl, "bubble", corner, elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_part_swallow(wd->bbl, "elm.swallow.icon", wd->icon);
    if (wd->content)
index 1580857..3bccbef 100644 (file)
@@ -79,7 +79,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->btn, "button", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
    if (wd->label)
@@ -250,7 +250,7 @@ elm_button_add(Evas_Object *parent)
    elm_widget_can_focus_set(obj, 1 );                 
 
    wd->btn = edje_object_add(e);
-   _elm_theme_set(wd->btn, "button", "base", "default");
+   _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
                                    _signal_clicked, obj);
    edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
index 329e7cc..ad3142b 100644 (file)
@@ -84,7 +84,7 @@ _theme_hook(Evas_Object *obj)
 
        if (it->selected)
          edje_object_signal_emit(it->base, "elm,state,selected", "elm");
-       _elm_theme_set(it->base, "carousel", "item", elm_widget_style_get(obj));
+       _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
        edje_object_scale_set(it->base, elm_widget_scale_get(obj) * _elm_config->scale);
        if (it->icon)
          {
@@ -171,7 +171,7 @@ elm_carousel_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
-   elm_smart_scroller_theme_set(wd->scr, "carousel", "base", "default");
+   elm_smart_scroller_object_theme_set(obj, 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,
@@ -210,7 +210,7 @@ elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Ev
    it->func = func;
    it->data = data;
    it->base = edje_object_add(evas_object_evas_get(obj));
-   _elm_theme_set(it->base, "carousel", "item", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
    edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
                                   _select, it);
    elm_widget_sub_object_add(obj, it->base);
index 2a5f9cc..c91956a 100644 (file)
@@ -60,7 +60,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->chk, "check", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->chk, "check", "base", elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
    else
@@ -193,7 +193,7 @@ elm_check_add(Evas_Object *parent)
    elm_widget_disable_hook_set(obj, _disable_hook);
 
    wd->chk = edje_object_add(e);
-   _elm_theme_set(wd->chk, "check", "base", "default");
+   _elm_theme_object_set(obj, wd->chk, "check", "base", "default");
    edje_object_signal_callback_add(wd->chk, "elm,action,check,on", "",
                                    _signal_check_on, obj);
    edje_object_signal_callback_add(wd->chk, "elm,action,check,off", "",
index 7598ac7..b7131d3 100644 (file)
@@ -212,13 +212,13 @@ _time_update(Evas_Object *obj)
          }
 
        if ((wd->seconds) && (wd->am_pm))
-         _elm_theme_set(wd->clk, "clock", "base-all", style);
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-all", style);
        else if (wd->seconds)
-         _elm_theme_set(wd->clk, "clock", "base-seconds", style);
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-seconds", style);
        else if (wd->am_pm)
-         _elm_theme_set(wd->clk, "clock", "base-am_pm", style);
+         _elm_theme_object_set(obj, wd->clk, "clock", "base-am_pm", style);
        else
-         _elm_theme_set(wd->clk, "clock", "base", style);
+         _elm_theme_object_set(obj, wd->clk, "clock", "base", style);
        edje_object_scale_set(wd->clk, elm_widget_scale_get(obj) * 
                               _elm_config->scale);
 
@@ -228,7 +228,7 @@ _time_update(Evas_Object *obj)
 
             if ((!wd->seconds) && (i >= 4)) break;
             wd->digit[i] = edje_object_add(evas_object_evas_get(wd->clk));
-            _elm_theme_set(wd->digit[i], "clock", "flipdigit", style);
+            _elm_theme_object_set(obj, wd->digit[i], "clock", "flipdigit", style);
             edje_object_scale_set(wd->digit[i], elm_widget_scale_get(obj) * 
                                    _elm_config->scale);
             if (wd->edit && (wd->digedit & (1 << i)))
@@ -249,7 +249,7 @@ _time_update(Evas_Object *obj)
        if (wd->am_pm)
          {
             wd->ampm = edje_object_add(evas_object_evas_get(wd->clk));
-            _elm_theme_set(wd->ampm, "clock", "flipampm", style);
+            _elm_theme_object_set(obj, wd->ampm, "clock", "flipampm", style);
             edje_object_scale_set(wd->ampm, elm_widget_scale_get(obj) * 
                                    _elm_config->scale);
             if (wd->edit)
index 1656919..97a265d 100644 (file)
@@ -131,7 +131,7 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
             eina_stringshare_replace(&_elm_config->theme, val);
             if (val)
               {
-                 _elm_theme_parse(val);
+                 _elm_theme_parse(NULL, val);
                  free(val);
                  _elm_rescale();
               }
@@ -299,7 +299,7 @@ _config_free(void)
 static void
 _config_apply(void)
 {
-   _elm_theme_parse(_elm_config->theme);
+   _elm_theme_parse(NULL, _elm_config->theme);
    if (_elm_config->modules) _elm_module_parse(_elm_config->modules);
    ecore_animator_frametime_set(1.0 / _elm_config->fps);
    edje_frametime_set(1.0 / _elm_config->fps);
@@ -578,7 +578,7 @@ _elm_config_sub_init(void)
              if (s)
               {
                  eina_stringshare_replace(&_elm_config->theme, s);
-                  _elm_theme_parse(s);
+                  _elm_theme_parse(NULL, s);
                   free(s);
               }
          }
index 48d5bbc..85bceb9 100644 (file)
@@ -46,7 +46,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->base, "conformant", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->base, "conformant", "base", elm_widget_style_get(obj));
    if (wd->content)
      edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
    edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
@@ -228,7 +228,7 @@ elm_conformant_add(Evas_Object *parent)
    elm_widget_theme_hook_set(obj, _theme_hook);
 
    wd->base = edje_object_add(evas);
-   _elm_theme_set(wd->base, "conformant", "base", "default");
+   _elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
    elm_widget_resize_object_set(obj, wd->base);
 
 #ifdef HAVE_ELEMENTARY_X
index 06aa24c..fba911b 100644 (file)
@@ -258,7 +258,7 @@ _theme_hook(Evas_Object *obj)
    const char *t;
 
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    edje_object_scale_set(wd->ent, elm_widget_scale_get(obj) * _elm_config->scale);
@@ -1240,9 +1240,9 @@ _get_item(void *data, Evas_Object *edje, const char *part, const char *item)
      }
    o = edje_object_add(evas_object_evas_get(data));
    if (!strncmp(item, "emoticon/", 9))
-     ok = _elm_theme_set(o, "entry", item, elm_widget_style_get(data));
+     ok = _elm_theme_object_set(data, o, "entry", item, elm_widget_style_get(data));
    if (!ok)
-     _elm_theme_set(o, "entry/emoticon", "wtf", elm_widget_style_get(data));
+     _elm_theme_object_set(data, o, "entry/emoticon", "wtf", elm_widget_style_get(data));
    return o;
 }
 
@@ -1291,7 +1291,7 @@ elm_entry_add(Evas_Object *parent)
    evas_object_event_callback_add(wd->ent, EVAS_CALLBACK_MOUSE_MOVE,
                                   _mouse_move, obj);
 
-   _elm_theme_set(wd->ent, "entry", "base", "default");
+   _elm_theme_object_set(obj, wd->ent, "entry", "base", "default");
    edje_object_signal_callback_add(wd->ent, "entry,changed", "elm.text",
                                    _signal_entry_changed, obj);
    edje_object_signal_callback_add(wd->ent, "selection,start", "elm.text",
@@ -1379,7 +1379,7 @@ elm_entry_single_line_set(Evas_Object *obj, Eina_Bool single_line)
    wd->linewrap = EINA_FALSE;
    wd->char_linewrap = EINA_FALSE;
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    _sizing_eval(obj);
@@ -1426,7 +1426,7 @@ elm_entry_password_set(Evas_Object *obj, Eina_Bool password)
    wd->linewrap = EINA_FALSE;
    wd->char_linewrap = EINA_FALSE;
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    _sizing_eval(obj);
@@ -1563,7 +1563,7 @@ elm_entry_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
    if(wd->linewrap)
        wd->char_linewrap = EINA_FALSE;
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    _sizing_eval(obj);
@@ -1593,7 +1593,7 @@ elm_entry_line_char_wrap_set(Evas_Object *obj, Eina_Bool wrap)
    if(wd->char_linewrap)
        wd->linewrap = EINA_FALSE;
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    _sizing_eval(obj);
@@ -1618,7 +1618,7 @@ elm_entry_editable_set(Evas_Object *obj, Eina_Bool editable)
    if (wd->editable == editable) return;
    wd->editable = editable;
    t = eina_stringshare_add(elm_entry_entry_get(obj));
-   _elm_theme_set(wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->ent, "entry", _getbase(obj), elm_widget_style_get(obj));
    elm_entry_entry_set(obj, t);
    eina_stringshare_del(t);
    _sizing_eval(obj);
index 727f566..3acd071 100644 (file)
@@ -36,7 +36,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->frm, "frame", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->frm, "frame", "base", elm_widget_style_get(obj));
    if (wd->content)
      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
    edje_object_scale_set(wd->frm, elm_widget_scale_get(obj) * _elm_config->scale);
@@ -106,7 +106,7 @@ elm_frame_add(Evas_Object *parent)
    elm_widget_theme_hook_set(obj, _theme_hook);
 
    wd->frm = edje_object_add(e);
-   _elm_theme_set(wd->frm, "frame", "base", "default");
+   _elm_theme_object_set(obj, wd->frm, "frame", "base", "default");
    elm_widget_resize_object_set(obj, wd->frm);
 
    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
index 39ba261..436c42b 100644 (file)
@@ -372,7 +372,7 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    Item_Block *itb;
    if (!wd) return;
-   elm_smart_scroller_theme_set(wd->scr, "genlist", "base", elm_widget_style_get(obj));
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
 //   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
    EINA_INLIST_FOREACH(wd->blocks, itb)
      {
@@ -833,7 +833,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
    strncat(buf, "/", sizeof(buf) - strlen(buf));
    strncat(buf, it->itc->item_style, sizeof(buf) - strlen(buf));
    
-   _elm_theme_set(it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
+   _elm_theme_object_set(it->wd->obj, it->base, "genlist", buf, elm_widget_style_get(it->wd->obj));
    it->spacer = evas_object_rectangle_add(evas_object_evas_get(it->wd->obj));
    evas_object_color_set(it->spacer, 0, 0, 0, 0);
    elm_widget_sub_object_add(it->wd->obj, it->spacer);
@@ -1487,6 +1487,7 @@ elm_genlist_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "genlist", "base", elm_widget_style_get(obj));
    elm_widget_resize_object_set(obj, wd->scr);
 
    elm_smart_scroller_bounce_allow_set(wd->scr, 0, 1);
index 27c3bde..2508aab 100644 (file)
@@ -77,7 +77,7 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    // FIXME: hover contents doesnt seem to propagate resizes properly
-   _elm_theme_set(wd->cov, "hover", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->cov, "hover", "base", elm_widget_style_get(obj));
    edje_object_scale_set(wd->cov, elm_widget_scale_get(obj) *
                          _elm_config->scale);
    _reval_content(obj);
@@ -288,7 +288,7 @@ elm_hover_add(Evas_Object *parent)
    evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj);
 
    wd->cov = edje_object_add(e);
-   _elm_theme_set(wd->cov, "hover", "base", "default");
+   _elm_theme_object_set(obj, wd->cov, "hover", "base", "default");
    elm_widget_sub_object_add(obj, wd->cov);
    edje_object_signal_callback_add(wd->cov, "elm,action,dismiss", "",
                                    _signal_dismiss, obj);
index 3f52756..c4ae4b6 100644 (file)
@@ -47,10 +47,9 @@ static void
 _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-
    if (!wd) return;
    if (wd->stdicon)
-     _elm_theme_icon_set(wd->img, wd->stdicon, "default");
+     _elm_theme_object_icon_set(obj, wd->img, wd->stdicon, "default");
    _sizing_eval(obj);
 }
 
@@ -185,7 +184,7 @@ elm_icon_standard_set(Evas_Object *obj, const char *name)
 
    if ((!wd) || (!name)) return EINA_FALSE;
    eina_stringshare_replace(&wd->stdicon, name);
-   ret = _elm_theme_icon_set(wd->img, name, "default");
+   ret = _elm_theme_object_icon_set(obj, wd->img, name, "default");
    _sizing_eval(obj);
    return ret;
 }
index feaed55..af2c1e2 100644 (file)
@@ -75,9 +75,9 @@ _theme_hook(Evas_Object *obj)
    _index_box_clear(obj, wd->bx[0], 0);
    _index_box_clear(obj, wd->bx[1], 1);
    if (wd->horizontal)
-     _elm_theme_set(wd->base, "index", "base/horizontal", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->base, "index", "base/horizontal", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->base, "index", "base/vertical", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->base, "index", "base/vertical", elm_widget_style_get(obj));
    edje_object_part_swallow(wd->base, "elm.swallow.event.0", wd->event[0]);
    edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]);
    if (edje_object_part_exists(wd->base, "elm.swallow.index.1"))
@@ -197,9 +197,9 @@ _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level)
         o = edje_object_add(evas_object_evas_get(obj));
         it->base = o;
         if (i & 0x1)
-          _elm_theme_set(o, "index", "item_odd/vertical", "default");
+          _elm_theme_object_set(obj, o, "index", "item_odd/vertical", "default");
         else
-          _elm_theme_set(o, "index", "item/vertical", "default");
+          _elm_theme_object_set(obj, o, "index", "item/vertical", "default");
         edje_object_part_text_set(o, "elm.text", it->letter);
         edje_object_size_min_restricted_calc(o, &mw, &mh, 0, 0);
         evas_object_size_hint_min_set(o, mw, mh);
@@ -494,7 +494,7 @@ elm_index_add(Evas_Object *parent)
    wd->horizontal = EINA_FALSE;
 
    wd->base = edje_object_add(e);
-   _elm_theme_set(wd->base, "index", "base/vertical", "default");
+   _elm_theme_object_set(obj, wd->base, "index", "base/vertical", "default");
    elm_widget_resize_object_set(obj, wd->base);
 
    o = evas_object_rectangle_add(e);
index fa0539e..ad2b37b 100644 (file)
@@ -71,9 +71,9 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (wd->linewrap)
-     _elm_theme_set(wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->lbl, "label", "base", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->lbl, "label", "base", elm_widget_style_get(obj));
    edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
    edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) * 
                          _elm_config->scale);
@@ -144,7 +144,7 @@ elm_label_add(Evas_Object *parent)
    wd->linewrap = EINA_FALSE;
 
    wd->lbl = edje_object_add(e);
-   _elm_theme_set(wd->lbl, "label", "base", "default");
+   _elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
    wd->label = eina_stringshare_add("<br>");
    edje_object_part_text_set(wd->lbl, "elm.text", "<br>");
    elm_widget_resize_object_set(obj, wd->lbl);
@@ -211,9 +211,9 @@ elm_label_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
    wd->linewrap = wrap;
    t = eina_stringshare_add(elm_label_label_get(obj));
    if (wd->linewrap)
-     _elm_theme_set(wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->lbl, "label", "base", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->lbl, "label", "base", elm_widget_style_get(obj));
    elm_label_label_set(obj, t);
    eina_stringshare_del(t);
    wd->changed = 1;
index a3ed0b5..9bd273a 100644 (file)
@@ -203,7 +203,7 @@ elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, cons
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
-   Eina_Bool ret = _elm_theme_set(wd->lay, clas, group, style);
+   Eina_Bool ret = _elm_theme_object_set(obj, wd->lay, clas, group, style);
    if (ret) _request_sizing_eval(obj);
    return ret;
 }
index 26eb034..aff0310 100644 (file)
@@ -568,16 +568,16 @@ _fix_items(Evas_Object *obj)
             if (wd->mode == ELM_LIST_COMPRESS)
               {
                  if (it->even)
-                   _elm_theme_set(it->base, "list", "item_compress", style);
+                   _elm_theme_object_set(obj, it->base, "list", "item_compress", style);
                  else
-                   _elm_theme_set(it->base, "list", "item_compress_odd", style);
+                   _elm_theme_object_set(obj, it->base, "list", "item_compress_odd", style);
               }
             else
               {
                  if (it->even)
-                   _elm_theme_set(it->base, "list", "item", style);
+                   _elm_theme_object_set(obj, it->base, "list", "item", style);
                  else
-                   _elm_theme_set(it->base, "list", "item_odd", style);
+                   _elm_theme_object_set(obj, it->base, "list", "item_odd", style);
               }
             stacking = edje_object_data_get(it->base, "stacking");
             if (stacking)
index 1cc0644..945a2b2 100644 (file)
@@ -1140,7 +1140,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   elm_smart_scroller_theme_set(wd->scr, "map", "base", elm_widget_style_get(obj));
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
 //   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
    _sizing_eval(obj);
 }
@@ -1459,8 +1459,8 @@ _group_bubble_create(Marker_Group *group)
 
    group->wd->opened_bubbles = eina_list_append(group->wd->opened_bubbles, group);
    group->bubble = edje_object_add(evas_object_evas_get(group->obj));
-   _elm_theme_set(group->bubble, "map", "marker_bubble",
-                  elm_widget_style_get(group->wd->obj));
+   _elm_theme_object_set(group->wd->obj, group->bubble, "map", "marker_bubble",
+                         elm_widget_style_get(group->wd->obj));
    evas_object_smart_member_add(group->bubble,
                                 group->wd->obj);
    elm_widget_sub_object_add(group->wd->obj, group->bubble);
@@ -1476,8 +1476,7 @@ _group_bubble_create(Marker_Group *group)
    group->rect = evas_object_rectangle_add(evas_object_evas_get(group->obj));
    evas_object_color_set(group->rect, 0, 0, 0, 0);
    evas_object_repeat_events_set(group->rect, EINA_TRUE);
-   evas_object_smart_member_add(group->rect,
-                                group->wd->obj);
+   evas_object_smart_member_add(group->rect, group->wd->obj);
    elm_widget_sub_object_add(group->wd->obj, group->rect);
    
    evas_object_event_callback_add(group->rect, EVAS_CALLBACK_MOUSE_UP, _group_bubble_mouse_up_cb, group);
@@ -1666,7 +1665,7 @@ elm_map_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
-   elm_smart_scroller_theme_set(wd->scr, "map", "base", "default");
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
    evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
    evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
    elm_widget_resize_object_set(obj, wd->scr);
@@ -2315,7 +2314,7 @@ elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Clas
          style = marker->clas_group->style;
 
        o = edje_object_add(evas_object_evas_get(obj));
-       _elm_theme_set(o, "map/marker", style, elm_widget_style_get(obj));
+       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
        s = edje_object_data_get(o, "size_w");
        clas_group->priv.edje_w = atoi(s);
        s = edje_object_data_get(o, "size_h");
@@ -2336,7 +2335,7 @@ elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Clas
          style = marker->clas->style;
         
        o = edje_object_add(evas_object_evas_get(obj));
-       _elm_theme_set(o, "map/marker", style, elm_widget_style_get(obj));
+       _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
        s = edje_object_data_get(o, "size_w");
        clas->priv.edje_w = atoi(s);
        s = edje_object_data_get(o, "size_h");
index 1304e5f..4556e96 100644 (file)
@@ -105,19 +105,19 @@ _theme_hook(Evas_Object *obj)
          {
             ll = eina_list_append(ll, item->items);
             if (item->separator)
-              _elm_theme_set(item->o, "menu", "separator",
-                              elm_widget_style_get(obj));
+              _elm_theme_object_set(obj, item->o, "menu", "separator",
+                                     elm_widget_style_get(obj));
             else if (item->bx)
               {
-                 _elm_theme_set(item->o, "menu", "item_with_submenu",
-                                 elm_widget_style_get(obj));
+                 _elm_theme_object_set(obj, item->o, "menu", "item_with_submenu",
+                                        elm_widget_style_get(obj));
                  elm_menu_item_label_set(item, item->label);
                  elm_menu_item_icon_set(item, item->icon);
               }
             else
               {
-                 _elm_theme_set(item->o, "menu", "item",
-                                 elm_widget_style_get(obj));
+                 _elm_theme_object_set(obj, item->o, "menu", "item",
+                                        elm_widget_style_get(obj));
                  elm_menu_item_label_set(item, item->label);
                  elm_menu_item_icon_set(item, item->icon);
               }
@@ -342,7 +342,7 @@ _item_obj_create(Elm_Menu_Item *item)
    item->o = edje_object_add(evas_object_evas_get(wd->bx));
    evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
-   _elm_theme_set(item->o, "menu", "item",  elm_widget_style_get(item->menu));
+   _elm_theme_object_set(item->menu, item->o, "menu", "item",  elm_widget_style_get(item->menu));
    edje_object_signal_callback_add(item->o, "elm,action,click", "",
                                    _menu_item_select, item);
    edje_object_signal_callback_add(item->o, "elm,action,activate", "",
@@ -358,7 +358,7 @@ _item_separator_obj_create(Elm_Menu_Item *item)
    item->o = edje_object_add(evas_object_evas_get(wd->bx));
    evas_object_size_hint_weight_set(item->o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_fill_set(item->o, EVAS_HINT_FILL, EVAS_HINT_FILL);
-   _elm_theme_set(item->o, "menu", "separator",  elm_widget_style_get(item->menu));
+   _elm_theme_object_set(item->menu, item->o, "menu", "separator",  elm_widget_style_get(item->menu));
    edje_object_signal_callback_add(item->o, "elm,action,activate", "",
                                    _menu_item_activate, item);
    evas_object_show(item->o);
@@ -380,7 +380,7 @@ _item_submenu_obj_create(Elm_Menu_Item *item)
    evas_object_show(item->bx);
    elm_hover_content_set(item->hv, elm_hover_best_content_location_get(item->hv, ELM_HOVER_AXIS_VERTICAL), item->bx);
 
-   _elm_theme_set(item->o, "menu", "item_with_submenu",  elm_widget_style_get(item->menu));
+   _elm_theme_object_set(item->menu, item->o, "menu", "item_with_submenu",  elm_widget_style_get(item->menu));
    elm_menu_item_label_set(item, item->label);
    elm_menu_item_icon_set(item, item->icon);
 
index 0aa7a8c..1232a90 100644 (file)
@@ -70,9 +70,9 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->notify, "notify", "base", "default");
+   _elm_theme_object_set(obj, wd->notify, "notify", "base", "default");
    if (wd->block_events)
-     _elm_theme_set(wd->block_events, "notify", "block_events", "default");
+     _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", "default");
    edje_object_scale_set(wd->notify, elm_widget_scale_get(obj) *
                          _elm_config->scale);
    _sizing_eval(obj);
@@ -385,31 +385,31 @@ elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient)
    switch (orient)
      {
      case ELM_NOTIFY_ORIENT_TOP:
-        _elm_theme_set(wd->notify, "notify", "base", "default");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "default");
         break;
      case ELM_NOTIFY_ORIENT_CENTER:
-        _elm_theme_set(wd->notify, "notify", "base", "center");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "center");
         break;
      case ELM_NOTIFY_ORIENT_BOTTOM:
-        _elm_theme_set(wd->notify, "notify", "base", "bottom");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom");
         break;
      case ELM_NOTIFY_ORIENT_LEFT:
-        _elm_theme_set(wd->notify, "notify", "base", "left");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "left");
         break;
      case ELM_NOTIFY_ORIENT_RIGHT:
-        _elm_theme_set(wd->notify, "notify", "base", "right");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "right");
         break;
      case ELM_NOTIFY_ORIENT_TOP_LEFT:
-        _elm_theme_set(wd->notify, "notify", "base", "top_left");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "top_left");
         break;
      case ELM_NOTIFY_ORIENT_TOP_RIGHT:
-        _elm_theme_set(wd->notify, "notify", "base", "top_right");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "top_right");
         break;
      case ELM_NOTIFY_ORIENT_BOTTOM_LEFT:
-        _elm_theme_set(wd->notify, "notify", "base", "bottom_left");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom_left");
         break;
      case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT:
-        _elm_theme_set(wd->notify, "notify", "base", "bottom_right");
+        _elm_theme_object_set(obj, wd->notify, "notify", "base", "bottom_right");
         break;
      }
    _resize(obj, NULL, obj, NULL);
@@ -469,7 +469,7 @@ elm_notify_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
    if (!repeat)
      {
        wd->block_events = edje_object_add(evas_object_evas_get(obj));
-       _elm_theme_set(wd->block_events, "notify", "block_events", "default");
+       _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", "default");
         elm_widget_resize_object_set(obj, wd->block_events);
        edje_object_signal_callback_add(wd->block_events, "elm,action,clicked", "elm", _signal_block_clicked, obj);
      }
index 4030329..b1c0299 100644 (file)
@@ -266,7 +266,7 @@ elm_pager_content_push(Evas_Object *obj, Evas_Object *content)
    evas_object_clip_set(it->base, wd->clip);
    elm_widget_sub_object_add(obj, it->base);
    elm_widget_sub_object_add(obj, it->content);
-   _elm_theme_set(it->base,  "pager", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, it->base,  "pager", "base", elm_widget_style_get(obj));
    edje_object_signal_callback_add(it->base, "elm,action,hide,finished", "", 
                                    _signal_hide_finished, it);
    evas_object_event_callback_add(it->content,
index a32a8bb..2c57c4c 100644 (file)
@@ -46,6 +46,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", elm_widget_style_get(obj));
 //   scale = (elm_widget_scale_get(obj) * _elm_config->scale);
 //   edje_object_scale_set(wd->scr, scale);
    _sizing_eval(obj);
@@ -150,8 +151,8 @@ elm_panel_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(evas);
    elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
    elm_smart_scroller_bounce_allow_set(wd->scr, 0, 0);
-   elm_smart_scroller_theme_set(wd->scr, "panel", "base", "left");
    elm_widget_resize_object_set(obj, wd->scr);
    elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, 
                                  ELM_SMART_SCROLLER_POLICY_OFF);
@@ -203,7 +204,7 @@ elm_panel_orient_set(Evas_Object *obj, Elm_Panel_Orient orient)
      case ELM_PANEL_ORIENT_BOTTOM:
         break;
      case ELM_PANEL_ORIENT_LEFT:
-        elm_smart_scroller_theme_set(wd->scr, "panel", "base", "left");
+        elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
      case ELM_PANEL_ORIENT_RIGHT:
         break;
      default:
index 4d1d2a6..5526ee6 100644 (file)
@@ -97,7 +97,7 @@ elm_photo_add(Evas_Object *parent)
    elm_widget_can_focus_set(obj, 0);
 
    wd->frm = edje_object_add(e);
-   _elm_theme_set(wd->frm, "photo", "base", "default");
+   _elm_theme_object_set(obj, wd->frm, "photo", "base", "default");
    elm_widget_resize_object_set(obj, wd->frm);
 
    wd->img = _els_smart_icon_add(e);
index 9f0af93..426cd8a 100644 (file)
@@ -709,7 +709,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   elm_smart_scroller_theme_set(wd->scr, "photocam", "base", elm_widget_style_get(obj));
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "photocam", "base", elm_widget_style_get(obj));
 //   edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
    _sizing_eval(obj);
 }
@@ -967,7 +967,7 @@ elm_photocam_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
-   elm_smart_scroller_theme_set(wd->scr, "photocam", "base", "default");
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "photocam", "base", "default");
    evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
    evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
    elm_widget_resize_object_set(obj, wd->scr);
index ddffc4a..b1c7002 100644 (file)
 // Why EAPI in a private header ?
 // EAPI is temporaty - that widget api will change, but makign it EAPI right now to indicate its bound for externalness
 
+struct _Elm_Theme
+{
+   Eina_List *overlay;
+   Eina_List *themes;
+   Eina_List *extension;
+   Eina_Hash *cache;
+   const char *theme;
+   int ref;
+};
+
 typedef enum _Elm_Engine
 {
    ELM_SOFTWARE_X11,
@@ -88,9 +98,11 @@ struct _Elm_Module
 void _elm_win_shutdown(void);
 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);
+int _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
+int _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);
+int _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style);
+int _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style);
+int _elm_theme_parse(Elm_Theme *th, const char *theme);
 void _elm_theme_shutdown(void);
 
 void _elm_module_init(void);
@@ -144,6 +156,8 @@ EAPI void         elm_widget_scroll_freeze_pop(Evas_Object *obj);
 EAPI int          elm_widget_scroll_freeze_get(const Evas_Object *obj);
 EAPI void         elm_widget_scale_set(Evas_Object *obj, double scale);
 EAPI double       elm_widget_scale_get(const Evas_Object *obj);
+EAPI void         elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th);
+EAPI Elm_Theme   *elm_widget_theme_get(const Evas_Object *obj);
 EAPI void         elm_widget_style_set(Evas_Object *obj, const char *style);
 EAPI const char  *elm_widget_style_get(const Evas_Object *obj);
 EAPI void         elm_widget_type_set(Evas_Object *obj, const char *type);
index 9fd6aac..d290f1d 100644 (file)
@@ -69,9 +69,9 @@ _theme_hook(Evas_Object *obj)
    if (!wd) return;
    edje_object_part_unswallow(NULL, wd->spacer);
    if (wd->horizontal)
-     _elm_theme_set(wd->progressbar, "progressbar", "horizontal", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->progressbar, "progressbar", "horizontal", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->progressbar, "progressbar", "vertical", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->progressbar, "progressbar", "vertical", elm_widget_style_get(obj));
    if (wd->inverted)
      edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm");
    else
@@ -202,7 +202,7 @@ elm_progressbar_add(Evas_Object *parent)
    wd->val = MIN_RATIO_LVL;
 
    wd->progressbar = edje_object_add(e);
-   _elm_theme_set(wd->progressbar, "progressbar", "horizontal", "default");
+   _elm_theme_object_set(obj, wd->progressbar, "progressbar", "horizontal", "default");
    elm_widget_resize_object_set(obj, wd->progressbar);
 
    wd->spacer = evas_object_rectangle_add(e);
index ba84d48..bcc2dda 100644 (file)
@@ -83,7 +83,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->chk, "radio", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->chk, "radio", "base", elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm");
    else
@@ -228,7 +228,7 @@ elm_radio_add(Evas_Object *parent)
    elm_widget_disable_hook_set(obj, _disable_hook);
 
    wd->chk = edje_object_add(e);
-   _elm_theme_set(wd->chk, "radio", "base", "default");
+   _elm_theme_object_set(obj, wd->chk, "radio", "base", "default");
    edje_object_signal_callback_add(wd->chk, "elm,action,radio,on", "", _signal_radio_on, obj);
    edje_object_signal_callback_add(wd->chk, "elm,action,radio,toggle", "", _signal_radio_on, obj);
    elm_widget_resize_object_set(obj, wd->chk);
index 1282ebb..2c69c91 100644 (file)
@@ -216,8 +216,8 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   elm_smart_scroller_theme_set(wd->scr, "grid", "base",
-                               elm_widget_style_get(obj));
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base",
+                                       elm_widget_style_get(obj));
    _sizing_eval(obj);
 }
 
@@ -459,8 +459,8 @@ _cell_realize(Elm_Grid_Cell *cell)
                         _elm_config->scale);
    evas_object_smart_member_add(cell->base, cell->wd->pan_smart);
    elm_widget_sub_object_add(cell->wd->self, cell->base);
-   _elm_theme_set(cell->base, "grid", "cell/default",
-                 elm_widget_style_get(cell->wd->self));
+   _elm_theme_object_set(cell->wd->self, cell->base, "grid", "cell/default",
+                         elm_widget_style_get(cell->wd->self));
    cell->spacer = evas_object_rectangle_add(evas_object_evas_get(cell->wd->self));
    evas_object_color_set(cell->spacer, 0, 0, 0, 0);
    elm_widget_sub_object_add(cell->wd->self, cell->spacer);
@@ -955,7 +955,7 @@ elm_scrolled_grid_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
-   elm_smart_scroller_theme_set(wd->scr, "grid", "base", "default");
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base", "default");
    elm_widget_resize_object_set(obj, wd->scr);
 
    evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
index 79d200d..2c365c8 100644 (file)
@@ -88,11 +88,9 @@ _theme_hook(Evas_Object *obj)
    if (!wd) return;
    if (wd->scr)
      {
-//        elm_smart_scroller_theme_set(wd->scr, "scroller", "base", elm_widget_style_get(obj));
-        elm_smart_scroller_theme_set(wd->scr, 
-                                     wd->widget_name, 
-                                     wd->widget_base,
-                                     elm_widget_style_get(obj));
+        elm_smart_scroller_object_theme_set(obj, wd->scr, 
+                                            wd->widget_name, wd->widget_base,
+                                            elm_widget_style_get(obj));
 //        edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
      }
    _sizing_eval(obj);
@@ -308,10 +306,9 @@ elm_scroller_add(Evas_Object *parent)
    
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
-//   elm_smart_scroller_theme_set(wd->scr, 
-//                                wd->widget_name, 
-//                                wd->widget_base,
-//                                elm_widget_style_get(obj));
+   elm_smart_scroller_object_theme_set(obj, wd->scr, 
+                                       wd->widget_name, wd->widget_base,
+                                       elm_widget_style_get(obj));
    elm_widget_resize_object_set(obj, wd->scr);
    evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
                                  _changed_size_hints, obj);
index f9f927d..5796fee 100644 (file)
@@ -35,9 +35,9 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (wd->horizontal)
-     _elm_theme_set(wd->sep, "separator", "horizontal", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->sep, "separator", "horizontal", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->sep, "separator", "vertical", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->sep, "separator", "vertical", elm_widget_style_get(obj));
    edje_object_scale_set(wd->sep, elm_widget_scale_get(obj) * _elm_config->scale);
    _sizing_eval(obj);
 }
@@ -83,7 +83,7 @@ elm_separator_add(Evas_Object *parent)
    elm_widget_can_focus_set(obj, 0);
 
    wd->sep = edje_object_add(e);
-   _elm_theme_set(wd->sep, "separator", "vertical", "default");
+   _elm_theme_object_set(obj, wd->sep, "separator", "vertical", "default");
    elm_widget_resize_object_set(obj, wd->sep);
    _sizing_eval(obj);
    return obj;
index c6d07da..5b4693c 100644 (file)
@@ -95,9 +95,9 @@ _theme_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (wd->horizontal)
-     _elm_theme_set(wd->slider, "slider", "horizontal", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->slider, "slider", "horizontal", elm_widget_style_get(obj));
    else
-     _elm_theme_set(wd->slider, "slider", "vertical", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->slider, "slider", "vertical", elm_widget_style_get(obj));
    if (wd->inverted)
      edje_object_signal_emit(wd->slider, "elm,state,inverted,on", "elm");
    else
@@ -319,7 +319,7 @@ elm_slider_add(Evas_Object *parent)
    wd->val_max = 1.0;
 
    wd->slider = edje_object_add(e);
-   _elm_theme_set(wd->slider, "slider", "horizontal", "default");
+   _elm_theme_object_set(obj, wd->slider, "slider", "horizontal", "default");
    elm_widget_resize_object_set(obj, wd->slider);
    edje_object_signal_callback_add(wd->slider, "drag", "*", _drag, obj);
    edje_object_signal_callback_add(wd->slider, "drag,start", "*", _drag_start, obj);
index 0e18d59..ec734b3 100644 (file)
@@ -74,7 +74,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->slideshow, "slideshow", "base", "default");
+   _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
    edje_object_scale_set(wd->slideshow, elm_widget_scale_get(obj) *
                          _elm_config->scale);
    _sizing_eval(obj);
@@ -232,7 +232,7 @@ elm_slideshow_add(Evas_Object *parent)
    wd->previous = NULL;
 
    wd->slideshow = edje_object_add(e);
-   _elm_theme_set(wd->slideshow, "slideshow", "base", "default");
+   _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
    elm_widget_resize_object_set(obj, wd->slideshow);
    evas_object_show(wd->slideshow);
 
index dde9de5..564f14a 100644 (file)
@@ -85,7 +85,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->spinner, "spinner", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->spinner, "spinner", "base", elm_widget_style_get(obj));
    edje_object_part_swallow(wd->spinner, "elm.swallow.entry", wd->ent);
    _write_label(obj);
    edje_object_message_signal_process(wd->spinner);
@@ -517,7 +517,7 @@ elm_spinner_add(Evas_Object *parent)
    wd->editable = EINA_TRUE;
 
    wd->spinner = edje_object_add(e);
-   _elm_theme_set(wd->spinner, "spinner", "base", "default");
+   _elm_theme_object_set(obj, wd->spinner, "spinner", "base", "default");
    elm_widget_resize_object_set(obj, wd->spinner);
    edje_object_signal_callback_add(wd->spinner, "drag", "*", _drag, obj);
    edje_object_signal_callback_add(wd->spinner, "drag,start", "*", 
index 6ca3664..ada77f7 100644 (file)
@@ -7,13 +7,38 @@
  * Functions to modify the theme in the currently running app.
  */
 
-static Eina_List *overlay = NULL;
+static Elm_Theme theme_default =
+{
+   NULL, NULL, NULL, NULL,
+     NULL, 1
+};
+
 static Eina_List *themes = NULL;
-static Eina_List *extension = NULL;
-static Eina_Hash *cache = NULL;
+
+static void
+_elm_theme_clear(Elm_Theme *th)
+{
+   const char *p;
+   EINA_LIST_FREE(th->themes, p)
+      eina_stringshare_del(p);
+   EINA_LIST_FREE(th->overlay, p)
+      eina_stringshare_del(p);
+   EINA_LIST_FREE(th->extension, p)
+      eina_stringshare_del(p);
+   if (th->cache)
+     {
+       eina_hash_free(th->cache);
+       th->cache = NULL;
+     }
+   if (th->theme)
+     {
+        eina_stringshare_del(th->theme);
+        th->theme = NULL;
+     }
+}
 
 static const char *
-_elm_theme_find_try(const char *f, const char *group)
+_elm_theme_find_try(Elm_Theme *th, const char *f, const char *group)
 {
    const char *file;
 
@@ -22,7 +47,7 @@ _elm_theme_find_try(const char *f, const char *group)
        file = eina_stringshare_add(f);
        if (file)
          {
-            eina_hash_add(cache, group, file);
+            eina_hash_add(th->cache, group, file);
             return file;
          }
      }
@@ -30,7 +55,7 @@ _elm_theme_find_try(const char *f, const char *group)
 }
 
 static const char *
-_elm_theme_theme_element_try(const char *home, const char *f, const char *group)
+_elm_theme_theme_element_try(Elm_Theme *th, const char *home, const char *f, const char *group)
 {
    char buf[PATH_MAX];
    const char *file = NULL;
@@ -38,27 +63,27 @@ _elm_theme_theme_element_try(const char *home, const char *f, const char *group)
    if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
        ((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
        (isalpha(f[0]) && f[1] == ':'))
-     return _elm_theme_find_try(f, group);
+     return _elm_theme_find_try(th, f, group);
    else if (((f[0] == '~') && (f[1] == '/')))
      {
        snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
-       return _elm_theme_find_try(buf, group);
+       return _elm_theme_find_try(th, buf, group);
      }
    snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, f);
-   file = _elm_theme_find_try(buf, group);
+   file = _elm_theme_find_try(th, buf, group);
    if (file) return file;
    snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
-   file = _elm_theme_find_try(buf, group);
+   file = _elm_theme_find_try(th, buf, group);
    return file;
 }
 
 static const char *
-_elm_theme_group_file_find(const char *group)
+_elm_theme_group_file_find(Elm_Theme *th, const char *group)
 {
    const Eina_List *l;
    const char *f;
    static const char *home = NULL;
-   const char *file = eina_hash_find(cache, group);
+   const char *file = eina_hash_find(th->cache, group);
 
    if (file) return file;
    if (!home)
@@ -66,123 +91,420 @@ _elm_theme_group_file_find(const char *group)
        home = getenv("HOME");
        if (!home) home = "";
      }
-   EINA_LIST_FOREACH(overlay, l, f)
+   EINA_LIST_FOREACH(th->overlay, l, f)
      {
-       file = _elm_theme_theme_element_try(home, f, group);
+       file = _elm_theme_theme_element_try(th, home, f, group);
        if (file) return file;
      }
-   EINA_LIST_FOREACH(themes, l, f)
+   EINA_LIST_FOREACH(th->themes, l, f)
      {
-       file = _elm_theme_theme_element_try(home, f, group);
+       file = _elm_theme_theme_element_try(th, home, f, group);
        if (file) return file;
      }
-   EINA_LIST_FOREACH(extension, l, f)
+   EINA_LIST_FOREACH(th->extension, l, f)
      {
-       file = _elm_theme_theme_element_try(home, f, group);
+       file = _elm_theme_theme_element_try(th, home, f, group);
        if (file) return file;
      }
    return NULL;
 }
 
+int
+_elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style)
+{
+   Elm_Theme *th = NULL;
+   if (parent) th = elm_widget_theme_get(parent);
+   return _elm_theme_set(th, o, clas, group, style);
+}
+
+int
+_elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style)
+{
+   Elm_Theme *th = NULL;
+   if (parent) th = elm_widget_theme_get(parent);
+   return _elm_theme_icon_set(th, o, group, style);
+}
+
+int
+_elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style)
+{
+   const char *file;
+   char buf2[1024];
+   int ok;
+
+   if (!th) th = &(theme_default);
+   snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
+   file = _elm_theme_group_file_find(th, 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);
+   file = _elm_theme_group_file_find(th, buf2);
+   if (!file) return 0;
+   ok = edje_object_file_set(o, file, buf2);
+   return ok;
+}
+
+int
+_elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style)
+{
+   const char *file;
+   char buf2[1024];
+   int w, h;
+
+   if (!th) th = &(theme_default);
+   snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
+   file = _elm_theme_group_file_find(th, 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);
+   file = _elm_theme_group_file_find(th, 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);
+}
+
+int
+_elm_theme_parse(Elm_Theme *th, const char *theme)
+{
+   Eina_List *names = NULL;
+   const char *p, *pe;
+
+   if (!th) th = &(theme_default);
+   if (theme)
+     {
+        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 (th->cache) eina_hash_free(th->cache);
+   th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
+
+   EINA_LIST_FREE(th->themes, p) eina_stringshare_del(p);
+
+   th->themes = names;
+   return 1;
+}
+
+void
+_elm_theme_shutdown(void)
+{
+   _elm_theme_clear(&(theme_default));
+}
+
+/**
+ * Create a new specific theme
+ * 
+ * This creates an empty specific theme that only uses the default theme. A
+ * specific theme has its own private set of extensions and overlays too
+ * (which are empty by default). Specific themes do not fall back to themes
+ * of parent objects. They are not intended for this use. Use styles, overlays
+ * and extensions when needed, but avoid specific themes unless there is no
+ * other way (example: you want to have a preview of a new theme you are
+ * selecting in a "theme selector" window. The preview is inside a scroller
+ * and should display what the theme you selected will look like, but not
+ * actually apply it yet. The child of the scroller will have a specific
+ * theme set to show this preview before the user decides to apply it to all
+ * applications).
+ * 
+ * @ingroup Theme
+ */
+EAPI Elm_Theme *
+elm_theme_new(void)
+{
+   Elm_Theme *th = calloc(1, sizeof(Elm_Theme));
+   if (!th) return NULL;
+   th->ref = 1;
+   th->themes = eina_list_append(th->themes, eina_stringshare_add("default"));
+   themes = eina_list_append(themes, th);
+   return th;
+}
+
+/**
+ * Free a specific theme
+ * 
+ * @param th The theme to free
+ * 
+ * This frees a theme created with elm_theme_new().
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_free(Elm_Theme *th)
+{
+   th->ref--;
+   if (th->ref < 1)
+     {
+        _elm_theme_clear(th);
+        themes = eina_list_remove(themes, th);
+        free(th);
+     }
+}
+
 /**
  * Prepends a theme overlay to the list of overlays
  *
- * @param item The name of the theme overlay
+ * @param th The theme to add to, or if NULL, the default theme
+ * @param item The Edje file path to be used
+ * 
+ * Use this if your application needs to provide some custom overlay theme
+ * (An Edje file that replaces some default styles of widgets) where adding
+ * new styles, or changing system theme configuration is not possible. Do
+ * NOT use this instead of a proper system theme configuration. Use proper
+ * configuration files, profiles, environment variables etc. to set a theme
+ * so that the theme can be altered by simple confiugration by a user. Using
+ * this call to achieve that effect is abusing the API and will create lots
+ * of trouble.
  *
  * @ingroup Theme
  */
 EAPI void
-elm_theme_overlay_add(const char *item)
+elm_theme_overlay_add(Elm_Theme *th, const char *item)
 {
    const char *f = eina_stringshare_add(item);
 
-   if (f) overlay = eina_list_prepend(overlay, f);
-   elm_theme_flush();
+   if (!th) th = &(theme_default);
+   if (f) th->overlay = eina_list_prepend(th->overlay, f);
+   elm_theme_flush(th);
 }
 
 /**
  * Delete a theme overlay from the list of overlays
  *
+ * @param th The theme to delete from, or if NULL, the default theme
  * @param item The name of the theme overlay
  *
+ * See elm_theme_overlay_add().
+ * 
  * @ingroup Theme
  */
 EAPI void
-elm_theme_overlay_del(const char *item)
+elm_theme_overlay_del(Elm_Theme *th, const char *item)
 {
    const Eina_List *l;
    const char *f, *s;
 
+   if (!th) th = &(theme_default);
    s = eina_stringshare_add(item);
-   EINA_LIST_FOREACH(overlay, l, f)
+   EINA_LIST_FOREACH(th->overlay, l, f)
      if (f == s)
        {
          eina_stringshare_del(f);
-         overlay = eina_list_remove_list(overlay, (Eina_List *)l);
+         th->overlay = eina_list_remove_list(th->overlay, (Eina_List *)l);
          break;
        }
    eina_stringshare_del(s);
-   elm_theme_flush();
+   elm_theme_flush(th);
 }
 
 /**
  * Prepends a theme extension to the list of extensions.
  *
- * @param item The name of the theme extension
+ * @param th The theme to add to, or if NULL, the default theme
+ * @param item The Edje file path to be used
  *
+ * This is intended when an application needs more styles of widgets or new
+ * widget themes that the default does not provide (or may not provide). The
+ * application has "extended" usage by coming up with new custom style names
+ * for widgets for specific uses, but as these are not "standard", they are
+ * not guaranteed to be provided by a default theme. This means the
+ * application is required to provide these extra elements itself in specific
+ * Edje files. This call adds one of those Edje files to the theme search
+ * path to be search after the default theme. The use of this call is
+ * encouraged when default styles do not meet the needs of the application.
+ * Use this call instead of elm_theme_overlay_add() for almost all cases.
+ * 
  * @ingroup Theme
  */
 EAPI void
-elm_theme_extension_add(const char *item)
+elm_theme_extension_add(Elm_Theme *th, const char *item)
 {
    const char *f = eina_stringshare_add(item);
 
-   if (f) extension = eina_list_append(extension, f);
-   elm_theme_flush();
+   if (!th) th = &(theme_default);
+   if (f) th->extension = eina_list_append(th->extension, f);
+   elm_theme_flush(th);
 }
 
 /**
  * Deletes a theme extension from the list of extensions.
  *
+ * @param th The theme to delete from, or if NULL, the default theme
  * @param item The name of the theme extension
+ * 
+ * See elm_theme_extension_add().
  *
  * @ingroup Theme
  */
 EAPI void
-elm_theme_extension_del(const char *item)
+elm_theme_extension_del(Elm_Theme *th, const char *item)
 {
    const Eina_List *l;
    const char *f, *s;
 
+   if (!th) th = &(theme_default);
    s = eina_stringshare_add(item);
-   EINA_LIST_FOREACH(extension, l, f)
+   EINA_LIST_FOREACH(th->extension, l, f)
      if (f == s)
        {
          eina_stringshare_del(f);
-         extension = eina_list_remove_list(extension, (Eina_List *)l);
+         th->extension = eina_list_remove_list(th->extension, (Eina_List *)l);
          break;
        }
    eina_stringshare_del(s);
-   elm_theme_flush();
+   elm_theme_flush(th);
+}
+
+/**
+ * Set the theme search order for the given theme
+ * 
+ * @param th The theme to set the search order, or if NULL, the default theme
+ * @param theme Theme search string
+ * 
+ * This sets the search string for the theme in path-notation from first
+ * theme to search, to last, delimited by the : character. Example:
+ * 
+ * "shiny:/path/to/file.edj:default"
+ * 
+ * See the ELM_THEME environment variable for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_set(Elm_Theme *th, const char *theme)
+{
+   if (!th) th = &(theme_default);
+   _elm_theme_parse(th, theme);
+   if (th->theme)
+     {
+        eina_stringshare_del(th->theme);
+        th->theme = NULL;
+     }
+   elm_theme_flush(th);
+}
+
+/**
+ * Return the theme search order
+ * 
+ * @param th The theme to get the search order, or if NULL, the default theme
+ * @return The internal search order path
+ * 
+ * See elm_theme_set() for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI const char *
+elm_theme_get(Elm_Theme *th)
+{
+   if (!th->theme)
+     {
+        Eina_List *l;
+        const char *f;
+        char *tmp;
+        int len;
+        
+        len = 0;
+        EINA_LIST_FOREACH(th->themes, l, f)
+          {
+             len + strlen(f);
+             if (l->next) len += 1;
+          }
+        tmp = alloca(len + 1);
+        tmp[0] = 0;
+        EINA_LIST_FOREACH(th->themes, l, f)
+          {
+             strcat(tmp, f);
+             if (l->next) strcat(tmp, ":");
+          }
+        th->theme = eina_stringshare_add(tmp);
+     }
+   return th->theme;
 }
 
 /**
  * Flush the current theme.
+ * 
+ * @param th Theme to flush
+ * 
+ * This flushes caches that let elementary know where to find theme elements
+ * in the given theme. If @p th is NULL, then the default theme is flushed.
+ * Call this call if source theme data has changed in such a way as to
+ * make any caches Elementary kept invalid.
  *
  * @ingroup Theme
  */
 EAPI void
-elm_theme_flush(void)
+elm_theme_flush(Elm_Theme *th)
 {
-   if (cache) eina_hash_free(cache);
-   cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
+   if (!th) th = &(theme_default);
+   if (th->cache) eina_hash_free(th->cache);
+   th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
    _elm_win_rescale();
 }
 
 /**
- * Set the theme in the current app to theme @p theme
+ * This flushes all themems (default and specific ones).
+ * 
+ * This will flush all themes in the current application context, by calling
+ * elm_theme_flush() on each of them.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_theme_full_flush(void)
+{
+   Eina_List *l;
+   Elm_Theme *th;
+   
+   EINA_LIST_FOREACH(themes, l, th)
+     {
+        elm_theme_flush(th);
+     }
+   elm_theme_flush(&(theme_default));
+}
+
+/**
+ * Set the theme for all elementary using applications on the current display
  *
- * @param theme The name of the theme to use
+ * @param theme The name of the theme to use. Format same as the ELM_THEME
+ * environment variable.
  *
  * @ingroup Theme
  */
@@ -196,117 +518,47 @@ elm_theme_all_set(const char *theme)
    ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
                                   atom, theme);
 #endif
+   elm_theme_set(NULL, theme);
 }
 
-int
-_elm_theme_set(Evas_Object *o, const char *clas, const char *group, const char *style)
-{
-   const char *file;
-   char buf2[1024];
-   int ok;
-
-   snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
-   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);
-   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)
-{
-   const char *file;
-   char buf2[1024];
-   int w, h;
-
-   snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
-   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);
-   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);
-}
-
-int
-_elm_theme_parse(const char *theme)
+/**
+ * Set a specific theme to be used for this object and its children
+ * 
+ * @param obj The object to set the theme on
+ * @param th The theme to set
+ * 
+ * This sets a specific theme that will be used for the given object and any
+ * child objects it has. If @p th is NULL then the theme to be used is
+ * cleared and the object will inherit its theme from its parent (which
+ * ultimately will use the default theme if no specific themes are set).
+ * 
+ * Use special themes with great care as this will annoy users and make
+ * configuration difficult. Avoid any custom themes at all if it can be
+ * helped.
+ * 
+ * @ingroup Theme
+ */
+EAPI void
+elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
 {
-   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_free(cache);
-   cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
-
-   EINA_LIST_FREE(themes, p)
-     eina_stringshare_del(p);
-
-   themes = names;
-   return 1;
+   elm_widget_theme_set(obj, th);
 }
 
-void
-_elm_theme_shutdown(void)
+/**
+ * Get the specific theme to be used
+ * 
+ * @param obj The object to get the specific theme from
+ * @return The specifc theme set.
+ * 
+ * This will return a specific theme set, or NULL if no specific theme is
+ * set on that object. It will not return inherited themes from parents, only
+ * the specific theme set for that specific object. See elm_object_theme_set()
+ * for more information.
+ * 
+ * @ingroup Theme
+ */
+EAPI Elm_Theme *
+elm_object_theme_get(Evas_Object *obj)
 {
-   const char *p;
-   EINA_LIST_FREE(themes, p)
-      eina_stringshare_del(p);
-   EINA_LIST_FREE(overlay, p)
-      eina_stringshare_del(p);
-   EINA_LIST_FREE(extension, p)
-      eina_stringshare_del(p);
-   if (cache)
-     {
-       eina_hash_free(cache);
-       cache = NULL;
-     }
+   return elm_widget_theme_get(obj);
 }
index c026f4e..ce14d8d 100644 (file)
@@ -99,7 +99,7 @@ static void
 _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   _elm_theme_set(wd->children.frm, "thumb", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->children.frm, "thumb", "base", elm_widget_style_get(obj));
 }
 
 #ifdef HAVE_ELEMENTARY_ETHUMB
@@ -473,7 +473,7 @@ elm_thumb_add(Evas_Object *parent)
    elm_widget_theme_hook_set(obj, _theme_hook);
 
    wd->children.frm = edje_object_add(evas);
-   _elm_theme_set(wd->children.frm, "thumb", "base", "default");
+   _elm_theme_object_set(obj, wd->children.frm, "thumb", "base", "default");
    elm_widget_sub_object_add(obj, wd->children.frm);
 
    edje_object_size_min_calc(obj, &minw, &minh);
index d91dfd4..b057215 100644 (file)
@@ -69,7 +69,7 @@ _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   _elm_theme_set(wd->tgl, "toggle", "base", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->tgl, "toggle", "base", elm_widget_style_get(obj));
    if (wd->icon)
      edje_object_signal_emit(wd->tgl, "elm,state,icon,visible", "elm");
    else
@@ -177,7 +177,7 @@ elm_toggle_add(Evas_Object *parent)
    elm_widget_disable_hook_set(obj, _disable_hook);
 
    wd->tgl = edje_object_add(e);
-   _elm_theme_set(wd->tgl, "toggle", "base", "default");
+   _elm_theme_object_set(obj, wd->tgl, "toggle", "base", "default");
    wd->ontext = eina_stringshare_add("ON");
    wd->offtext = eina_stringshare_add("OFF");
    edje_object_signal_callback_add(wd->tgl, "elm,action,toggle,on", "",
index 9d372dc..10173f9 100644 (file)
@@ -177,9 +177,10 @@ _theme_hook(Evas_Object *obj)
    const Eina_List *l;
    Elm_Toolbar_Item *it;
    const char *style = elm_widget_style_get(obj);
-   int scale = 0;
+   double scale = 0;
 
    if (!wd) return;
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", elm_widget_style_get(obj));
    scale = (elm_widget_scale_get(obj) * _elm_config->scale);
 //   edje_object_scale_set(wd->scr, scale);
    EINA_LIST_FOREACH(wd->items, l, it)
@@ -193,7 +194,7 @@ _theme_hook(Evas_Object *obj)
                edje_object_signal_emit(it->base, "elm,state,selected", "elm");
              if (it->disabled)
                edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
-             _elm_theme_set(it->base, "toolbar", "item", style);
+             _elm_theme_object_set(obj, it->base, "toolbar", "item", style);
              if (it->icon)
                {
                   int ms = 0;
@@ -207,7 +208,7 @@ _theme_hook(Evas_Object *obj)
              edje_object_part_text_set(it->base, "elm.text", it->label);
           }
         else
-          _elm_theme_set(it->base, "toolbar", "separator", style);
+          _elm_theme_object_set(obj, it->base, "toolbar", "separator", style);
 
        mw = mh = -1;
        if (!it->separator)
@@ -321,8 +322,8 @@ elm_toolbar_add(Evas_Object *parent)
 
    wd->scr = elm_smart_scroller_add(e);
    elm_smart_scroller_widget_set(wd->scr, obj);
+   elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", "default");
    elm_smart_scroller_bounce_allow_set(wd->scr, 1, 0);
-   elm_smart_scroller_theme_set(wd->scr, "toolbar", "base", "default");
    elm_widget_resize_object_set(obj, wd->scr);
    elm_smart_scroller_policy_set(wd->scr,
                                 ELM_SMART_SCROLLER_POLICY_AUTO,
@@ -415,7 +416,7 @@ elm_toolbar_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Eva
    it->data = data;
    it->separator = EINA_FALSE;
    it->base = edje_object_add(evas_object_evas_get(obj));
-   _elm_theme_set(it->base, "toolbar", "item", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, it->base, "toolbar", "item", elm_widget_style_get(obj));
    edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
                                   _select, it);
    elm_widget_sub_object_add(obj, it->base);
index bd7818b..684d197 100644 (file)
@@ -39,6 +39,7 @@ struct _Smart_Data
    int            scroll_hold;
    int            scroll_freeze;
    double         scale;
+   Elm_Theme     *theme;
    const char    *style;
    
    int            child_drag_x_locked;
@@ -212,6 +213,7 @@ elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
 {
    API_ENTRY return;
    double scale, pscale = elm_widget_scale_get(sobj);
+   Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
 
    sd->subobjs = eina_list_append(sd->subobjs, sobj);
    if (!sd->child_can_focus)
@@ -232,7 +234,8 @@ elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
    evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
    evas_object_smart_callback_call(obj, "sub-object-add", sobj);
    scale = elm_widget_scale_get(sobj);
-   if (scale != pscale) elm_widget_theme(sobj);
+   th = elm_widget_theme_get(sobj);
+   if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
 }
 
 EAPI void
@@ -877,6 +880,7 @@ EAPI double
 elm_widget_scale_get(const Evas_Object *obj)
 {
    API_ENTRY return 1.0;
+   // FIXME: save walking up the tree by storingcaching parent scale
    if (sd->scale == 0.0)
      {
        if (sd->parent_obj)
@@ -888,6 +892,33 @@ elm_widget_scale_get(const Evas_Object *obj)
 }
 
 EAPI void
+elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
+{
+   API_ENTRY return;
+   if (sd->theme != th)
+     {
+        if (sd->theme) elm_theme_free(sd->theme);
+        sd->theme = th;
+        if (th) th->ref++;
+        elm_widget_theme(obj);
+     }
+}
+
+EAPI Elm_Theme *
+elm_widget_theme_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   if (!sd->theme)
+     {
+        if (sd->parent_obj)
+          return elm_widget_theme_get(sd->parent_obj);
+        else
+          return NULL;
+     }
+   return sd->theme;
+}
+
+EAPI void
 elm_widget_style_set(Evas_Object *obj, const char *style)
 {
    API_ENTRY return;
@@ -1081,6 +1112,7 @@ _smart_del(Evas_Object *obj)
    if (sd->del_func) sd->del_func(obj);
    if (sd->style) eina_stringshare_del(sd->style);
    if (sd->type) eina_stringshare_del(sd->type);
+   if (sd->theme) elm_theme_free(sd->theme);
    free(sd);
 }
 
index 8e1c2d4..72472c7 100644 (file)
@@ -1590,7 +1590,7 @@ static void
 _theme_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   _elm_theme_set(wd->frm, "win", "inwin", elm_widget_style_get(obj));
+   _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
    if (wd->content)
      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
    _sizing_eval(obj);
@@ -1657,7 +1657,7 @@ elm_win_inwin_add(Evas_Object *obj)
    elm_widget_theme_hook_set(obj2, _theme_hook);
 
    wd->frm = edje_object_add(win->evas);
-   _elm_theme_set(wd->frm, "win", "inwin", "default");
+   _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
    elm_widget_resize_object_set(obj2, wd->frm);
 
    evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
index 93cef9d..0af0fd4 100644 (file)
@@ -978,10 +978,10 @@ elm_smart_scroller_single_dir_get(Evas_Object *obj)
 }
 
 void
-elm_smart_scroller_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style)
+elm_smart_scroller_object_theme_set(Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style)
 {
    API_ENTRY return;
-   _elm_theme_set(sd->edje_obj, clas, group, style);
+   _elm_theme_object_set(parent, sd->edje_obj, clas, group, style);
    if (sd->pan_obj)
      edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
    sd->vbar_visible = !sd->vbar_visible;
@@ -2305,7 +2305,8 @@ _smart_add(Evas_Object *obj)
 
    o = edje_object_add(evas_object_evas_get(obj));
    sd->edje_obj = o;
-   _elm_theme_set(o, "scroller", "base", "default");
+   // FIXME: null parent obj ... :(
+   _elm_theme_object_set(NULL, o, "scroller", "base", "default");
    edje_object_signal_callback_add(o, "drag", "elm.dragable.vbar", _smart_edje_drag_v, sd);
    edje_object_signal_callback_add(o, "drag,start", "elm.dragable.vbar", _smart_edje_drag_v_start, sd);
    edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.vbar", _smart_edje_drag_v_stop, sd);
index 24b8fdf..4a4acc4 100644 (file)
@@ -23,7 +23,7 @@ void elm_smart_scroller_policy_get              (Evas_Object *obj, Elm_Smart_Scr
 Evas_Object *elm_smart_scroller_edje_object_get (Evas_Object *obj);
 void elm_smart_scroller_single_dir_set          (Evas_Object *obj, Eina_Bool single_dir);
 Eina_Bool elm_smart_scroller_single_dir_get     (Evas_Object *obj);
-void elm_smart_scroller_theme_set               (Evas_Object *obj, const char *clas, const char *group, const char *style);
+void elm_smart_scroller_object_theme_set        (Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style);
 void elm_smart_scroller_hold_set                (Evas_Object *obj, Eina_Bool hold);
 void elm_smart_scroller_freeze_set              (Evas_Object *obj, Eina_Bool freeze);
 void elm_smart_scroller_bounce_allow_set        (Evas_Object *obj, Eina_Bool horiz, Eina_Bool vert);