diff options
86 files changed, 16685 insertions, 19551 deletions
diff --git a/data/themes/widgets/bubble.edc b/data/themes/widgets/bubble.edc index 07ff9cba8..8348b07bd 100644 --- a/data/themes/widgets/bubble.edc +++ b/data/themes/widgets/bubble.edc @@ -569,7 +569,7 @@ group { name: "elm/bubble/bottom_right/default"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 1; - visible: 0; + visible: 0.0; align: 1.0 1.0; aspect: 1.0 1.0; aspect_preference: VERTICAL; diff --git a/data/themes/widgets/button.edc b/data/themes/widgets/button.edc index b4e6c4a0b..11dcd4279 100644 --- a/data/themes/widgets/button.edc +++ b/data/themes/widgets/button.edc @@ -32,7 +32,7 @@ group { name: "elm/button/base/default"; } } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -69,7 +69,7 @@ group { name: "elm/button/base/default"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 0 4; rel2.offset: -5 -5; @@ -227,9 +227,9 @@ group { name: "elm/button/base/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "icononly")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "disabled") || (!strcmp(st, "disabled_visible"))) set_state(PART:"elm.text", "disabled_visible", 0.0); @@ -243,9 +243,9 @@ group { name: "elm/button/base/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); set_state(PART:"elm.text", "default", 0.0); get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "default") || (!strcmp(st, "visible"))) @@ -262,16 +262,16 @@ group { name: "elm/button/base/default"; new Float:vl; get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); } } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; @@ -359,7 +359,7 @@ group { name: "elm/button/base/hoversel_vertical/default"; align: 0.0 0.5; } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -406,7 +406,7 @@ group { name: "elm/button/base/hoversel_vertical/default"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 0 4; rel2.offset: -5 -5; @@ -541,9 +541,9 @@ group { name: "elm/button/base/hoversel_vertical/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "icononly")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); set_state(PART:"elm.text", "visible", 0.0); } } @@ -553,9 +553,9 @@ group { name: "elm/button/base/hoversel_vertical/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); set_state(PART:"elm.text", "default", 0.0); } } @@ -567,16 +567,16 @@ group { name: "elm/button/base/hoversel_vertical/default"; new Float:vl; get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); } } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; @@ -644,7 +644,7 @@ group { name: "elm/button/base/hoversel_vertical_entry/default"; color: 255 255 255 255; } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; visible: 0; @@ -688,7 +688,7 @@ group { name: "elm/button/base/hoversel_vertical_entry/default"; scale: 1; clip_to: "textvis"; description { state: "default" 0.0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 0 4; rel2.offset: -5 -5; @@ -750,9 +750,9 @@ group { name: "elm/button/base/hoversel_vertical_entry/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "icononly")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); set_state(PART:"textvis", "visible", 0.0); set_state(PART:"elm.text", "visible", 0.0); } @@ -763,9 +763,9 @@ group { name: "elm/button/base/hoversel_vertical_entry/default"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); set_state(PART:"textvis", "default", 0.0); set_state(PART:"elm.text", "default", 0.0); } @@ -778,16 +778,16 @@ group { name: "elm/button/base/hoversel_vertical_entry/default"; new Float:vl; get_state(PART:"textvis", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); } } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } } } @@ -833,7 +833,7 @@ group { name: "elm/button/base/anchor"; } } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -870,7 +870,7 @@ group { name: "elm/button/base/anchor"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 0 4; rel2.offset: -5 -5; @@ -1020,9 +1020,9 @@ group { name: "elm/button/base/anchor"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "icononly")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "disabled") || (!strcmp(st, "disabled_visible"))) set_state(PART:"elm.text", "disabled_visible", 0.0); @@ -1036,9 +1036,9 @@ group { name: "elm/button/base/anchor"; script { new st[31]; new Float:vl; - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "default") || (!strcmp(st, "visible"))) set_state(PART:"elm.text", "default", 0.0); @@ -1054,16 +1054,16 @@ group { name: "elm/button/base/anchor"; new Float:vl; get_state(PART:"elm.text", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "icononly", 0.0); + set_state(PART:"elm.swallow.content", "icononly", 0.0); } } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; diff --git a/data/themes/widgets/check.edc b/data/themes/widgets/check.edc index 69463e8bc..ba63cecdc 100644 --- a/data/themes/widgets/check.edc +++ b/data/themes/widgets/check.edc @@ -56,7 +56,7 @@ group { name: "elm/check/base/default"; visible: 1; } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -93,7 +93,7 @@ group { name: "elm/check/base/default"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 1 1; rel2.relative: 1.0 1.0; @@ -177,13 +177,13 @@ group { name: "elm/check/base/default"; signal: "elm,state,icon,visible"; source: "elm"; action: STATE_SET "visible" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; @@ -202,11 +202,11 @@ group { name: "elm/check/base/default"; else set_state(PART:"elm.text", "disabled", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0); + set_state(PART:"elm.swallow.content", "disabled_visible", 0.0); else - set_state(PART:"elm.swallow.icon", "disabled", 0.0); + set_state(PART:"elm.swallow.content", "disabled", 0.0); get_state(PART:"check", st, 30, vl); if (!strcmp(st, "visible")) @@ -232,11 +232,11 @@ group { name: "elm/check/base/default"; else set_state(PART:"elm.text", "default", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "default", 0.0); + set_state(PART:"elm.swallow.content", "default", 0.0); get_state(PART:"check", st, 30, vl); if (!strcmp(st, "visible")) @@ -470,7 +470,7 @@ group { name: "elm/check/base/toggle"; } } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -503,7 +503,7 @@ group { name: "elm/check/base/toggle"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 0 4; rel2.to_x: "bg"; @@ -614,13 +614,13 @@ group { name: "elm/check/base/toggle"; signal: "elm,state,icon,visible"; source: "elm"; action: STATE_SET "visible" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; @@ -643,11 +643,11 @@ group { name: "elm/check/base/toggle"; else set_state(PART:"elm.text", "disabled", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0); + set_state(PART:"elm.swallow.content", "disabled_visible", 0.0); else - set_state(PART:"elm.swallow.icon", "disabled", 0.0); + set_state(PART:"elm.swallow.content", "disabled", 0.0); } } program { name: "enable"; @@ -669,11 +669,11 @@ group { name: "elm/check/base/toggle"; else set_state(PART:"elm.text", "default", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "default", 0.0); + set_state(PART:"elm.swallow.content", "default", 0.0); } } program { name: "to_rtl"; diff --git a/data/themes/widgets/panes.edc b/data/themes/widgets/panes.edc index 015f4b4f6..10423e829 100644 --- a/data/themes/widgets/panes.edc +++ b/data/themes/widgets/panes.edc @@ -86,7 +86,6 @@ group { description { state: "default" 0.0; max: 15 9999; min: 15 100; - fixed: 1 1; rel1.relative: 0.0 0.5; rel2.relative: 1.0 0.5; image { @@ -580,7 +579,6 @@ group { description { state: "default" 0.0; max: 999 15; min: 100 15; - fixed: 1 1; rel1.relative: 0.5 0.0; rel2.relative: 0.5 1.0; image { diff --git a/data/themes/widgets/player.edc b/data/themes/widgets/player.edc index 179945c5a..e6f199635 100644 --- a/data/themes/widgets/player.edc +++ b/data/themes/widgets/player.edc @@ -1,6 +1,6 @@ group { name: "elm/player/base/default"; - min: 365 60; + min: 290 26; parts { part { @@ -8,7 +8,6 @@ group { name: "media_player/slider"; description { - fixed: 1 1; rel2 { relative: 1.0 0.0; to_x: "media_player/forward"; @@ -20,7 +19,6 @@ group { name: "media_player/rewind"; description { - fixed: 1 1; rel1 { to_y: "media_player/slider"; offset: 42 0; diff --git a/data/themes/widgets/progressbar.edc b/data/themes/widgets/progressbar.edc index a6becbbcd..1f88ef21d 100644 --- a/data/themes/widgets/progressbar.edc +++ b/data/themes/widgets/progressbar.edc @@ -40,7 +40,7 @@ group { name: "elm/progressbar/horizontal/default"; } } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; visible: 0; @@ -71,10 +71,10 @@ group { name: "elm/progressbar/horizontal/default"; visible: 0; fixed: 1 1; align: 0.0 0.5; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: -1 4; - rel2.to_x: "elm.swallow.icon"; + rel2.to_x: "elm.swallow.content"; rel2.relative: 1.0 1.0; rel2.offset: -1 -5; color: 0 0 0 255; @@ -303,13 +303,13 @@ group { name: "elm/progressbar/horizontal/default"; signal: "elm,state,icon,visible"; source: "elm"; action: STATE_SET "visible" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "units_show"; signal: "elm,state,units,visible"; @@ -427,7 +427,7 @@ group { name: "elm/progressbar/vertical/default"; } } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; visible: 0; @@ -458,10 +458,10 @@ group { name: "elm/progressbar/vertical/default"; visible: 0; fixed: 1 1; align: 0.5 0.0; - rel1.to_y: "elm.swallow.icon"; + rel1.to_y: "elm.swallow.content"; rel1.relative: 0.5 1.0; rel1.offset: 0 -1; - rel2.to_y: "elm.swallow.icon"; + rel2.to_y: "elm.swallow.content"; rel2.relative: 0.5 1.0; rel2.offset: -1 -1; color: 0 0 0 255; @@ -673,13 +673,13 @@ group { name: "elm/progressbar/vertical/default"; signal: "elm,state,icon,visible"; source: "elm"; action: STATE_SET "visible" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "units_show"; signal: "elm,state,units,visible"; @@ -787,7 +787,7 @@ group { name: "elm/progressbar/horizontal/wheel"; visible: 0; } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; min: 0 0; diff --git a/data/themes/widgets/radio.edc b/data/themes/widgets/radio.edc index e836a8f44..59f93fd93 100644 --- a/data/themes/widgets/radio.edc +++ b/data/themes/widgets/radio.edc @@ -34,7 +34,7 @@ group { name: "elm/radio/base/default"; visible: 1; } } - part { name: "elm.swallow.icon"; + part { name: "elm.swallow.content"; type: SWALLOW; description { state: "default" 0.0; fixed: 1 0; @@ -71,7 +71,7 @@ group { name: "elm/radio/base/default"; scale: 1; description { state: "default" 0.0; visible: 0; - rel1.to_x: "elm.swallow.icon"; + rel1.to_x: "elm.swallow.content"; rel1.relative: 1.0 0.0; rel1.offset: 1 1; rel2.relative: 1.0 1.0; @@ -155,13 +155,13 @@ group { name: "elm/radio/base/default"; signal: "elm,state,icon,visible"; source: "elm"; action: STATE_SET "visible" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "icon_hide"; signal: "elm,state,icon,hidden"; source: "elm"; action: STATE_SET "default" 0.0; - target: "elm.swallow.icon"; + target: "elm.swallow.content"; } program { name: "disable"; signal: "elm,state,disabled"; @@ -180,11 +180,11 @@ group { name: "elm/radio/base/default"; else set_state(PART:"elm.text", "disabled", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "disabled_visible", 0.0); + set_state(PART:"elm.swallow.content", "disabled_visible", 0.0); else - set_state(PART:"elm.swallow.icon", "disabled", 0.0); + set_state(PART:"elm.swallow.content", "disabled", 0.0); } } program { name: "enable"; @@ -204,11 +204,11 @@ group { name: "elm/radio/base/default"; else set_state(PART:"elm.text", "default", 0.0); - get_state(PART:"elm.swallow.icon", st, 30, vl); + get_state(PART:"elm.swallow.content", st, 30, vl); if (!strcmp(st, "visible")) - set_state(PART:"elm.swallow.icon", "visible", 0.0); + set_state(PART:"elm.swallow.content", "visible", 0.0); else - set_state(PART:"elm.swallow.icon", "default", 0.0); + set_state(PART:"elm.swallow.content", "default", 0.0); } } } diff --git a/src/bin/test_bg.c b/src/bin/test_bg.c index 95ace0ec5..d0a382915 100644 --- a/src/bin/test_bg.c +++ b/src/bin/test_bg.c @@ -244,9 +244,6 @@ test_bg_options(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_ /* color choices ... this is ghetto, but we don't have a 'colorpicker' * widget yet :( */ rd = elm_spinner_add(win); - elm_object_tooltip_text_set(rd, "The background's part being affected<br/>" - "here may be seen only if you enlarge<br/>" - "the window and mark the 'Center' radio."); elm_object_style_set(rd, "vertical"); elm_spinner_min_max_set(rd, 1, 4); elm_spinner_label_format_set(rd, "%.0f"); diff --git a/src/bin/test_box.c b/src/bin/test_box.c index eb0310a34..1b191f9f5 100644 --- a/src/bin/test_box.c +++ b/src/bin/test_box.c @@ -189,7 +189,7 @@ _del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) elm_box_unpack(data, obj); evas_object_move(obj, 0, 0); evas_object_color_set(obj, 128, 64, 0, 128); - evas_object_del(obj); +// evas_object_del(obj); } void diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index 73bc91d6d..37ce93b8b 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -161,7 +161,7 @@ EAPI extern Elm_Version *elm_version; /* other includes */ // Tom Hacohen #include <elc_ctxpopup.h> // OK -#include <elm_dayselector.h> // OK +#include <elc_dayselector.h> // OK #include <elc_fileselector_button.h> // OK #include <elc_fileselector_entry.h> // OK #include <elc_fileselector.h> // OK diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b5027472a..844f4811f 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -41,14 +41,12 @@ Elementary_Cursor.h includesdir = $(includedir)/elementary-@VMAJ@ includesunstable_HEADERS = \ -elm_widget.h \ -elm_widget_container.h \ -elm_widget_layout.h +elm_widget.h includesunstabledir = $(includedir)/elementary-@VMAJ@ includesub_HEADERS = \ elc_ctxpopup.h \ -elm_dayselector.h \ +elc_dayselector.h \ elc_fileselector_button.h \ elc_fileselector_entry.h \ elc_fileselector.h \ @@ -139,7 +137,7 @@ includesubdir = $(includedir)/elementary-@VMAJ@/ libelementary_la_SOURCES = \ elm_priv.h \ elc_ctxpopup.c \ -elm_dayselector.c \ +elc_dayselector.c \ elc_popup.c \ elc_fileselector_button.c \ elc_fileselector.c \ @@ -162,7 +160,6 @@ elm_cnp.c \ elm_colorselector.c \ elm_config.c \ elm_conform.c \ -elm_container.c \ elm_datetime.c \ elm_diskselector.c \ elm_entry.c \ diff --git a/src/lib/elc_dayselector.c b/src/lib/elc_dayselector.c new file mode 100644 index 000000000..68f351baf --- /dev/null +++ b/src/lib/elc_dayselector.c @@ -0,0 +1,669 @@ +#include <Elementary.h> +#include "elm_priv.h" + +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Dayselector_Item Elm_Dayselector_Item; + +/* signals to edc */ +#define ITEM_TYPE_WEEKDAY_DEFAULT "elm,type,weekday,default" +#define ITEM_TYPE_WEEKDAY_STYLE1 "elm,type,weekday,style1" +#define ITEM_TYPE_WEEKEND_DEFAULT "elm,type,weekend,default" +#define ITEM_TYPE_WEEKEND_STYLE1 "elm,type,weekend,style1" +#define ITEM_POS_LEFT "elm,pos,check,left" +#define ITEM_POS_RIGHT "elm,pos,check,right" +#define ITEM_POS_MIDDLE "elm,pos,check,middle" + +struct _Widget_Data +{ + Evas_Object *base; + Eina_List *items; + Elm_Dayselector_Day week_start; + Elm_Dayselector_Day weekend_start; + unsigned int weekend_len; +}; + +struct _Elm_Dayselector_Item +{ + ELM_WIDGET_ITEM; + Elm_Dayselector_Day day; + const char *day_style; +}; + +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object* obj); +static void _dayselector_resize(void *data, Evas *e __UNUSED__, + Evas_Object *obj __UNUSED__, void *event_info __UNUSED__); +static void _disable_hook(Evas_Object *obj); +static Eina_Bool _focus_next_hook(const Evas_Object *obj, + Elm_Focus_Direction dir __UNUSED__, + Evas_Object **next __UNUSED__); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _translate_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _item_text_set_hook(Evas_Object *obj, const char *item, + const char *label); +static const char *_item_text_get_hook(const Evas_Object *obj, + const char *item); +static void _content_set_hook(Evas_Object *obj, const char *item, + Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *item); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *item); +static void _signal_emit_cb(void *data, Evas_Object *obj, const char *emission, + const char *source __UNUSED__); +static void _item_clicked_cb(void *data, Evas_Object *obj, + void *event_info __UNUSED__); +static Elm_Dayselector_Item * _item_find(const Evas_Object *obj, + Elm_Dayselector_Day day); +static void _items_style_set(Evas_Object *obj); +static void _update_items(Evas_Object *obj); +static void _create_items(Evas_Object *obj); + +static const char SIG_CHANGED[] = "dayselector,changed"; +static const char SIG_LANG_CHANGED[] = "language,changed"; +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHANGED, ""}, + {SIG_LANG_CHANGED, ""}, + {NULL, NULL} +}; + +static void +_del_hook(Evas_Object *obj) +{ + Elm_Dayselector_Item *it; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + EINA_LIST_FREE(wd->items, it) + { + wd->items = eina_list_remove(wd->items, it); + eina_stringshare_del(it->day_style); + elm_widget_item_free(it); + } + free(wd); +} + +static void +_sizing_eval(Evas_Object* obj) +{ + Evas_Coord min_w = -1, min_h = -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h); + edje_object_size_min_restricted_calc(wd->base, &min_w, &min_h, min_w, min_h); + elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h); + evas_object_size_hint_min_set(obj, min_w, min_h); +} + +static void +_dayselector_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + _sizing_eval(data); +} + +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->base, "elm,state,disabled", "elm"); + else + edje_object_signal_emit(wd->base, "elm,state,enabled", "elm"); +} + +static Eina_Bool +_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir __UNUSED__, + Evas_Object **next __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + + /* TODO: Focus switch support to Elm_widget_Item is not supported yet.*/ + return EINA_FALSE; +} + +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + edje_object_mirrored_set(wd->base, rtl); +} + +static void +_translate_hook(Evas_Object *obj) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + struct tm time_daysel; + time_t t; + char buf[1024]; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + t = time(NULL); + localtime_r(&t, &time_daysel); + EINA_LIST_FOREACH(wd->items, l, it) + { + time_daysel.tm_wday = it->day; + strftime(buf, sizeof(buf), "%a", &time_daysel); + elm_object_text_set(VIEW(it), buf); + } + evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + unsigned int loc; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->base, "dayselector", "base", + elm_widget_style_get(obj)); + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "dayselector/%s", elm_object_style_get(obj)); + elm_object_style_set(VIEW(it), buf); + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d,visible", loc); + edje_object_signal_emit(wd->base, buf, "elm"); + snprintf(buf, sizeof(buf), "day%d", loc); + edje_object_part_swallow(wd->base, buf, VIEW(it)); + } + _update_items(obj); + _sizing_eval(obj); +} + +static void +_item_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, + void *event_info __UNUSED__) +{ + ELM_CHECK_WIDTYPE(data, widtype); + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + unsigned int loc = 0; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + + EINA_LIST_FOREACH(wd->items, l, it) + { + if (obj == VIEW(it)) + { + wd->items = eina_list_remove(wd->items, it); + eina_stringshare_del(it->day_style); + evas_object_smart_callback_del(VIEW(it), "changed", _item_clicked_cb); + evas_object_event_callback_del(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb); + edje_object_part_unswallow(wd->base, VIEW(it)); + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d,default", loc); + edje_object_signal_emit(wd->base, buf, "elm"); + elm_widget_item_free(it); + _sizing_eval(obj); + break; + } + } +} + +static void +_signal_emit_cb(void *data, Evas_Object *obj, const char *emission, const char *source __UNUSED__) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + + EINA_LIST_FOREACH(wd->items, l, it) + { + if (obj == VIEW(it)) + { + eina_stringshare_replace(&it->day_style, emission); + return ; + } + } +} + +static void +_item_text_set_hook(Evas_Object *obj, const char *item, const char *label) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && !strcmp(item, "default")) return; + if (!wd) return; + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "day%d", it->day); + if (!strncmp(buf, item, sizeof(buf))) + { + elm_object_text_set(VIEW(it), label); + _sizing_eval(obj); + break; + } + } +} + +static const char * +_item_text_get_hook(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && !strcmp(item, "default")) return NULL; + if (!wd) return NULL; + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "day%d", it->day); + if (!strncmp(buf, item, sizeof(buf))) + return elm_object_text_get(VIEW(it)); + } + return NULL; +} + +static void +_content_set_hook(Evas_Object *obj, const char *item, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + unsigned int idx, loc; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd || !content) return; + if (item && !strcmp(item, "default")) return; + if (strcmp(elm_object_widget_type_get(content), "check")) return; + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "day%d", it->day); + if (!strncmp(buf, item, sizeof(buf))) + { + if (VIEW(it)) evas_object_del(VIEW(it)); + break; + } + } + for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++) + { + snprintf(buf, sizeof(buf), "day%d", idx); + if (!strncmp(buf, item, sizeof(buf))) + { + it = elm_widget_item_new(obj, Elm_Dayselector_Item); + if (!it) continue; + VIEW(it) = content; + it->day = idx; + wd->items = eina_list_append(wd->items, it); + elm_widget_sub_object_add(obj, content); + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + idx) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d", loc); + edje_object_part_swallow(wd->base, buf, VIEW(it)); + snprintf(buf, sizeof(buf), "day%d,visible", loc); + edje_object_signal_emit(wd->base, buf, "elm"); + evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb, obj); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "", _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "", _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "", _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "", _signal_emit_cb, obj); + _sizing_eval(obj); + _update_items(obj); + break; + } + } +} + +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (item && !strcmp(item, "default")) return NULL; + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "day%d", it->day); + if (!strncmp(buf, item, sizeof(buf))) return VIEW(it); + } + return NULL; +} + +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Eina_List *l; + Elm_Dayselector_Item *it; + Evas_Object *content; + char buf[1024]; + unsigned int loc; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (item && !strcmp(item, "default")) return NULL; + + EINA_LIST_FOREACH(wd->items, l, it) + { + snprintf(buf, sizeof(buf), "day%d", it->day); + if (!strncmp(buf, item, sizeof(buf))) + { + content = VIEW(it); + wd->items = eina_list_remove(wd->items, it); + elm_widget_sub_object_del(obj, VIEW(it)); + evas_object_smart_callback_del(VIEW(it), "changed", _item_clicked_cb); + evas_object_event_callback_del(VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb); + edje_object_part_unswallow(wd->base, VIEW(it)); + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d,default", loc); + edje_object_signal_emit(wd->base, buf, "elm"); + _sizing_eval(obj); + return content; + } + } + return NULL; +} + +static void +_item_clicked_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + + EINA_LIST_FOREACH(wd->items, l, it) + { + if (obj != VIEW(it)) continue; + evas_object_smart_callback_call(data, SIG_CHANGED, (void *)it->day); + return; + } +} + +static Elm_Dayselector_Item * +_item_find(const Evas_Object *obj, Elm_Dayselector_Day day) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + EINA_LIST_FOREACH(wd->items, l, it) + if (day == it->day) return it; + + return NULL; +} + +static void +_items_style_set(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Eina_List *l; + Elm_Dayselector_Item *it; + unsigned int weekend_last; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + weekend_last = wd->weekend_start + wd->weekend_len - 1; + if (weekend_last >= ELM_DAYSELECTOR_MAX) + weekend_last = weekend_last % ELM_DAYSELECTOR_MAX; + + EINA_LIST_FOREACH(wd->items, l, it) + { + if (weekend_last >= wd->weekend_start) + { + if ((it->day >= wd->weekend_start) && (it->day <= weekend_last)) + eina_stringshare_replace(&it->day_style, + ITEM_TYPE_WEEKEND_DEFAULT); + else + eina_stringshare_replace(&it->day_style, + ITEM_TYPE_WEEKDAY_DEFAULT); + } + else + { + if ((it->day >= wd->weekend_start) || (it->day <= weekend_last)) + eina_stringshare_replace(&it->day_style, + ITEM_TYPE_WEEKEND_DEFAULT); + else + eina_stringshare_replace(&it->day_style, + ITEM_TYPE_WEEKDAY_DEFAULT); + } + } +} + +static void +_update_items(Evas_Object *obj) +{ + Eina_List *l; + Elm_Dayselector_Item *it; + unsigned int last_day; + Eina_Bool rtl; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + last_day = wd->week_start + ELM_DAYSELECTOR_MAX - 1; + if (last_day >= ELM_DAYSELECTOR_MAX) + last_day = last_day % ELM_DAYSELECTOR_MAX; + + rtl = elm_widget_mirrored_get(obj); + EINA_LIST_FOREACH(wd->items, l, it) + { + elm_object_signal_emit(VIEW(it), it->day_style, ""); + if (it->day == wd->week_start) + { + if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm"); + else elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm"); + } + else if (it->day == last_day) + { + if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm"); + else elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm"); + } + else + elm_object_signal_emit(VIEW(it), ITEM_POS_MIDDLE, "elm"); + } +} + +static void +_create_items(Evas_Object *obj) +{ + Elm_Dayselector_Item *it; + struct tm time_daysel; + time_t t; + char buf[1024]; + unsigned int idx, loc; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + t = time(NULL); + localtime_r(&t, &time_daysel); + + for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++) + { + it = elm_widget_item_new(obj, Elm_Dayselector_Item); + if (!it) continue; + VIEW(it) = elm_check_add(wd->base); + elm_widget_sub_object_add(obj, VIEW(it)); + wd->items = eina_list_append(wd->items, it); + elm_object_style_set(VIEW(it), "dayselector/default"); + time_daysel.tm_wday = idx; + strftime(buf, sizeof(buf), "%a", &time_daysel); + elm_object_text_set(VIEW(it), buf); + it->day = idx; + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + idx) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d", loc); + edje_object_part_swallow(wd->base, buf, VIEW(it)); + snprintf(buf, sizeof(buf), "day%d,visible", idx); + edje_object_signal_emit(wd->base, buf, "elm"); + evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb, + obj); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_DEL, + _item_del_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "", + _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "", + _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "", + _signal_emit_cb, obj); + elm_object_signal_callback_add(VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "", + _signal_emit_cb, obj); + } + _items_style_set(obj); + _update_items(obj); +} + +EAPI Evas_Object * +elm_dayselector_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "dayselector"); + elm_widget_type_set(obj, widtype); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_focus_next_hook_set(obj, _focus_next_hook); + elm_widget_translate_hook_set(obj, _translate_hook); + elm_widget_text_set_hook_set(obj, _item_text_set_hook); + elm_widget_text_get_hook_set(obj, _item_text_get_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "dayselector", "base", "default"); + elm_object_style_set(wd->base, "dayselector"); + elm_widget_resize_object_set(obj, wd->base); + + wd->week_start = _elm_config->week_start; + wd->weekend_start = _elm_config->weekend_start; + wd->weekend_len = _elm_config->weekend_len; + printf("%d %d %d\n", wd->week_start, wd->weekend_start, wd->weekend_len); + _create_items(obj); + + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, + _dayselector_resize, obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + return obj; +} + +EAPI void +elm_dayselector_day_selected_set(Evas_Object *obj, Elm_Dayselector_Day day, Eina_Bool selected) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + elm_check_state_set(VIEW(_item_find(obj, day)), selected); +} + +EAPI Eina_Bool +elm_dayselector_day_selected_get(const Evas_Object *obj, Elm_Dayselector_Day day) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + + return elm_check_state_get(VIEW(_item_find(obj, day))); +} + +EAPI void +elm_dayselector_week_start_set(Evas_Object *obj, Elm_Dayselector_Day day) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Eina_List *l; + Elm_Dayselector_Item *it; + char buf[1024]; + unsigned int loc; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + wd->week_start = day; + EINA_LIST_FOREACH(wd->items, l, it) + { + loc = (ELM_DAYSELECTOR_MAX - wd->week_start + it->day) % ELM_DAYSELECTOR_MAX; + snprintf(buf, sizeof(buf), "day%d", loc); + edje_object_part_swallow(wd->base, buf, VIEW(it)); + } + _update_items(obj); +} + +EAPI Elm_Dayselector_Day +elm_dayselector_week_start_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_DAYSELECTOR_MAX; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return ELM_DAYSELECTOR_MAX; + + return wd->week_start; +} + +EAPI void +elm_dayselector_weekend_start_set(Evas_Object *obj, Elm_Dayselector_Day day) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + wd->weekend_start = day; + _items_style_set(obj); + _update_items(obj); +} + +EAPI Elm_Dayselector_Day +elm_dayselector_weekend_start_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_DAYSELECTOR_MAX; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return ELM_DAYSELECTOR_MAX; + + return wd->weekend_start; +} + +EAPI void +elm_dayselector_weekend_length_set(Evas_Object *obj, unsigned int length) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return; + + wd->weekend_len = length; + _items_style_set(obj); + _update_items(obj); +} + +EAPI unsigned int +elm_dayselector_weekend_length_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data* wd = elm_widget_data_get(obj); + if (!wd) return 0; + + return wd->weekend_len; +} diff --git a/src/lib/elm_dayselector.h b/src/lib/elc_dayselector.h index f61849dc3..6b1497d93 100644 --- a/src/lib/elm_dayselector.h +++ b/src/lib/elc_dayselector.h @@ -51,13 +51,9 @@ * the elm_object_part_content_set/get APIs thus providing a way to handle * the different check styles for individual days. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for dayselector objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @c "dayselector,changed" - when the user changes the state of a day. - * @li @c "language,changed" - the program's language changed + * The widget emits the following signals: + * @li "dayselector,changed" - when the user changes the state of a day. + * @li "language,changed" - the program's language changed * * Available styles for dayselector are: * @li default diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c index 6201de98b..148c73d60 100644 --- a/src/lib/elc_fileselector.c +++ b/src/lib/elc_fileselector.c @@ -10,47 +10,48 @@ * - Filter support */ -#include <Elementary.h> -#include "elm_priv.h" -#include "elm_widget_layout.h" +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif #ifdef HAVE_EIO # include <Eio.h> #endif -static const char FILESELECTOR_SMART_NAME[] = "elm_fileselector"; +#include <Elementary.h> +#include "elm_priv.h" -typedef struct _Elm_Fileselector_Smart_Data Elm_Fileselector_Smart_Data; +typedef struct _Widget_Data Widget_Data; -struct _Elm_Fileselector_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - EINA_REFCOUNT; - Evas_Object *filename_entry; - Evas_Object *path_entry; - Evas_Object *files_list; - Evas_Object *files_grid; - Evas_Object *up_button; - Evas_Object *home_button; - Evas_Object *ok_button; - Evas_Object *cancel_button; + Evas_Object *edje; + Evas_Object *filename_entry; + Evas_Object *path_entry; + Evas_Object *files_list; + Evas_Object *files_grid; + Evas_Object *up_button; + Evas_Object *home_button; + + Evas_Object *ok_button; + Evas_Object *cancel_button; - const char *path; - const char *selection; - Ecore_Idler *sel_idler; + const char *path; + const char *selection; + Ecore_Idler *sel_idler; - const char *path_separator; + const char *path_separator; #ifdef HAVE_EIO - Eio_File *current; + Eio_File *current; #endif Elm_Fileselector_Mode mode; - Eina_Bool only_folder : 1; - Eina_Bool expand : 1; + Eina_Bool only_folder : 1; + Eina_Bool expand : 1; }; struct sel_data @@ -59,182 +60,202 @@ struct sel_data const char *path; }; -typedef struct _Listing_Request Listing_Request; -struct _Listing_Request +typedef struct _Widget_Request Widget_Request; +struct _Widget_Request { - Elm_Fileselector_Smart_Data *sd; - Elm_Object_Item *parent_it; + Widget_Data *wd; + Elm_Object_Item *parent; - Evas_Object *obj; - const char *path; - Eina_Bool first : 1; + Evas_Object *obj; + const char *path; + Eina_Bool first : 1; }; typedef enum { - ELM_DIRECTORY = 0, - ELM_FILE_IMAGE = 1, - ELM_FILE_UNKNOW = 2, - ELM_FILE_LAST + ELM_DIRECTORY = 0, + ELM_FILE_IMAGE = 1, + ELM_FILE_UNKNOW = 2, + ELM_FILE_LAST } Elm_Fileselector_Type; static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST]; static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST]; +static const char *widtype = NULL; + static const char SIG_DIRECTORY_OPEN[] = "directory,open"; static const char SIG_DONE[] = "done"; static const char SIG_SELECTED[] = "selected"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_DIRECTORY_OPEN, "s"}, {SIG_DONE, "s"}, {SIG_SELECTED, "s"}, {NULL, NULL} }; -#define ELM_FILESELECTOR_DATA_GET(o, sd) \ - Elm_Fileselector_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_FILESELECTOR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_FILESELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_FILESELECTOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_FILESELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } +static void _populate(Evas_Object *obj, + const char *path, + Elm_Object_Item *parent); +static void _do_anchors(Evas_Object *obj, + const char *path); -#define ELM_FILESELECTOR_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), FILESELECTOR_SMART_NAME, __func__)) \ - return +/*** ELEMENTARY WIDGET ***/ +static void +_widget_data_free(Widget_Data *wd) +{ + if (wd->path) eina_stringshare_del(wd->path); + if (wd->selection) eina_stringshare_del(wd->selection); + if (wd->sel_idler) + { + void *sd; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (FILESELECTOR_SMART_NAME, _elm_fileselector, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); + sd = ecore_idler_del(wd->sel_idler); + free(sd); + } + free(wd); +} -/* final routine on deletion */ static void -_elm_fileselector_smart_del_do(Elm_Fileselector_Smart_Data *sd) +_del_hook(Evas_Object *obj) { - if (sd->path) eina_stringshare_del(sd->path); - if (sd->selection) eina_stringshare_del(sd->selection); - if (sd->sel_idler) free(ecore_idler_del(sd->sel_idler)); + Widget_Data *wd; + int i; + + wd = elm_widget_data_get(obj); + if (!wd) return; + + for (i = 0; i < ELM_FILE_LAST; ++i) + { + elm_genlist_item_class_free(list_itc[i]); + elm_gengrid_item_class_free(grid_itc[i]); + } - ELM_WIDGET_CLASS(_elm_fileselector_parent_sc)->base.del - (ELM_WIDGET_DATA(sd)->obj); +#ifdef HAVE_EIO + if (wd->current) + eio_file_cancel(wd->current); +#endif + + wd->files_list = NULL; + wd->files_grid = NULL; + + EINA_REFCOUNT_UNREF(wd) + _widget_data_free(wd); } static void -_elm_fileselector_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; - - ELM_FILESELECTOR_DATA_GET(obj, sd); - + if (!wd) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(wd->edje, &minw, &minh, minw, minh); evas_object_size_hint_min_set(obj, minw, minh); } static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_FILESELECTOR_DATA_GET(obj, sd); - - elm_widget_mirrored_set(sd->cancel_button, rtl); - elm_widget_mirrored_set(sd->ok_button, rtl); - elm_widget_mirrored_set(sd->files_list, rtl); - elm_widget_mirrored_set(sd->up_button, rtl); - elm_widget_mirrored_set(sd->home_button, rtl); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_widget_mirrored_set(wd->cancel_button, rtl); + elm_widget_mirrored_set(wd->ok_button, rtl); + elm_widget_mirrored_set(wd->files_list, rtl); + elm_widget_mirrored_set(wd->up_button, rtl); + elm_widget_mirrored_set(wd->home_button, rtl); + edje_object_mirrored_set(wd->edje, rtl); } -static Eina_Bool -_elm_fileselector_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { - const char *style; + Widget_Data *wd = elm_widget_data_get(obj); + const char *style = elm_widget_style_get(obj); const char *data; char buf[1024]; - ELM_FILESELECTOR_DATA_GET(obj, sd); + if (!wd) return; + _elm_widget_mirrored_reload(obj); - if (!ELM_WIDGET_CLASS(_elm_fileselector_parent_sc)->theme(obj)) return EINA_FALSE; + _elm_theme_object_set(obj, wd->edje, "fileselector", "base", style); - style = elm_widget_style_get(obj); - _mirrored_set(obj, elm_widget_mirrored_get(obj)); + if (elm_object_disabled_get(obj)) + edje_object_signal_emit(wd->edje, "elm,state,disabled", "elm"); - data = edje_object_data_get - (ELM_WIDGET_DATA(sd)->resize_obj, "path_separator"); - if (data) sd->path_separator = data; - else sd->path_separator = "/"; + data = edje_object_data_get(wd->edje, "path_separator"); + if (data) + wd->path_separator = data; + else + wd->path_separator = "/"; + if (!style) style = "default"; snprintf(buf, sizeof(buf), "fileselector/%s", style); -#define SWALLOW(part_name, object_ptn) \ - if (object_ptn) \ - { \ - elm_widget_style_set(object_ptn, buf); \ - if (!elm_layout_content_set(obj, part_name, object_ptn)) \ - evas_object_hide(object_ptn); \ +#define SWALLOW(part_name, object_ptn) \ + if (object_ptn) \ + { \ + elm_widget_style_set(object_ptn, buf); \ + if (edje_object_part_swallow(wd->edje, part_name, object_ptn)) \ + evas_object_show(object_ptn); \ + else \ + evas_object_hide(object_ptn); \ } + SWALLOW("elm.swallow.up", wd->up_button); + SWALLOW("elm.swallow.home", wd->home_button); - SWALLOW("elm.swallow.up", sd->up_button); - SWALLOW("elm.swallow.home", sd->home_button); - - if (sd->mode == ELM_FILESELECTOR_LIST) + if (wd->mode == ELM_FILESELECTOR_LIST) { - if (elm_layout_content_set(obj, "elm.swallow.files", sd->files_list)) - evas_object_hide(sd->files_grid); - else evas_object_hide(sd->files_list); + if (edje_object_part_swallow(wd->edje, "elm.swallow.files", + wd->files_list)) + { + evas_object_show(wd->files_list); + evas_object_hide(wd->files_grid); + } + else + evas_object_hide(wd->files_list); } else { - if (elm_layout_content_set(obj, "elm.swallow.files", sd->files_grid)) - evas_object_hide(sd->files_list); - else evas_object_hide(sd->files_grid); + if (edje_object_part_swallow(wd->edje, "elm.swallow.files", + wd->files_grid)) + { + evas_object_show(wd->files_grid); + evas_object_hide(wd->files_list); + } + else + evas_object_hide(wd->files_grid); } - SWALLOW("elm.swallow.filename", sd->filename_entry); - SWALLOW("elm.swallow.path", sd->path_entry); + SWALLOW("elm.swallow.filename", wd->filename_entry); + SWALLOW("elm.swallow.path", wd->path_entry); snprintf(buf, sizeof(buf), "fileselector/actions/%s", style); - SWALLOW("elm.swallow.cancel", sd->cancel_button); - SWALLOW("elm.swallow.ok", sd->ok_button); - + SWALLOW("elm.swallow.cancel", wd->cancel_button); + SWALLOW("elm.swallow.ok", wd->ok_button); #undef SWALLOW - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); - - return EINA_TRUE; + edje_object_message_signal_process(wd->edje); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + edje_object_scale_set + (wd->edje, elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); } -/*** GENLIST/GENGRID "MODEL" ***/ +/*** GENLIST "MODEL" ***/ static char * -_itc_text_get(void *data, - Evas_Object *obj __UNUSED__, - const char *source __UNUSED__) +_itc_text_get(void *data, + Evas_Object *obj __UNUSED__, + const char *source __UNUSED__) { - return elm_entry_utf8_to_markup - (ecore_file_file_get(data)); /* NOTE this will be free()'d by - * the caller */ + return elm_entry_utf8_to_markup(ecore_file_file_get(data)); /* NOTE this will be + * free() by the + * caller */ } static Evas_Object * -_itc_icon_folder_get(void *data __UNUSED__, +_itc_icon_folder_get(void *data __UNUSED__, Evas_Object *obj, - const char *source) + const char *source) { Evas_Object *ic; @@ -243,14 +264,15 @@ _itc_icon_folder_get(void *data __UNUSED__, ic = elm_icon_add(obj); elm_icon_standard_set(ic, "folder"); - evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, + 1, 1); return ic; } static Evas_Object * -_itc_icon_image_get(void *data, +_itc_icon_image_get(void *data, Evas_Object *obj, - const char *source) + const char *source) { const char *filename = data; Evas_Object *ic; @@ -261,14 +283,15 @@ _itc_icon_image_get(void *data, elm_icon_standard_set(ic, "image"); elm_icon_thumb_set(ic, filename, NULL); - evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, + 1, 1); return ic; } static Evas_Object * -_itc_icon_file_get(void *data __UNUSED__, +_itc_icon_file_get(void *data __UNUSED__, Evas_Object *obj, - const char *source) + const char *source) { Evas_Object *ic; @@ -277,7 +300,8 @@ _itc_icon_file_get(void *data __UNUSED__, ic = elm_icon_add(obj); elm_icon_standard_set(ic, "file"); - evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, + 1, 1); return ic; } @@ -290,33 +314,233 @@ _itc_state_get(void *data __UNUSED__, } static void -_itc_del(void *data, +_itc_del(void *data, Evas_Object *obj __UNUSED__) { eina_stringshare_del(data); } static void -_anchors_do(Evas_Object *obj, - const char *path) +_expand_done(void *data, + Evas_Object *obj __UNUSED__, + void *event_info) { - char **tok, buf[PATH_MAX * 3], *s; - int i, j; + Elm_Object_Item *it = event_info; + const char *path = elm_object_item_data_get(it); + _populate(data, path, it); +} + +static void +_contract_done(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info) +{ + Elm_Object_Item *it = event_info; + elm_genlist_item_subitems_clear(it); +} + +static void +_expand_req(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info) +{ + Elm_Object_Item *it = event_info; + elm_genlist_item_expanded_set(it, EINA_TRUE); +} + +static void +_contract_req(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info) +{ + Elm_Object_Item *it = event_info; + elm_genlist_item_expanded_set(it, EINA_FALSE); +} + +/*** PRIVATES ***/ +static Eina_Bool +_sel_do(void *data) +{ + struct sel_data *sd; + const char *path; + Widget_Data *wd; + const char *p; - ELM_FILESELECTOR_DATA_GET(obj, sd); + sd = data; + wd = elm_widget_data_get(sd->fs); + path = sd->path; + if ((!wd->only_folder) && ecore_file_is_dir(path)) + { + if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST) + { + _do_anchors(sd->fs, path); + elm_object_text_set(wd->filename_entry, ""); + } + else + { + /* keep a ref to path 'couse it will be destroyed by _populate */ + p = eina_stringshare_add(path); + _populate(sd->fs, p, NULL); + eina_stringshare_del(p); + } + goto end; + } + else /* navigating through folders only or file is not a dir. */ + { + char *s; + + if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST) + _do_anchors(sd->fs, path); + else if (wd->only_folder) + { + /* keep a ref to path 'couse it will be destroyed by _populate */ + p = eina_stringshare_add(path); + _populate(sd->fs, p, NULL); + eina_stringshare_del(p); + } + s = elm_entry_utf8_to_markup(ecore_file_file_get(path)); + if (s) + { + elm_object_text_set(wd->filename_entry, s); + free(s); + } + else + elm_object_text_set(wd->filename_entry, ""); + } + + evas_object_smart_callback_call(sd->fs, SIG_SELECTED, (void *)path); + +end: + wd->sel_idler = NULL; + free(sd); + return ECORE_CALLBACK_CANCEL; +} + +static void +_sel(void *data, + Evas_Object *obj __UNUSED__, + void *event_info) +{ + struct sel_data *sd; + Widget_Data *wd; + void *old_sd; + char *dir; + //This event_info could be a list or gengrid item + Elm_Object_Item *it = event_info; + + wd = elm_widget_data_get(data); + if (!wd) return; + + sd = malloc(sizeof(*sd)); + sd->fs = data; + sd->path = elm_object_item_data_get(it); + + if (!sd->path) + { + eina_stringshare_replace(&wd->path, ""); + goto end; + } + + dir = wd->only_folder ? strdup(sd->path) : ecore_file_dir_get(sd->path); + if (dir) + { + eina_stringshare_replace(&wd->path, dir); + free(dir); + } + else + { + eina_stringshare_replace(&wd->path, ""); + } + +end: + if (wd->sel_idler) + { + old_sd = ecore_idler_del(wd->sel_idler); + free(old_sd); + } + wd->sel_idler = ecore_idler_add(_sel_do, sd); +} + +static void +_up(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *fs = data; + char *parent; + + Widget_Data *wd = elm_widget_data_get(fs); + if (!wd) return; + parent = ecore_file_dir_get(wd->path); + _populate(fs, parent, NULL); + free(parent); +} + +static void +_home(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *fs = data; + _populate(fs, getenv("HOME"), NULL); +} + +static void +_ok(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *fs = data; + evas_object_smart_callback_call(fs, SIG_DONE, + (void *)elm_fileselector_selected_get(fs)); +} + +static void +_canc(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *fs = data; + evas_object_smart_callback_call(fs, SIG_DONE, NULL); +} + +static void +_anchor_clicked(void *data, + Evas_Object *obj __UNUSED__, + void *event_info) +{ + Evas_Object *fs = data; + Widget_Data *wd = elm_widget_data_get(fs); + Elm_Entry_Anchor_Info *info = event_info; + const char *p; + if (!wd) return; + // keep a ref to path 'couse it will be destroyed by _populate + p = eina_stringshare_add(info->name); + _populate(fs, p, NULL); + evas_object_smart_callback_call(data, SIG_SELECTED, (void *)p); + eina_stringshare_del(p); +} + +static void +_do_anchors(Evas_Object *obj, + const char *path) +{ + Widget_Data *wd = elm_widget_data_get(obj); + char **tok, buf[PATH_MAX * 3], *s; + int i, j; + + if (!wd) return; s = elm_entry_utf8_to_markup(path); if (!s) return; - buf[0] = '\0'; tok = eina_str_split(s, "/", 0); free(s); - eina_strlcat(buf, "<a href=/>root</a>", sizeof(buf)); for (i = 0; tok[i]; i++) { if ((!tok[i]) || (!tok[i][0])) continue; - eina_strlcat(buf, sd->path_separator, sizeof(buf)); + eina_strlcat(buf, wd->path_separator, sizeof(buf)); eina_strlcat(buf, "<a href=", sizeof(buf)); for (j = 0; j <= i; j++) { @@ -331,14 +555,12 @@ _anchors_do(Evas_Object *obj, free(tok[0]); free(tok); - elm_object_text_set(sd->path_entry, buf); + elm_object_text_set(wd->path_entry, buf); } #ifdef HAVE_EIO static Eina_Bool -_ls_filter_cb(void *data __UNUSED__, - Eio_File *handler, - const Eina_File_Direct_Info *info) +_filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info *info) { const char *filename; @@ -346,32 +568,24 @@ _ls_filter_cb(void *data __UNUSED__, return EINA_FALSE; filename = eina_stringshare_add(info->path); - eio_file_associate_direct_add - (handler, "filename", filename, EINA_FREE_CB(eina_stringshare_del)); + eio_file_associate_direct_add(handler, "filename", filename, EINA_FREE_CB(eina_stringshare_del)); if (info->type == EINA_FILE_DIR) { - eio_file_associate_direct_add - (handler, "type/grid", grid_itc[ELM_DIRECTORY], NULL); - eio_file_associate_direct_add - (handler, "type/list", list_itc[ELM_DIRECTORY], NULL); + eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_DIRECTORY], NULL); + eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_DIRECTORY], NULL); } else { - if (evas_object_image_extension_can_load_get - (info->path + info->name_start)) + if (evas_object_image_extension_can_load_get(info->path + info->name_start)) { - eio_file_associate_direct_add - (handler, "type/grid", grid_itc[ELM_FILE_IMAGE], NULL); - eio_file_associate_direct_add - (handler, "type/list", list_itc[ELM_FILE_IMAGE], NULL); + eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_IMAGE], NULL); + eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_IMAGE], NULL); } else { - eio_file_associate_direct_add - (handler, "type/grid", grid_itc[ELM_FILE_UNKNOW], NULL); - eio_file_associate_direct_add - (handler, "type/list", list_itc[ELM_FILE_UNKNOW], NULL); + eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_UNKNOW], NULL); + eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_UNKNOW], NULL); } } @@ -379,8 +593,7 @@ _ls_filter_cb(void *data __UNUSED__, } static int -_file_grid_cmp(const void *a, - const void *b) +_file_grid_cmp(const void *a, const void *b) { const Elm_Object_Item *ga = a; const Elm_Object_Item *gb = b; @@ -401,8 +614,7 @@ _file_grid_cmp(const void *a, } static int -_file_list_cmp(const void *a, - const void *b) +_file_list_cmp(const void *a, const void *b) { const Elm_Object_Item *la = a; const Elm_Object_Item *lb = b; @@ -423,451 +635,244 @@ _file_list_cmp(const void *a, } static void -_signal_first(Listing_Request *lreq) +_signal_first(Widget_Request *wr) { - if (!lreq->first) return; - - evas_object_smart_callback_call - (lreq->obj, SIG_DIRECTORY_OPEN, (void *)lreq->path); - - if (!lreq->parent_it) + if (!wr->first) return ; + evas_object_smart_callback_call(wr->obj, SIG_DIRECTORY_OPEN, (void *)wr->path); + if (!wr->parent) { - elm_genlist_clear(lreq->sd->files_list); - elm_gengrid_clear(lreq->sd->files_grid); - eina_stringshare_replace(&lreq->sd->path, lreq->path); - _anchors_do(lreq->obj, lreq->path); + elm_genlist_clear(wr->wd->files_list); + elm_gengrid_clear(wr->wd->files_grid); + eina_stringshare_replace(&wr->wd->path, wr->path); + _do_anchors(wr->obj, wr->path); } - if (lreq->sd->filename_entry) - elm_object_text_set(lreq->sd->filename_entry, ""); + if (wr->wd->filename_entry) elm_object_text_set(wr->wd->filename_entry, ""); - lreq->first = EINA_FALSE; + wr->first = EINA_FALSE; } static void -_ls_main_cb(void *data, - Eio_File *handler, - const Eina_File_Direct_Info *info __UNUSED__) +_main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info __UNUSED__) { - Listing_Request *lreq = data; + Widget_Request *wr = data; - if (eio_file_check(handler)) return; - - if (!lreq->sd->files_list || !lreq->sd->files_grid - || lreq->sd->current != handler) + if (eio_file_check(handler)) + return ; + if (!wr->wd->files_list || !wr->wd->files_grid || wr->wd->current != handler) { eio_file_cancel(handler); - return; + return ; } - _signal_first(lreq); + _signal_first(wr); - if (lreq->sd->mode == ELM_FILESELECTOR_LIST) + if (wr->wd->mode == ELM_FILESELECTOR_LIST) { - Eina_Bool is_dir = (eio_file_associate_find(handler, "type/list") - == list_itc[ELM_DIRECTORY]); - - elm_genlist_item_sorted_insert - (lreq->sd->files_list, eio_file_associate_find(handler, "type/list"), - eina_stringshare_ref(eio_file_associate_find - (handler, "filename")), - lreq->parent_it, lreq->sd->expand && is_dir ? ELM_GENLIST_ITEM_TREE - : ELM_GENLIST_ITEM_NONE, _file_list_cmp, NULL, NULL); + Eina_Bool is_dir = (eio_file_associate_find(handler, "type/list") == list_itc[ELM_DIRECTORY]); + + elm_genlist_item_sorted_insert(wr->wd->files_list, eio_file_associate_find(handler, "type/list"), + eina_stringshare_ref(eio_file_associate_find(handler, "filename")), + wr->parent, wr->wd->expand && is_dir ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE, + _file_list_cmp, NULL, NULL); } - else if (lreq->sd->mode == ELM_FILESELECTOR_GRID) - elm_gengrid_item_sorted_insert - (lreq->sd->files_grid, eio_file_associate_find(handler, "type/grid"), - eina_stringshare_ref(eio_file_associate_find(handler, "filename")), - _file_grid_cmp, NULL, NULL); + else if (wr->wd->mode == ELM_FILESELECTOR_GRID) + elm_gengrid_item_sorted_insert(wr->wd->files_grid, eio_file_associate_find(handler, "type/grid"), + eina_stringshare_ref(eio_file_associate_find(handler, "filename")), + _file_grid_cmp, NULL, NULL); } static void -_listing_request_cleanup(Listing_Request *lreq) +_widget_request_cleanup(Widget_Request *wr) { - EINA_REFCOUNT_UNREF(lreq->sd) _elm_fileselector_smart_del_do(lreq->sd); + EINA_REFCOUNT_UNREF(wr->wd) + _widget_data_free(wr->wd); - eina_stringshare_del(lreq->path); - free(lreq); + eina_stringshare_del(wr->path); + free(wr); } static void -_ls_done_cb(void *data, Eio_File *handler __UNUSED__) +_done_cb(void *data, Eio_File *handler __UNUSED__) { - Listing_Request *lreq = data; + Widget_Request *wr = data; - _signal_first(lreq); + _signal_first(wr); - lreq->sd->current = NULL; - _listing_request_cleanup(lreq); + wr->wd->current = NULL; + _widget_request_cleanup(wr); } static void -_ls_error_cb(void *data, Eio_File *handler, int error __UNUSED__) +_error_cb(void *data, Eio_File *handler, int error __UNUSED__) { - Listing_Request *lreq = data; + Widget_Request *wr = data; - if (lreq->sd->current == handler) - lreq->sd->current = NULL; - _listing_request_cleanup(lreq); + if (wr->wd->current == handler) + wr->wd->current = NULL; + _widget_request_cleanup(wr); } #endif static void -_populate(Evas_Object *obj, - const char *path, - Elm_Object_Item *parent_it) +_populate(Evas_Object *obj, + const char *path, + Elm_Object_Item *parent) { - ELM_FILESELECTOR_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); #ifdef HAVE_EIO - Listing_Request *lreq; + Widget_Request *wr; #else - Eina_List *files = NULL, *dirs = NULL; Eina_File_Direct_Info *file; Eina_Iterator *it; - const char *entry; + const char *real; + Eina_List *files = NULL, *dirs = NULL; #endif -#ifndef HAVE_EIO /* synchronous listing path */ - if (!ecore_file_is_dir(path)) return; - + if (!wd) return; +#ifndef HAVE_EIO + if (!ecore_file_is_dir(path)) return ; it = eina_file_stat_ls(path); - if (!it) return; - + if (!it) return ; evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void *)path); - if (!parent_it) + if (!parent) { - elm_genlist_clear(sd->files_list); - elm_gengrid_clear(sd->files_grid); - eina_stringshare_replace(&sd->path, path); - _anchors_do(obj, path); + elm_genlist_clear(wd->files_list); + elm_gengrid_clear(wd->files_grid); + eina_stringshare_replace(&wd->path, path); + _do_anchors(obj, path); } - if (sd->filename_entry) elm_object_text_set(sd->filename_entry, ""); - EINA_ITERATOR_FOREACH (it, file) + if (wd->filename_entry) elm_object_text_set(wd->filename_entry, ""); + EINA_ITERATOR_FOREACH(it, file) { const char *filename; - if (file->path[file->name_start] == '.') continue; + if (file->path[file->name_start] == '.') + continue ; filename = eina_stringshare_add(file->path); if (file->type == EINA_FILE_DIR) dirs = eina_list_append(dirs, filename); - else if (!sd->only_folder) + else if (!wd->only_folder) files = eina_list_append(files, filename); } eina_iterator_free(it); - files = eina_list_sort - (files, eina_list_count(files), EINA_COMPARE_CB(strcoll)); - - dirs = eina_list_sort - (dirs, eina_list_count(dirs), EINA_COMPARE_CB(strcoll)); - EINA_LIST_FREE (dirs, entry) + files = eina_list_sort(files, eina_list_count(files), + EINA_COMPARE_CB(strcoll)); + dirs = eina_list_sort(dirs, eina_list_count(dirs), EINA_COMPARE_CB(strcoll)); + EINA_LIST_FREE(dirs, real) { - if (sd->mode == ELM_FILESELECTOR_LIST) - elm_genlist_item_append(sd->files_list, list_itc[ELM_DIRECTORY], - entry, /* item data */ - parent_it, - sd->expand ? ELM_GENLIST_ITEM_TREE : + if (wd->mode == ELM_FILESELECTOR_LIST) + elm_genlist_item_append(wd->files_list, list_itc[ELM_DIRECTORY], + real, /* item data */ + parent, + wd->expand ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE, NULL, NULL); - else if (sd->mode == ELM_FILESELECTOR_GRID) - elm_gengrid_item_append(sd->files_grid, grid_itc[ELM_DIRECTORY], - entry, /* item data */ + else if (wd->mode == ELM_FILESELECTOR_GRID) + elm_gengrid_item_append(wd->files_grid, grid_itc[ELM_DIRECTORY], + real, /* item data */ NULL, NULL); } - EINA_LIST_FREE (files, entry) + EINA_LIST_FREE(files, real) { - Elm_Fileselector_Type type = - evas_object_image_extension_can_load_fast_get(entry) ? + Elm_Fileselector_Type type = evas_object_image_extension_can_load_fast_get(real) ? ELM_FILE_IMAGE : ELM_FILE_UNKNOW; - if (sd->mode == ELM_FILESELECTOR_LIST) - elm_genlist_item_append(sd->files_list, list_itc[type], - entry, /* item data */ - parent_it, ELM_GENLIST_ITEM_NONE, + if (wd->mode == ELM_FILESELECTOR_LIST) + elm_genlist_item_append(wd->files_list, list_itc[type], + real, /* item data */ + parent, ELM_GENLIST_ITEM_NONE, NULL, NULL); - else if (sd->mode == ELM_FILESELECTOR_GRID) - elm_gengrid_item_append(sd->files_grid, grid_itc[type], - entry, /* item data */ + else if (wd->mode == ELM_FILESELECTOR_GRID) + elm_gengrid_item_append(wd->files_grid, grid_itc[type], + real, /* item data */ NULL, NULL); } - -#else /* asynchronous listing path */ - if (sd->expand && sd->current) return; - - if (sd->current) eio_file_cancel(sd->current); - - lreq = malloc(sizeof (Listing_Request)); - if (!lreq) return; - - lreq->sd = sd; - EINA_REFCOUNT_REF(lreq->sd); - - lreq->parent_it = parent_it; /* FIXME: should we refcount the parent_it ? */ - lreq->obj = obj; - lreq->path = eina_stringshare_add(path); - lreq->first = EINA_TRUE; - - sd->current = eio_file_stat_ls(path, _ls_filter_cb, _ls_main_cb, - _ls_done_cb, _ls_error_cb, lreq); +#else + if (wd->expand && wd->current) return ; + if (wd->current) + eio_file_cancel(wd->current); + wr = malloc(sizeof (Widget_Request)); + if (!wr) return ; + wr->wd = wd; + EINA_REFCOUNT_REF(wr->wd); + wr->parent = parent; /* FIXME: should we refcount the parent ? */ + wr->obj = obj; + wr->path = eina_stringshare_add(path); + wr->first = EINA_TRUE; + + wd->current = eio_file_stat_ls(path, + _filter_cb, + _main_cb, + _done_cb, + _error_cb, + wr); #endif } -static void -_on_list_expanded(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Elm_Object_Item *it = event_info; - const char *path = elm_object_item_data_get(it); - - _populate(data, path, it); -} +/*** API ***/ -static void -_on_list_contracted(void *data __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Elm_Object_Item *it = event_info; - - elm_genlist_item_subitems_clear(it); -} - -static void -_on_list_expand_req(void *data __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Elm_Object_Item *it = event_info; - - elm_genlist_item_expanded_set(it, EINA_TRUE); -} - -static void -_on_list_contract_req(void *data __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Elm_Object_Item *it = event_info; - - elm_genlist_item_expanded_set(it, EINA_FALSE); -} - -static Eina_Bool -_sel_do(void *data) -{ - struct sel_data *sdata = data; - const char *path; - const char *p; - - ELM_FILESELECTOR_DATA_GET(sdata->fs, sd); - path = sdata->path; - - if ((!sd->only_folder) && ecore_file_is_dir(path)) - { - if (sd->expand && sd->mode == ELM_FILESELECTOR_LIST) - { - _anchors_do(sdata->fs, path); - elm_object_text_set(sd->filename_entry, ""); - } - else - { - /* keep a ref to path 'couse it will be destroyed by _populate */ - p = eina_stringshare_add(path); - _populate(sdata->fs, p, NULL); - eina_stringshare_del(p); - } - goto end; - } - else /* navigating through folders only or file is not a dir. */ - { - char *s; - - if (sd->expand && sd->mode == ELM_FILESELECTOR_LIST) - _anchors_do(sdata->fs, path); - else if (sd->only_folder) - { - /* keep a ref to path 'couse it will be destroyed by _populate */ - p = eina_stringshare_add(path); - _populate(sdata->fs, p, NULL); - eina_stringshare_del(p); - } - - s = elm_entry_utf8_to_markup(ecore_file_file_get(path)); - if (s) - { - elm_object_text_set(sd->filename_entry, s); - free(s); - } - else elm_object_text_set(sd->filename_entry, ""); - } - - evas_object_smart_callback_call(sdata->fs, SIG_SELECTED, (void *)path); - -end: - sd->sel_idler = NULL; - free(sdata); - return ECORE_CALLBACK_CANCEL; -} - -static void -_on_item_selected(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - //This event_info could be a list or gengrid item - Elm_Object_Item *it = event_info; - struct sel_data *sdata; - void *old_sd; - char *dir; - - ELM_FILESELECTOR_DATA_GET(data, sd); - - sdata = malloc(sizeof(*sdata)); - sdata->fs = data; - sdata->path = elm_object_item_data_get(it); - - if (!sdata->path) - { - eina_stringshare_replace(&sd->path, ""); - goto end; - } - - dir = sd->only_folder ? strdup(sdata->path) : - ecore_file_dir_get(sdata->path); - if (dir) - { - eina_stringshare_replace(&sd->path, dir); - free(dir); - } - else - { - eina_stringshare_replace(&sd->path, ""); - } - -end: - if (sd->sel_idler) - { - old_sd = ecore_idler_del(sd->sel_idler); - free(old_sd); - } - sd->sel_idler = ecore_idler_add(_sel_do, sdata); -} - -static void -_on_dir_up(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Evas_Object *fs = data; - char *parent; - - ELM_FILESELECTOR_DATA_GET(fs, sd); - - parent = ecore_file_dir_get(sd->path); - _populate(fs, parent, NULL); - free(parent); -} - -static void -_home(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Evas_Object *fs = data; - - _populate(fs, getenv("HOME"), NULL); -} - -static void -_ok(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Evas_Object *fs = data; - - evas_object_smart_callback_call - (fs, SIG_DONE, (void *)elm_fileselector_selected_get(fs)); -} - -static void -_canc(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Evas_Object *fs = data; - - evas_object_smart_callback_call(fs, SIG_DONE, NULL); -} - -static void -_anchor_clicked(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Elm_Entry_Anchor_Info *info = event_info; - Evas_Object *fs = data; - const char *p; - - // keep a ref to path 'couse it will be destroyed by _populate - p = eina_stringshare_add(info->name); - _populate(fs, p, NULL); - evas_object_smart_callback_call(data, SIG_SELECTED, (void *)p); - eina_stringshare_del(p); -} - -static void -_elm_fileselector_smart_add(Evas_Object *obj) +EAPI Evas_Object * +elm_fileselector_add(Evas_Object *parent) { - Evas_Object *ic, *bt, *li, *en, *grid; + Evas *e; + Evas_Object *obj, *ic, *bt, *li, *en, *grid; + Widget_Data *wd; unsigned int i; int s; - EVAS_SMART_DATA_ALLOC(obj, Elm_Fileselector_Smart_Data); - EINA_REFCOUNT_INIT(priv); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - ELM_WIDGET_CLASS(_elm_fileselector_parent_sc)->base.add(obj); + EINA_REFCOUNT_INIT(wd); + ELM_SET_WIDTYPE(widtype, "fileselector"); + elm_widget_type_set(obj, "fileselector"); + elm_widget_sub_object_add(parent, obj); + 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, EINA_FALSE); - priv->expand = !!_elm_config->fileselector_expand_enable; + wd->expand = !!_elm_config->fileselector_expand_enable; - elm_layout_theme_set - (obj, "fileselector", "base", elm_widget_style_get(obj)); + wd->edje = edje_object_add(e); + _elm_theme_object_set(obj, wd->edje, "fileselector", "base", "default"); + elm_widget_resize_object_set(obj, wd->edje); // up btn - ic = elm_icon_add(obj); + ic = elm_icon_add(parent); elm_icon_standard_set(ic, "arrow_up"); evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); - bt = elm_button_add(obj); + bt = elm_button_add(parent); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_object_part_content_set(bt, "icon", ic); elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Up")); evas_object_size_hint_align_set(bt, 0.0, 0.0); - evas_object_smart_callback_add(bt, "clicked", _on_dir_up, obj); - elm_widget_sub_object_add(obj, bt); + evas_object_smart_callback_add(bt, "clicked", _up, obj); - priv->up_button = bt; + elm_widget_sub_object_add(obj, bt); + wd->up_button = bt; // home btn - ic = elm_icon_add(obj); + ic = elm_icon_add(parent); elm_icon_standard_set(ic, "home"); evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); - bt = elm_button_add(obj); + bt = elm_button_add(parent); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_object_part_content_set(bt, "icon", ic); elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Home")); evas_object_size_hint_align_set(bt, 0.0, 0.0); + evas_object_smart_callback_add(bt, "clicked", _home, obj); elm_widget_sub_object_add(obj, bt); - priv->home_button = bt; + wd->home_button = bt; for (i = 0; i < ELM_FILE_LAST; ++i) { @@ -875,10 +880,8 @@ _elm_fileselector_smart_add(Evas_Object *obj) grid_itc[i] = elm_gengrid_item_class_new(); list_itc[i]->item_style = "default"; - list_itc[i]->func.text_get = grid_itc[i]->func.text_get = - _itc_text_get; - list_itc[i]->func.state_get = grid_itc[i]->func.state_get = - _itc_state_get; + list_itc[i]->func.text_get = grid_itc[i]->func.text_get = _itc_text_get; + list_itc[i]->func.state_get = grid_itc[i]->func.state_get = _itc_state_get; list_itc[i]->func.del = grid_itc[i]->func.del = _itc_del; } @@ -889,39 +892,37 @@ _elm_fileselector_smart_add(Evas_Object *obj) list_itc[ELM_FILE_UNKNOW]->func.content_get = grid_itc[ELM_FILE_UNKNOW]->func.content_get = _itc_icon_file_get; - li = elm_genlist_add(obj); + li = elm_genlist_add(parent); elm_widget_mirrored_automatic_set(li, EINA_FALSE); evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_min_set(li, 100, 100); - grid = elm_gengrid_add(obj); + grid = elm_gengrid_add(parent); elm_widget_mirrored_automatic_set(grid, EINA_FALSE); evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); // XXX: will fail for dynamic finger size changing - s = elm_config_finger_size_get() * 2; + s = _elm_config->finger_size * 2; elm_gengrid_item_size_set(grid, s, s); elm_gengrid_align_set(grid, 0.0, 0.0); - evas_object_smart_callback_add(li, "selected", _on_item_selected, obj); - evas_object_smart_callback_add - (li, "expand,request", _on_list_expand_req, obj); - evas_object_smart_callback_add - (li, "contract,request", _on_list_contract_req, obj); - evas_object_smart_callback_add(li, "expanded", _on_list_expanded, obj); - evas_object_smart_callback_add(li, "contracted", _on_list_contracted, obj); + evas_object_smart_callback_add(li, "selected", _sel, obj); + evas_object_smart_callback_add(li, "expand,request", _expand_req, obj); + evas_object_smart_callback_add(li, "contract,request", _contract_req, obj); + evas_object_smart_callback_add(li, "expanded", _expand_done, obj); + evas_object_smart_callback_add(li, "contracted", _contract_done, obj); - evas_object_smart_callback_add(grid, "selected", _on_item_selected, obj); + evas_object_smart_callback_add(grid, "selected", _sel, obj); elm_widget_sub_object_add(obj, li); elm_widget_sub_object_add(obj, grid); - priv->files_list = li; - priv->files_grid = grid; + wd->files_list = li; + wd->files_grid = grid; // path entry - en = elm_entry_add(obj); + en = elm_entry_add(parent); elm_entry_scrollable_set(en, EINA_TRUE); elm_widget_mirrored_automatic_set(en, EINA_FALSE); elm_entry_editable_set(en, EINA_FALSE); @@ -933,10 +934,10 @@ _elm_fileselector_smart_add(Evas_Object *obj) evas_object_smart_callback_add(en, "anchor,clicked", _anchor_clicked, obj); elm_widget_sub_object_add(obj, en); - priv->path_entry = en; + wd->path_entry = en; // filename entry - en = elm_entry_add(obj); + en = elm_entry_add(parent); elm_entry_scrollable_set(en, EINA_TRUE); elm_widget_mirrored_automatic_set(en, EINA_FALSE); elm_entry_editable_set(en, EINA_TRUE); @@ -946,121 +947,71 @@ _elm_fileselector_smart_add(Evas_Object *obj) evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_widget_sub_object_add(obj, en); - priv->filename_entry = en; + wd->filename_entry = en; elm_fileselector_buttons_ok_cancel_set(obj, EINA_TRUE); elm_fileselector_is_save_set(obj, EINA_FALSE); - _elm_fileselector_smart_theme(obj); -} - -static void -_elm_fileselector_smart_del(Evas_Object *obj) -{ - int i; - - ELM_FILESELECTOR_DATA_GET(obj, sd); - - for (i = 0; i < ELM_FILE_LAST; ++i) - { - elm_genlist_item_class_free(list_itc[i]); - elm_gengrid_item_class_free(grid_itc[i]); - } - -#ifdef HAVE_EIO - if (sd->current) eio_file_cancel(sd->current); -#endif - - sd->files_list = NULL; - sd->files_grid = NULL; - - /* this one matching EINA_REFCOUNT_INIT() */ - EINA_REFCOUNT_UNREF(sd) _elm_fileselector_smart_del_do(sd); -} - -static void -_elm_fileselector_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_fileselector_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_fileselector_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_fileselector_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_fileselector_smart_sizing_eval; -} - -EAPI Evas_Object * -elm_fileselector_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_fileselector_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + _theme_hook(obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } EAPI void elm_fileselector_is_save_set(Evas_Object *obj, - Eina_Bool is_save) + Eina_Bool is_save) { - ELM_FILESELECTOR_CHECK(obj); - ELM_FILESELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - elm_object_disabled_set(sd->filename_entry, !is_save); + elm_object_disabled_set(wd->filename_entry, !is_save); - if (is_save) elm_layout_signal_emit(obj, "elm,state,save,on", "elm"); - else elm_layout_signal_emit(obj, "elm,state,save,off", "elm"); + if (is_save) + edje_object_signal_emit(wd->edje, "elm,state,save,on", "elm"); + else + edje_object_signal_emit(wd->edje, "elm,state,save,off", "elm"); } EAPI Eina_Bool elm_fileselector_is_save_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - return !elm_object_disabled_get(sd->filename_entry); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return !elm_object_disabled_get(wd->filename_entry); } EAPI void elm_fileselector_folder_only_set(Evas_Object *obj, - Eina_Bool only) + Eina_Bool only) { - ELM_FILESELECTOR_CHECK(obj); - ELM_FILESELECTOR_DATA_GET(obj, sd); - - if (sd->only_folder == only) return; - - sd->only_folder = !!only; - if (sd->path) _populate(obj, sd->path, NULL); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->only_folder == only) return; + wd->only_folder = !!only; + if (wd->path) _populate(obj, wd->path, NULL); } EAPI Eina_Bool elm_fileselector_folder_only_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - return sd->only_folder; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->only_folder; } EAPI void elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, - Eina_Bool visible) + Eina_Bool visible) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); Evas_Object *bt; - - ELM_FILESELECTOR_CHECK(obj); - ELM_FILESELECTOR_DATA_GET(obj, sd); + if (!wd) return; if (visible) { @@ -1072,7 +1023,7 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, evas_object_smart_callback_add(bt, "clicked", _canc, obj); elm_widget_sub_object_add(obj, bt); - sd->cancel_button = bt; + wd->cancel_button = bt; // ok btn bt = elm_button_add(obj); @@ -1082,57 +1033,58 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, evas_object_smart_callback_add(bt, "clicked", _ok, obj); elm_widget_sub_object_add(obj, bt); - sd->ok_button = bt; + wd->ok_button = bt; - _elm_fileselector_smart_theme(obj); + _theme_hook(obj); } else { - evas_object_del(sd->cancel_button); - sd->cancel_button = NULL; - evas_object_del(sd->ok_button); - sd->ok_button = NULL; + evas_object_del(wd->cancel_button); + wd->cancel_button = NULL; + evas_object_del(wd->ok_button); + wd->ok_button = NULL; } } EAPI Eina_Bool elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - return sd->ok_button ? EINA_TRUE : EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->ok_button ? EINA_TRUE : EINA_FALSE; } EAPI void elm_fileselector_expandable_set(Evas_Object *obj, - Eina_Bool expand) + Eina_Bool expand) { - ELM_FILESELECTOR_CHECK(obj); - ELM_FILESELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return; - sd->expand = !!expand; + wd->expand = !!expand; - if (sd->path) _populate(obj, sd->path, NULL); + if (wd->path) _populate(obj, wd->path, NULL); } EAPI Eina_Bool elm_fileselector_expandable_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - return sd->expand; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->expand; } EAPI void elm_fileselector_path_set(Evas_Object *obj, - const char *_path) + const char *_path) { + ELM_CHECK_WIDTYPE(obj, widtype); char *path; - - ELM_FILESELECTOR_CHECK(obj); - path = ecore_file_realpath(_path); _populate(obj, path, NULL); free(path); @@ -1141,59 +1093,79 @@ elm_fileselector_path_set(Evas_Object *obj, EAPI const char * elm_fileselector_path_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) NULL; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - return sd->path; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->path; } EAPI void -elm_fileselector_mode_set(Evas_Object *obj, +elm_fileselector_mode_set(Evas_Object *obj, Elm_Fileselector_Mode mode) { - ELM_FILESELECTOR_CHECK(obj); + ELM_CHECK_WIDTYPE(obj, widtype); - ELM_FILESELECTOR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (mode == sd->mode) return; - - evas_object_hide(elm_layout_content_unset(obj, "elm.swallow.files")); + if (mode == wd->mode) return; if (mode == ELM_FILESELECTOR_LIST) - elm_layout_content_set(obj, "elm.swallow.files", sd->files_list); - else elm_layout_content_set(obj, "elm.swallow.files", sd->files_grid); + { + if (edje_object_part_swallow(wd->edje, "elm.swallow.files", + wd->files_list)) + { + evas_object_show(wd->files_list); + evas_object_hide(wd->files_grid); + } + else + evas_object_hide(wd->files_list); + } + else + { + if (edje_object_part_swallow(wd->edje, "elm.swallow.files", + wd->files_grid)) + { + evas_object_show(wd->files_grid); + evas_object_hide(wd->files_list); + } + else + evas_object_hide(wd->files_grid); + } - sd->mode = mode; + wd->mode = mode; - _populate(obj, sd->path, NULL); + _populate(obj, wd->path, NULL); } EAPI Elm_Fileselector_Mode elm_fileselector_mode_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) ELM_FILESELECTOR_LAST; - ELM_FILESELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) ELM_FILESELECTOR_LAST; - return sd->mode; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_FILESELECTOR_LAST; + + return wd->mode; } EAPI const char * elm_fileselector_selected_get(const Evas_Object *obj) { - ELM_FILESELECTOR_CHECK(obj) NULL; - ELM_FILESELECTOR_DATA_GET(obj, sd); - - if (!sd->path) return NULL; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - if (sd->filename_entry) + if (!wd->path) return NULL; + + if (wd->filename_entry) { - char buf[PATH_MAX]; const char *name; + char buf[PATH_MAX]; char *dir, *s; - dir = sd->only_folder ? ecore_file_dir_get(sd->path) - : strdup(sd->path); - name = elm_object_text_get(sd->filename_entry); + dir = wd->only_folder ? ecore_file_dir_get(wd->path) : strdup(wd->path); + name = elm_object_text_get(wd->filename_entry); if (name) { s = elm_entry_markup_to_utf8(name); @@ -1202,47 +1174,49 @@ elm_fileselector_selected_get(const Evas_Object *obj) snprintf(buf, sizeof(buf), "%s/%s", dir, s); free(s); } - else snprintf(buf, sizeof(buf), "%s", dir); + else + snprintf(buf, sizeof(buf), "%s", dir); } - else snprintf(buf, sizeof(buf), "%s", dir); - - if (sd->only_folder && !ecore_file_is_dir(buf)) - eina_stringshare_replace(&sd->selection, ecore_file_dir_get(buf)); - else eina_stringshare_replace(&sd->selection, buf); - + else + { + snprintf(buf, sizeof(buf), "%s", dir); + } + if (wd->only_folder && !ecore_file_is_dir(buf)) + eina_stringshare_replace(&wd->selection, ecore_file_dir_get(buf)); + else + eina_stringshare_replace(&wd->selection, buf); if (dir) free(dir); - return sd->selection; + return wd->selection; } - if (sd->mode == ELM_FILESELECTOR_LIST) + if (wd->mode == ELM_FILESELECTOR_LIST) { - Elm_Object_Item *gl_it = elm_genlist_selected_item_get(sd->files_list); - + Elm_Object_Item *gl_it = elm_genlist_selected_item_get(wd->files_list); if (gl_it) return elm_object_item_data_get(gl_it); } else { - Elm_Object_Item *gg_it = elm_gengrid_selected_item_get(sd->files_grid); - + Elm_Object_Item *gg_it = elm_gengrid_selected_item_get(wd->files_grid); if (gg_it) return elm_object_item_data_get(gg_it); } - return sd->path; + return wd->path; } EAPI Eina_Bool elm_fileselector_selected_set(Evas_Object *obj, - const char *_path) + const char *_path) { + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + Eina_Bool ret = EINA_TRUE; char *path; - - ELM_FILESELECTOR_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_DATA_GET(obj, sd); - path = ecore_file_realpath(_path); - if (ecore_file_is_dir(path)) _populate(obj, path, NULL); + if (ecore_file_is_dir(path)) + _populate(obj, path, NULL); else { if (!ecore_file_exists(path)) @@ -1252,19 +1226,19 @@ elm_fileselector_selected_set(Evas_Object *obj, } _populate(obj, ecore_file_dir_get(path), NULL); - if (sd->filename_entry) + if (wd->filename_entry) { char *s; - + s = elm_entry_utf8_to_markup(ecore_file_file_get(path)); if (s) { - elm_object_text_set(sd->filename_entry, s); + elm_object_text_set(wd->filename_entry, s); free(s); } - else elm_object_text_set(sd->filename_entry, ""); - - eina_stringshare_replace(&sd->selection, path); + else + elm_object_text_set(wd->filename_entry, ""); + eina_stringshare_replace(&wd->selection, path); } } @@ -1272,3 +1246,4 @@ clean_up: free(path); return ret; } + diff --git a/src/lib/elc_fileselector.h b/src/lib/elc_fileselector.h index 7e0a4e8f1..bf11c677f 100644 --- a/src/lib/elc_fileselector.h +++ b/src/lib/elc_fileselector.h @@ -31,11 +31,8 @@ * library, the second form of view will display preview thumbnails * of files which it supports. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for file selector objects. + * Smart callbacks one can register to: * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: * - @c "selected" - the user has clicked on a file (when not in * folders-only mode) or directory (when in folders-only mode) * - @c "directory,open" - the list has been populated with new diff --git a/src/lib/elc_fileselector_button.c b/src/lib/elc_fileselector_button.c index 2ae137811..a7c936d67 100644 --- a/src/lib/elc_fileselector_button.c +++ b/src/lib/elc_fileselector_button.c @@ -1,20 +1,13 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_button.h" -static const char FILESELECTOR_BUTTON_SMART_NAME[] = "elm_fileselector_button"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Fileselector_Button_Smart_Data \ - Elm_Fileselector_Button_Smart_Data; - -struct _Elm_Fileselector_Button_Smart_Data +struct _Widget_Data { - Elm_Button_Smart_Data base; - - Evas_Object *fs, *fsw; - const char *window_title; - Evas_Coord w, h; - + Evas_Object *self, *btn, *fs, *fsw; + const char *window_title; + Evas_Coord w, h; struct { const char *path; @@ -22,396 +15,507 @@ struct _Elm_Fileselector_Button_Smart_Data Eina_Bool folder_only : 1; Eina_Bool is_save : 1; } fsd; - - Eina_Bool inwin_mode : 1; + Eina_Bool inwin_mode : 1; }; #define DEFAULT_WINDOW_TITLE "Select a file" -#define ELM_FILESELECTOR_BUTTON_DATA_GET(o, sd) \ - Elm_Fileselector_Button_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_FILESELECTOR_BUTTON_DATA_GET_OR_RETURN(o, ptr) \ - ELM_FILESELECTOR_BUTTON_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_FILESELECTOR_BUTTON_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_FILESELECTOR_BUTTON_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_FILESELECTOR_BUTTON_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), FILESELECTOR_BUTTON_SMART_NAME, __func__)) \ - return +static const char *widtype = NULL; + +static void _del_pre_hook(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, + Evas *e, + Evas_Object *obj, + void *event_info); +static void _button_clicked(void *data, + Evas_Object *obj, + void *event_info); +static void _on_focus_hook(void *data, + Evas_Object *obj); +static void _selection_done(void *data, + Evas_Object *obj, + void *event_info); +static void _activate(Widget_Data *wd); static const char SIG_FILE_CHOSEN[] = "file,chosen"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_FILE_CHOSEN, "s"}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_FILE_CHOSEN, "s"}, + {NULL, NULL} }; -EVAS_SMART_SUBCLASS_NEW - (FILESELECTOR_BUTTON_SMART_NAME, _elm_fileselector_button, - Elm_Button_Smart_Class, Elm_Button_Smart_Class, elm_button_smart_class_get, - _smart_callbacks); +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_event_callback_del_full(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_smart_callback_del(wd->btn, "clicked", _button_clicked); +} -static Eina_Bool -_elm_fileselector_button_smart_theme(Evas_Object *obj) +static void +_del_hook(Evas_Object *obj) { - char buf[4096]; - const char *style; + Evas_Object *win; + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + if (wd->window_title) eina_stringshare_del(wd->window_title); + if (wd->fsd.path) eina_stringshare_del(wd->fsd.path); + if (wd->fs) + { + win = evas_object_data_del(obj, "win"); + evas_object_del(win); + } + free(wd); +} - style = eina_stringshare_add(elm_widget_style_get(obj)); +static void +_on_focus_hook(void *data __UNUSED__, + Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + elm_widget_focus_steal(wd->btn); +} - snprintf(buf, sizeof(buf), "fileselector_button/%s", style); +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_widget_mirrored_set(wd->btn, rtl); + elm_widget_mirrored_set(wd->fs, rtl); +} - /* file selector button's style has an extra bit */ - eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), buf); +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + char buf[4096]; + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + + snprintf(buf, sizeof(buf), "fileselector_button/%s", + elm_widget_style_get(obj)); + elm_object_style_set(wd->btn, buf); + _sizing_eval(obj); +} - if (!ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->theme(obj)) - return EINA_FALSE; +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_widget_disabled_set(wd->btn, elm_widget_disabled_get(obj)); +} - eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style); +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; + if (!wd) return; + evas_object_size_hint_min_get(wd->btn, &minw, &minh); + evas_object_size_hint_max_get(wd->btn, &maxw, &maxh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); +} - eina_stringshare_del(style); +static void +_changed_size_hints(void *data, + Evas *e __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + _sizing_eval(data); +} - return EINA_TRUE; +static void +_activate_hook(Evas_Object *obj) +{ + Widget_Data *wd; + wd = elm_widget_data_get(obj); + if (!wd) return; + _activate(wd); } static void -_selection_done(void *data, +_button_clicked(void *data, Evas_Object *obj __UNUSED__, - void *event_info) + void *event_info __UNUSED__) { - Elm_Fileselector_Button_Smart_Data *sd = data; - const char *file = event_info; - Evas_Object *del; - - if (file) eina_stringshare_replace(&sd->fsd.path, file); + _activate(data); +} - del = sd->fsw; - sd->fs = NULL; - sd->fsw = NULL; - evas_object_del(del); +static Evas_Object * +_parent_win_get(Evas_Object *obj) +{ + while ((obj) && (strcmp(elm_widget_type_get(obj), "win"))) + obj = elm_object_parent_widget_get(obj); - evas_object_smart_callback_call - (ELM_WIDGET_DATA(sd)->obj, SIG_FILE_CHOSEN, (void *)sd->fsd.path); + return obj; } static Evas_Object * -_new_window_add(Elm_Fileselector_Button_Smart_Data *sd) +_new_window_add(Widget_Data *wd) { Evas_Object *win, *bg; win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC); - elm_win_title_set(win, sd->window_title); + elm_win_title_set(win, wd->window_title); elm_win_autodel_set(win, EINA_TRUE); - evas_object_smart_callback_add(win, "delete,request", _selection_done, sd); + evas_object_smart_callback_add(win, "delete,request", _selection_done, wd); bg = elm_bg_add(win); elm_win_resize_object_add(win, bg); evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(bg); - evas_object_resize(win, sd->w, sd->h); + evas_object_resize(win, wd->w, wd->h); return win; } -static Evas_Object * -_parent_win_get(Evas_Object *obj) -{ - while ((obj) && (strcmp(elm_widget_type_get(obj), "elm_win"))) - obj = elm_object_parent_widget_get(obj); - - return obj; -} - static void -_activate(Elm_Fileselector_Button_Smart_Data *sd) +_activate(Widget_Data *wd) { Eina_Bool is_inwin = EINA_FALSE; - if (sd->fs) return; + if (wd->fs) return; - if (sd->inwin_mode) + if (wd->inwin_mode) { - sd->fsw = _parent_win_get(ELM_WIDGET_DATA(sd)->obj); + wd->fsw = _parent_win_get(wd->self); - if (!sd->fsw) - sd->fsw = _new_window_add(sd); + if (!wd->fsw) + wd->fsw = _new_window_add(wd); else { - sd->fsw = elm_win_inwin_add(sd->fsw); + wd->fsw = elm_win_inwin_add(wd->fsw); is_inwin = EINA_TRUE; } } else - sd->fsw = _new_window_add(sd); - - sd->fs = elm_fileselector_add(sd->fsw); - elm_widget_mirrored_set - (sd->fs, elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj)); - elm_widget_mirrored_automatic_set(sd->fs, EINA_FALSE); - elm_fileselector_expandable_set(sd->fs, sd->fsd.expandable); - elm_fileselector_folder_only_set(sd->fs, sd->fsd.folder_only); - elm_fileselector_is_save_set(sd->fs, sd->fsd.is_save); - elm_fileselector_selected_set(sd->fs, sd->fsd.path); - evas_object_size_hint_weight_set - (sd->fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(sd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_smart_callback_add(sd->fs, "done", _selection_done, sd); - evas_object_show(sd->fs); + wd->fsw = _new_window_add(wd); + + wd->fs = elm_fileselector_add(wd->fsw); + elm_widget_mirrored_set(wd->fs, elm_widget_mirrored_get(wd->self)); + elm_widget_mirrored_automatic_set(wd->fs, EINA_FALSE); + elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable); + elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only); + elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save); + elm_fileselector_selected_set(wd->fs, wd->fsd.path); + evas_object_size_hint_weight_set(wd->fs, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(wd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(wd->fs, "done", _selection_done, wd); + evas_object_show(wd->fs); if (is_inwin) { - elm_win_inwin_content_set(sd->fsw, sd->fs); - elm_win_inwin_activate(sd->fsw); + elm_win_inwin_content_set(wd->fsw, wd->fs); + elm_win_inwin_activate(wd->fsw); } else { - elm_win_resize_object_add(sd->fsw, sd->fs); - evas_object_show(sd->fsw); + elm_win_resize_object_add(wd->fsw, wd->fs); + evas_object_show(wd->fsw); } } static void -_button_clicked(void *data, +_selection_done(void *data, Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - _activate(data); -} - -static void -_elm_fileselector_button_smart_add(Evas_Object *obj) + void *event_info) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Fileselector_Button_Smart_Data); - - ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->base.add(obj); - - priv->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE); - if (getenv("HOME")) priv->fsd.path = eina_stringshare_add(getenv("HOME")); - else priv->fsd.path = eina_stringshare_add("/"); - - priv->fsd.expandable = _elm_config->fileselector_expand_enable; - priv->inwin_mode = _elm_config->inwin_dialogs_enable; - priv->w = 400; - priv->h = 400; + const char *file = event_info; + Widget_Data *wd = data; + Evas_Object *del; + if (!wd) return; - elm_widget_mirrored_automatic_set(obj, EINA_FALSE); + if (file) eina_stringshare_replace(&wd->fsd.path, file); - evas_object_smart_callback_add(obj, "clicked", _button_clicked, priv); + del = wd->fsw; + wd->fs = NULL; + wd->fsw = NULL; + evas_object_del(del); - _elm_fileselector_button_smart_theme(obj); - elm_widget_can_focus_set(obj, EINA_TRUE); + evas_object_smart_callback_call(wd->self, SIG_FILE_CHOSEN, + (void *)wd->fsd.path); } static void -_elm_fileselector_button_smart_del(Evas_Object *obj) +_elm_fileselector_button_label_set(Evas_Object *obj, const char *item, + const char *label) { - Evas_Object *win; - - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); - - if (sd->window_title) eina_stringshare_del(sd->window_title); - if (sd->fsd.path) eina_stringshare_del(sd->fsd.path); - if (sd->fs) - { - win = evas_object_data_del(obj, "win"); - evas_object_del(win); - } + ELM_CHECK_WIDTYPE(obj, widtype); + if (item && strcmp(item, "default")) return; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_object_text_set(wd->btn, label); +} - ELM_WIDGET_CLASS(_elm_fileselector_button_parent_sc)->base.del(obj); +static const char * +_elm_fileselector_button_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if (!wd) return NULL; + return elm_object_text_get(wd->btn); } static void -_elm_fileselector_button_smart_set_user(Elm_Button_Smart_Class *sc) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_fileselector_button_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_fileselector_button_smart_del; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_object_part_content_set(wd->btn, part, content); +} - ELM_WIDGET_CLASS(sc)->theme = _elm_fileselector_button_smart_theme; +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return elm_object_part_content_get(wd->btn, part); +} - sc->admits_autorepeat = EINA_FALSE; +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return elm_object_part_content_unset(wd->btn, part); } EAPI Evas_Object * elm_fileselector_button_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_fileselector_button_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "fileselector_button"); + elm_widget_type_set(obj, "fileselector_button"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_activate_hook_set(obj, _activate_hook); + elm_widget_text_set_hook_set(obj, _elm_fileselector_button_label_set); + elm_widget_text_get_hook_set(obj, _elm_fileselector_button_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->self = obj; + wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE); + if (getenv("HOME")) wd->fsd.path = eina_stringshare_add(getenv("HOME")); + else wd->fsd.path = eina_stringshare_add("/"); + wd->fsd.expandable = _elm_config->fileselector_expand_enable; + wd->inwin_mode = _elm_config->inwin_dialogs_enable; + wd->w = 400; + wd->h = 400; + + wd->btn = elm_button_add(parent); + elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE); + elm_widget_resize_object_set(obj, wd->btn); + evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, wd); + elm_widget_sub_object_add(obj, wd->btn); + + _theme_hook(obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } + EAPI void elm_fileselector_button_window_title_set(Evas_Object *obj, - const char *title) + const char *title) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - eina_stringshare_replace(&sd->window_title, title); + if (!wd) return; + eina_stringshare_replace(&wd->window_title, title); - if (sd->fsw) elm_win_title_set(sd->fsw, sd->window_title); + if (wd->fsw) + elm_win_title_set(wd->fsw, wd->window_title); } EAPI const char * elm_fileselector_button_window_title_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) NULL; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); - return sd->window_title; + if (!wd) return NULL; + return wd->window_title; } EAPI void elm_fileselector_button_window_size_set(Evas_Object *obj, - Evas_Coord width, - Evas_Coord height) + Evas_Coord width, + Evas_Coord height) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - sd->w = width; - sd->h = height; + if (!wd) return; + wd->w = width; + wd->h = height; - if (sd->fsw) evas_object_resize(sd->fsw, sd->w, sd->h); + if (wd->fsw) + evas_object_resize(wd->fsw, wd->w, wd->h); } EAPI void elm_fileselector_button_window_size_get(const Evas_Object *obj, - Evas_Coord *width, - Evas_Coord *height) + Evas_Coord *width, + Evas_Coord *height) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - if (width) *width = sd->w; - if (height) *height = sd->h; + if (!wd) return; + if (width) *width = wd->w; + if (height) *height = wd->h; } EAPI void elm_fileselector_button_path_set(Evas_Object *obj, - const char *path) + const char *path) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - eina_stringshare_replace(&sd->fsd.path, path); + if (!wd) return; + eina_stringshare_replace(&wd->fsd.path, path); - if (sd->fs) elm_fileselector_selected_set(sd->fs, sd->fsd.path); + if (wd->fs) + elm_fileselector_selected_set(wd->fs, wd->fsd.path); } EAPI const char * elm_fileselector_button_path_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) NULL; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); - - return sd->fsd.path; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->fsd.path; } EAPI void elm_fileselector_button_expandable_set(Evas_Object *obj, - Eina_Bool value) + Eina_Bool value) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - sd->fsd.expandable = value; + if (!wd) return; + wd->fsd.expandable = value; - if (sd->fs) elm_fileselector_expandable_set(sd->fs, sd->fsd.expandable); + if (wd->fs) + elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable); } EAPI Eina_Bool elm_fileselector_button_expandable_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); - return sd->fsd.expandable; + if (!wd) return EINA_FALSE; + return wd->fsd.expandable; } EAPI void elm_fileselector_button_folder_only_set(Evas_Object *obj, - Eina_Bool value) + Eina_Bool value) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - sd->fsd.folder_only = value; + if (!wd) return; + wd->fsd.folder_only = value; - if (sd->fs) elm_fileselector_folder_only_set(sd->fs, sd->fsd.folder_only); + if (wd->fs) + elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only); } EAPI Eina_Bool elm_fileselector_button_folder_only_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); - return sd->fsd.folder_only; + if (!wd) return EINA_FALSE; + return wd->fsd.folder_only; } EAPI void elm_fileselector_button_is_save_set(Evas_Object *obj, - Eina_Bool value) + Eina_Bool value) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - sd->fsd.is_save = value; + if (!wd) return; + wd->fsd.is_save = value; - if (sd->fs) elm_fileselector_is_save_set(sd->fs, sd->fsd.is_save); + if (wd->fs) + elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save); } EAPI Eina_Bool elm_fileselector_button_is_save_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); - return sd->fsd.is_save; + if (!wd) return EINA_FALSE; + return wd->fsd.is_save; } EAPI void elm_fileselector_button_inwin_mode_set(Evas_Object *obj, - Eina_Bool value) + Eina_Bool value) { - ELM_FILESELECTOR_BUTTON_CHECK(obj); - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - sd->inwin_mode = value; + if (!wd) return; + wd->inwin_mode = value; } EAPI Eina_Bool elm_fileselector_button_inwin_mode_get(const Evas_Object *obj) { - ELM_FILESELECTOR_BUTTON_CHECK(obj) EINA_FALSE; - ELM_FILESELECTOR_BUTTON_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); - return sd->inwin_mode; + if (!wd) return EINA_FALSE; + return wd->inwin_mode; } diff --git a/src/lib/elc_fileselector_button.h b/src/lib/elc_fileselector_button.h index 4286ead95..3eab2929f 100644 --- a/src/lib/elc_fileselector_button.h +++ b/src/lib/elc_fileselector_button.h @@ -25,11 +25,7 @@ * @li @c "hoversel_vertical" * @li @c "hoversel_vertical_entry" * - * This widget inherits from the @ref Button one, so that all the - * functions acting on it also work for file selector button objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Button: + * Smart callbacks one can register to: * - @c "file,chosen" - the user has selected a path, whose string * pointer comes as the @c event_info data (a stringshared * string) diff --git a/src/lib/elc_hoversel.c b/src/lib/elc_hoversel.c index dcb6c4a5c..fb07d78e1 100644 --- a/src/lib/elc_hoversel.c +++ b/src/lib/elc_hoversel.c @@ -1,195 +1,203 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_button.h" -static const char HOVERSEL_SMART_NAME[] = "elm_hoversel"; +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Hoversel_Item Elm_Hoversel_Item; -typedef struct _Elm_Hoversel_Smart_Data Elm_Hoversel_Smart_Data; -typedef struct _Elm_Hoversel_Item Elm_Hoversel_Item; - -struct _Elm_Hoversel_Smart_Data +struct _Widget_Data { - Elm_Button_Smart_Data base; - - /* aggregates a hover */ - Evas_Object *hover; - Evas_Object *hover_parent; - - Eina_List *items; - - Eina_Bool horizontal : 1; - Eina_Bool expanded : 1; + Evas_Object *btn, *hover; + Evas_Object *hover_parent; + Eina_List *items; + Eina_Bool horizontal : 1; + Eina_Bool expanded : 1; }; struct _Elm_Hoversel_Item { ELM_WIDGET_ITEM; - - const char *label; - const char *icon_file; - const char *icon_group; - + const char *label; + const char *icon_file; + const char *icon_group; Elm_Icon_Type icon_type; Evas_Smart_Cb func; }; -#define ELM_HOVERSEL_DATA_GET(o, sd) \ - Elm_Hoversel_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_HOVERSEL_DATA_GET_OR_RETURN(o, ptr) \ - ELM_HOVERSEL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_HOVERSEL_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_HOVERSEL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_HOVERSEL_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), HOVERSEL_SMART_NAME, __func__)) \ - return - -#define ELM_HOVERSEL_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_HOVERSEL_CHECK(it->base.widget); - -#define ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_HOVERSEL_CHECK(it->base.widget) __VA_ARGS__; - +static const char *widtype = NULL; +static void _del_pre_hook(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _activate(Evas_Object *obj); +static void _activate_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static const char SIG_CLICKED[] = "clicked"; static const char SIG_SELECTED[] = "selected"; static const char SIG_DISMISSED[] = "dismissed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { + +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CLICKED, ""}, {SIG_SELECTED, ""}, {SIG_DISMISSED, ""}, {NULL, NULL} }; -EVAS_SMART_SUBCLASS_NEW - (HOVERSEL_SMART_NAME, _elm_hoversel, Elm_Button_Smart_Class, - Elm_Button_Smart_Class, elm_button_smart_class_get, _smart_callbacks); +static void +_del_pre_hook(Evas_Object *obj) +{ + Elm_Hoversel_Item *item; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_event_callback_del_full(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + elm_hoversel_hover_end(obj); + elm_hoversel_hover_parent_set(obj, NULL); + EINA_LIST_FREE(wd->items, item) + { + eina_stringshare_del(item->label); + eina_stringshare_del(item->icon_file); + eina_stringshare_del(item->icon_group); + elm_widget_item_free(item); + } +} -static Eina_Bool -_elm_hoversel_smart_theme(Evas_Object *obj) +static void +_del_hook(Evas_Object *obj) { - char buf[4096]; - const char *style; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} - ELM_HOVERSEL_DATA_GET(obj, sd); +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_widget_mirrored_set(wd->btn, rtl); + elm_widget_mirrored_set(wd->hover, rtl); +} - style = eina_stringshare_add(elm_widget_style_get(obj)); +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + char buf[4096]; + if (!wd) return; + _elm_widget_mirrored_reload(obj); - if (sd->horizontal) - snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", style); + elm_hoversel_hover_end(obj); + if (wd->horizontal) + snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj)); else - snprintf(buf, sizeof(buf), "hoversel_vertical/%s", style); - - /* hoversel's style has an extra bit: orientation */ - eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), buf); - - if (!ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->theme(obj)) - return EINA_FALSE; - - eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style); + snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj)); + elm_object_style_set(wd->btn, buf); + elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj)); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); +} - eina_stringshare_del(style); +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj)); +} - if (sd->hover) - elm_widget_mirrored_set(sd->hover, elm_widget_mirrored_get(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; + if (!wd) return; + evas_object_size_hint_min_get(wd->btn, &minw, &minh); + evas_object_size_hint_max_get(wd->btn, &maxw, &maxh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); +} - elm_hoversel_hover_end(obj); +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + elm_widget_focus_steal(wd->btn); +} - return EINA_TRUE; +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); } static void -_on_hover_clicked(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { elm_hoversel_hover_end(data); } static void -_on_item_clicked(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Elm_Hoversel_Item *item = data; Evas_Object *obj2 = WIDGET(item); + elm_hoversel_hover_end(obj2); if (item->func) item->func((void *)item->base.data, obj2, item); evas_object_smart_callback_call(obj2, SIG_SELECTED, item); - elm_hoversel_hover_end(obj2); } static void _activate(Evas_Object *obj) { - const Elm_Hoversel_Item *item; + Widget_Data *wd = elm_widget_data_get(obj); Evas_Object *bt, *bx, *ic; const Eina_List *l; + const Elm_Hoversel_Item *item; char buf[4096]; - ELM_HOVERSEL_DATA_GET(obj, sd); - - if (sd->expanded) + if (!wd) return; + if (wd->expanded) { elm_hoversel_hover_end(obj); return; } - sd->expanded = EINA_TRUE; + wd->expanded = EINA_TRUE; if (elm_widget_disabled_get(obj)) return; - - printf("creating hover!!\n"); - - sd->hover = elm_hover_add(sd->hover_parent); - elm_widget_mirrored_automatic_set(sd->hover, EINA_FALSE); - - if (sd->horizontal) - snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", - elm_widget_style_get(obj)); + wd->hover = elm_hover_add(obj); + elm_widget_mirrored_automatic_set(wd->hover, EINA_FALSE); + if (wd->horizontal) + snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj)); else - snprintf(buf, sizeof(buf), "hoversel_vertical/%s", - elm_widget_style_get(obj)); + snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj)); + elm_object_style_set(wd->hover, buf); + evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, obj); + elm_hover_parent_set(wd->hover, wd->hover_parent); + elm_hover_target_set(wd->hover, wd->btn); - elm_object_style_set(sd->hover, buf); - - evas_object_smart_callback_add - (sd->hover, "clicked", _on_hover_clicked, obj); - elm_hover_target_set(sd->hover, obj); - - /* hover's content */ - bx = elm_box_add(sd->hover); + bx = elm_box_add(wd->hover); elm_widget_mirrored_automatic_set(bx, EINA_FALSE); - elm_box_homogeneous_set(bx, EINA_TRUE); - elm_box_horizontal_set(bx, sd->horizontal); + elm_box_homogeneous_set(bx, 1); + + elm_box_horizontal_set(bx, wd->horizontal); - if (sd->horizontal) + if (wd->horizontal) snprintf(buf, sizeof(buf), "hoversel_horizontal_entry/%s", elm_widget_style_get(obj)); else snprintf(buf, sizeof(buf), "hoversel_vertical_entry/%s", elm_widget_style_get(obj)); - - EINA_LIST_FOREACH (sd->items, l, item) + EINA_LIST_FOREACH(wd->items, l, item) { - bt = elm_button_add(bx); + bt = elm_button_add(wd->hover); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_widget_mirrored_set(bt, elm_widget_mirrored_get(obj)); elm_object_style_set(bt, buf); elm_object_text_set(bt, item->label); - if (item->icon_file) { ic = elm_icon_add(obj); @@ -199,216 +207,239 @@ _activate(Evas_Object *obj) else if (item->icon_type == ELM_ICON_STANDARD) elm_icon_standard_set(ic, item->icon_file); elm_object_part_content_set(bt, "icon", ic); + evas_object_show(ic); } - evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_box_pack_end(bx, bt); - evas_object_smart_callback_add(bt, "clicked", _on_item_clicked, item); + evas_object_smart_callback_add(bt, "clicked", _item_clicked, item); evas_object_show(bt); } - if (sd->horizontal) - elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get - (sd->hover, ELM_HOVER_AXIS_HORIZONTAL), bx); + if (wd->horizontal) + elm_object_part_content_set(wd->hover, + elm_hover_best_content_location_get(wd->hover, + ELM_HOVER_AXIS_HORIZONTAL), + bx); else - elm_object_part_content_set(sd->hover, elm_hover_best_content_location_get - (sd->hover, ELM_HOVER_AXIS_VERTICAL), bx); + elm_object_part_content_set(wd->hover, + elm_hover_best_content_location_get(wd->hover, + ELM_HOVER_AXIS_VERTICAL), + bx); + evas_object_show(bx); + + evas_object_show(wd->hover); + evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); - evas_object_show(sd->hover); + // if (wd->horizontal) evas_object_hide(wd->btn); } static void -_on_clicked(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_activate_hook(Evas_Object *obj) { - _activate(data); + _activate(obj); } static void -_on_parent_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_HOVERSEL_DATA_GET(data, sd); - - sd->hover_parent = NULL; + _activate(data); } -static const char * -_item_text_get_hook(const Elm_Object_Item *it, - const char *part) +static void +_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - if (part && strcmp(part, "default")) return NULL; - return ((Elm_Hoversel_Item *)it)->label; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->hover_parent = NULL; } -static Eina_Bool -_item_del_pre_hook(Elm_Object_Item *it) +static void +_elm_hoversel_label_set(Evas_Object *obj, const char *item, const char *label) { - Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it; - - ELM_HOVERSEL_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE); - - elm_hoversel_hover_end(WIDGET(item)); - sd->items = eina_list_remove(sd->items, item); - eina_stringshare_del(item->label); - eina_stringshare_del(item->icon_file); - eina_stringshare_del(item->icon_group); - - return EINA_TRUE; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return; + if (!wd) return; + elm_object_text_set(wd->btn, label); } -static void -_elm_hoversel_smart_add(Evas_Object *obj) +static const char * +_elm_hoversel_label_get(const Evas_Object *obj, const char *item) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Hoversel_Smart_Data); - - ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.add(obj); - - elm_widget_mirrored_automatic_set(obj, EINA_FALSE); - - priv->expanded = EINA_FALSE; - - evas_object_smart_callback_add(obj, "clicked", _on_clicked, obj); - - _elm_hoversel_smart_theme(obj); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if ((!wd) || (!wd->btn)) return NULL; + return elm_object_text_get(wd->btn); } static void -_elm_hoversel_smart_del(Evas_Object *obj) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - Elm_Hoversel_Item *item; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - ELM_HOVERSEL_DATA_GET(obj, sd); + elm_object_part_content_set(wd->btn, part, content); +} - EINA_LIST_FREE (sd->items, item) - { - eina_stringshare_del(item->label); - eina_stringshare_del(item->icon_file); - eina_stringshare_del(item->icon_group); - elm_widget_item_free(item); - } +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (!wd->btn)) return NULL; + return elm_object_part_content_get(wd->btn, part); +} - ELM_WIDGET_CLASS(_elm_hoversel_parent_sc)->base.del(obj); +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (!wd->btn)) return NULL; + return elm_object_part_content_unset(wd->btn, part); } -static void -_elm_hoversel_smart_set_user(Elm_Button_Smart_Class *sc) +static const char * +_item_text_get_hook(const Elm_Object_Item *it, const char *part) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_hoversel_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_hoversel_smart_del; + if (part && strcmp(part, "default")) return NULL; + return ((Elm_Hoversel_Item *)it)->label; +} - ELM_WIDGET_CLASS(sc)->theme = _elm_hoversel_smart_theme; +static Eina_Bool +_item_del_pre_hook(Elm_Object_Item *it) +{ + Widget_Data *wd; + Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it; + wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return EINA_FALSE; + elm_hoversel_hover_end(WIDGET(item)); + wd->items = eina_list_remove(wd->items, item); + eina_stringshare_del(item->label); + eina_stringshare_del(item->icon_file); + eina_stringshare_del(item->icon_group); - sc->admits_autorepeat = EINA_FALSE; + return EINA_TRUE; } EAPI Evas_Object * elm_hoversel_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_hoversel_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "hoversel"); + elm_widget_type_set(obj, "hoversel"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_activate_hook_set(obj, _activate_hook); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_text_set_hook_set(obj, _elm_hoversel_label_set); + elm_widget_text_get_hook_set(obj, _elm_hoversel_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->btn = elm_button_add(parent); + elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE); + wd->expanded = EINA_FALSE; + elm_widget_resize_object_set(obj, wd->btn); + evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + elm_widget_sub_object_add(obj, wd->btn); elm_hoversel_hover_parent_set(obj, parent); + _theme_hook(obj); return obj; } EAPI void -elm_hoversel_hover_parent_set(Evas_Object *obj, - Evas_Object *parent) +elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent) { - ELM_HOVERSEL_CHECK(obj); - ELM_HOVERSEL_DATA_GET(obj, sd); - - if (sd->hover_parent) - evas_object_event_callback_del_full - (sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj); - - sd->hover_parent = parent; - if (sd->hover_parent) - evas_object_event_callback_add - (sd->hover_parent, EVAS_CALLBACK_DEL, _on_parent_del, obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->hover_parent) + evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL, + _parent_del, obj); + wd->hover_parent = parent; + if (wd->hover_parent) + evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL, + _parent_del, obj); } EAPI Evas_Object * elm_hoversel_hover_parent_get(const Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj) NULL; - ELM_HOVERSEL_DATA_GET(obj, sd); - - return sd->hover_parent; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->hover_parent; } EAPI void -elm_hoversel_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_HOVERSEL_CHECK(obj); - ELM_HOVERSEL_DATA_GET(obj, sd); - - sd->horizontal = !!horizontal; - - _elm_hoversel_smart_theme(obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->horizontal = !!horizontal; } EAPI Eina_Bool elm_hoversel_horizontal_get(const Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj) EINA_FALSE; - ELM_HOVERSEL_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } EAPI void elm_hoversel_hover_begin(Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj); - ELM_HOVERSEL_DATA_GET(obj, sd); - - if (sd->hover) return; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->hover) return; _activate(obj); } EAPI void elm_hoversel_hover_end(Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj); - ELM_HOVERSEL_DATA_GET(obj, sd); - - if (!sd->hover) return; - - sd->expanded = EINA_FALSE; - - printf("deleting hover!!\n"); - evas_object_del(sd->hover); - sd->hover = NULL; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (!wd->hover) return; + wd->expanded = EINA_FALSE; + evas_object_del(wd->hover); + wd->hover = NULL; evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL); } EAPI Eina_Bool elm_hoversel_expanded_get(const Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj) EINA_FALSE; - ELM_HOVERSEL_DATA_GET(obj, sd); - - return (sd->hover) ? EINA_TRUE : EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return (wd->hover) ? EINA_TRUE : EINA_FALSE; } EAPI void @@ -416,80 +447,61 @@ elm_hoversel_clear(Evas_Object *obj) { Elm_Object_Item *it; Eina_List *l, *ll; - - ELM_HOVERSEL_CHECK(obj); - ELM_HOVERSEL_DATA_GET(obj, sd); - - EINA_LIST_FOREACH_SAFE (sd->items, l, ll, it) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + EINA_LIST_FOREACH_SAFE(wd->items, l, ll, it) { - elm_widget_item_del(it); + _item_del_pre_hook(it); + elm_widget_item_free(it); } } EAPI const Eina_List * elm_hoversel_items_get(const Evas_Object *obj) { - ELM_HOVERSEL_CHECK(obj) NULL; - ELM_HOVERSEL_DATA_GET(obj, sd); - - return sd->items; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->items; } EAPI Elm_Object_Item * -elm_hoversel_item_add(Evas_Object *obj, - const char *label, - const char *icon_file, - Elm_Icon_Type icon_type, - Evas_Smart_Cb func, - const void *data) +elm_hoversel_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data) { - ELM_HOVERSEL_CHECK(obj) NULL; - ELM_HOVERSEL_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; Elm_Hoversel_Item *item = elm_widget_item_new(obj, Elm_Hoversel_Item); if (!item) return NULL; - elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook); elm_widget_item_text_get_hook_set(item, _item_text_get_hook); - + wd->items = eina_list_append(wd->items, item); item->label = eina_stringshare_add(label); item->icon_file = eina_stringshare_add(icon_file); item->icon_type = icon_type; item->func = func; item->base.data = data; - - sd->items = eina_list_append(sd->items, item); - return (Elm_Object_Item *)item; } EAPI void -elm_hoversel_item_icon_set(Elm_Object_Item *it, - const char *icon_file, - const char *icon_group, - Elm_Icon_Type icon_type) +elm_hoversel_item_icon_set(Elm_Object_Item *it, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type) { - ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it); - + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it; - eina_stringshare_replace(&item->icon_file, icon_file); eina_stringshare_replace(&item->icon_group, icon_group); - item->icon_type = icon_type; } EAPI void -elm_hoversel_item_icon_get(const Elm_Object_Item *it, - const char **icon_file, - const char **icon_group, - Elm_Icon_Type *icon_type) +elm_hoversel_item_icon_get(const Elm_Object_Item *it, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type) { - ELM_HOVERSEL_ITEM_CHECK_OR_RETURN(it); - + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); Elm_Hoversel_Item *item = (Elm_Hoversel_Item *)it; - if (icon_file) *icon_file = item->icon_file; if (icon_group) *icon_group = item->icon_group; if (icon_type) *icon_type = item->icon_type; } + diff --git a/src/lib/elc_hoversel.h b/src/lib/elc_hoversel.h index d54db0550..1f6084907 100644 --- a/src/lib/elc_hoversel.h +++ b/src/lib/elc_hoversel.h @@ -12,16 +12,10 @@ * items in the hoversel menu (no more than 8), though is capable of many * more. * - * This widget inherits from the @ref Button one, so that all the - * functions acting on it also work for hoversel objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Button: - * - @c "clicked" - the user clicked the hoversel button and popped up - * the sel - * - @c "selected" - an item in the hoversel list is selected. event_info - * is the item - * - @c "dismissed" - the hover is dismissed + * Signals that you can add callbacks for are: + * "clicked" - the user clicked the hoversel button and popped up the sel + * "selected" - an item in the hoversel list is selected. event_info is the item + * "dismissed" - the hover is dismissed * * Default content parts of the hoversel widget that you can use for are: * @li "icon" - An icon of the hoversel diff --git a/src/lib/elc_player.c b/src/lib/elc_player.c index 06e6086dc..a6327c323 100644 --- a/src/lib/elc_player.c +++ b/src/lib/elc_player.c @@ -1,57 +1,31 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" #ifdef HAVE_EMOTION # include <Emotion.h> #endif -static const char PLAYER_SMART_NAME[] = "elm_player"; - -typedef struct _Elm_Player_Smart_Data Elm_Player_Smart_Data; -struct _Elm_Player_Smart_Data +typedef struct _Widget_Data Widget_Data; +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *video; - Evas_Object *emotion; - - /* tracking those to ease disabling/enabling them back */ - Evas_Object *forward; - Evas_Object *info; - Evas_Object *next; - Evas_Object *pause; - Evas_Object *play; - Evas_Object *prev; - Evas_Object *rewind; - Evas_Object *stop; - Evas_Object *slider; + Evas_Object *layout; + Evas_Object *video; + Evas_Object *emotion; + + Evas_Object *forward; + Evas_Object *info; + Evas_Object *next; + Evas_Object *pause; + Evas_Object *play; + Evas_Object *prev; + Evas_Object *rewind; + Evas_Object *stop; + + Evas_Object *slider; }; -#define ELM_PLAYER_DATA_GET(o, sd) \ - Elm_Player_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_PLAYER_DATA_GET_OR_RETURN(o, ptr) \ - ELM_PLAYER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_PLAYER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_PLAYER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_PLAYER_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), PLAYER_SMART_NAME, __func__)) \ - return +#ifdef HAVE_EMOTION +static const char *widtype = NULL; static const char SIG_FORWARD_CLICKED[] = "forward,clicked"; static const char SIG_INFO_CLICKED[] = "info,clicked"; @@ -61,52 +35,49 @@ static const char SIG_PLAY_CLICKED[] = "play,clicked"; static const char SIG_PREV_CLICKED[] = "prev,clicked"; static const char SIG_REWIND_CLICKED[] = "rewind,clicked"; static const char SIG_STOP_CLICKED[] = "stop,clicked"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - { SIG_FORWARD_CLICKED, "" }, - { SIG_INFO_CLICKED, "" }, - { SIG_NEXT_CLICKED, "" }, - { SIG_PAUSE_CLICKED, "" }, - { SIG_PLAY_CLICKED, "" }, - { SIG_PREV_CLICKED, "" }, - { SIG_REWIND_CLICKED, "" }, - { SIG_STOP_CLICKED, "" }, - { NULL, NULL } + +static const Evas_Smart_Cb_Description _signals[] = { + { SIG_FORWARD_CLICKED, "" }, + { SIG_INFO_CLICKED, "" }, + { SIG_NEXT_CLICKED, "" }, + { SIG_PAUSE_CLICKED, "" }, + { SIG_PLAY_CLICKED, "" }, + { SIG_PREV_CLICKED, "" }, + { SIG_REWIND_CLICKED, "" }, + { SIG_STOP_CLICKED, "" }, + { NULL, NULL } }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (PLAYER_SMART_NAME, _elm_player, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _on_focus_hook(void *data, Evas_Object *obj); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); -#ifdef HAVE_EMOTION static Eina_Bool -_elm_player_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - Evas_Event_Key_Down *ev = event_info; - - ELM_PLAYER_DATA_GET(obj, sd); - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - if (!sd->video) return EINA_FALSE; - + if (elm_widget_disabled_get(obj)) return EINA_FALSE; + if (!wd->video) return EINA_FALSE; if ((!strcmp(ev->keyname, "Left")) || ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { double current, last; - current = elm_video_play_position_get(sd->video); - last = elm_video_play_length_get(sd->video); + current = elm_video_play_position_get(wd->video); + last = elm_video_play_length_get(wd->video); if (current < last) { - current -= last / 100; - elm_video_play_position_set(sd->video, current); + current += last / 100; + elm_video_play_position_set(wd->video, current); } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; @@ -117,14 +88,14 @@ _elm_player_smart_event(Evas_Object *obj, { double current, last; - current = elm_video_play_position_get(sd->video); - last = elm_video_play_length_get(sd->video); + current = elm_video_play_position_get(wd->video); + last = elm_video_play_length_get(wd->video); if (current > 0) { - current += last / 100; + current -= last / 100; if (current < 0) current = 0; - elm_video_play_position_set(sd->video, current); + elm_video_play_position_set(wd->video, current); } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; @@ -132,270 +103,329 @@ _elm_player_smart_event(Evas_Object *obj, } if (!strcmp(ev->keyname, "space")) { - if (elm_video_is_playing_get(sd->video)) - elm_video_pause(sd->video); + if (elm_video_is_playing_get(wd->video)) + elm_video_pause(wd->video); else - elm_video_play(sd->video); + elm_video_play(wd->video); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } fprintf(stderr, "keyname: '%s' not handle\n", ev->keyname); - return EINA_FALSE; } -static Eina_Bool -_elm_player_smart_theme(Evas_Object *obj) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - ELM_PLAYER_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_player_parent_sc)->theme(obj)) return EINA_FALSE; - -#define UPDATE_THEME(Target, Name) \ - if (Target) \ - { \ - elm_object_style_set(Target, elm_widget_style_get(obj)); \ - if (!elm_layout_content_set(obj, Name, Target)) \ - evas_object_hide(Target); \ - elm_object_disabled_set(Target, elm_widget_disabled_get(obj)); \ - } - - UPDATE_THEME(sd->forward, "media_player/forward"); - UPDATE_THEME(sd->info, "media_player/info"); - UPDATE_THEME(sd->next, "media_player/next"); - UPDATE_THEME(sd->pause, "media_player/pause"); - UPDATE_THEME(sd->play, "media_player/play"); - UPDATE_THEME(sd->prev, "media_player/prev"); - UPDATE_THEME(sd->rewind, "media_player/rewind"); - UPDATE_THEME(sd->next, "media_player/next"); - UPDATE_THEME(sd->slider, "media_player/slider"); - - elm_layout_sizing_eval(obj); - - return EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->layout, "elm,action,focus", "elm"); + evas_object_focus_set(wd->layout, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->layout, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->layout, EINA_FALSE); + } } static void -_elm_player_smart_sizing_eval(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Evas_Coord w, h; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->layout, rtl); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->layout, "video", "base", elm_widget_style_get(obj)); + edje_object_scale_set(wd->layout, elm_widget_scale_get(obj) * + _elm_config->scale); + +#define UPDATE_THEME(Obj, Target, Layout, Name) \ + if (Target) \ + { \ + elm_object_style_set(Target, elm_widget_style_get(Obj)); \ + if (!edje_object_part_swallow(Layout, Name, Target)) \ + evas_object_hide(Target); \ + elm_object_disabled_set(Target, elm_widget_disabled_get(Obj)); \ + } - ELM_PLAYER_DATA_GET(obj, sd); + UPDATE_THEME(obj, wd->forward, wd->layout, "media_player/forward"); + UPDATE_THEME(obj, wd->info, wd->layout, "media_player/info"); + UPDATE_THEME(obj, wd->next, wd->layout, "media_player/next"); + UPDATE_THEME(obj, wd->pause, wd->layout, "media_player/pause"); + UPDATE_THEME(obj, wd->play, wd->layout, "media_player/play"); + UPDATE_THEME(obj, wd->prev, wd->layout, "media_player/prev"); + UPDATE_THEME(obj, wd->rewind, wd->layout, "media_player/rewind"); + UPDATE_THEME(obj, wd->next, wd->layout, "media_player/next"); + UPDATE_THEME(obj, wd->slider, wd->layout, "media_player/slider"); + + _sizing_eval(obj); +} + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord w, h; - edje_object_size_min_get(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &w, &h, w, h); + if (!wd) return; + edje_object_size_min_get(wd->layout, &w, &h); + edje_object_size_min_restricted_calc(wd->layout, &w, &h, w, h); evas_object_size_hint_min_set(obj, w, h); } static void -_update_slider(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_update_slider(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); double pos, length; Eina_Bool seekable; - ELM_PLAYER_DATA_GET(data, sd); + if (!wd) return ; + seekable = elm_video_is_seekable_get(wd->video); + length = elm_video_play_length_get(wd->video); + pos = elm_video_play_position_get(wd->video); - seekable = elm_video_is_seekable_get(sd->video); - length = elm_video_play_length_get(sd->video); - pos = elm_video_play_position_get(sd->video); - - elm_object_disabled_set(sd->slider, !seekable); - elm_slider_min_max_set(sd->slider, 0, length); - elm_slider_value_set(sd->slider, pos); + elm_object_disabled_set(wd->slider, !seekable); + elm_slider_min_max_set(wd->slider, 0, length); + elm_slider_value_set(wd->slider, pos); } static void -_update_position(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_update_position(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_PLAYER_DATA_GET(data, sd); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); - elm_video_play_position_set(sd->video, elm_slider_value_get(sd->slider)); + if (!wd) return ; + elm_video_play_position_set(wd->video, elm_slider_value_get(wd->slider)); } static void -_forward(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_forward(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); double pos, length; - ELM_PLAYER_DATA_GET(data, sd); + if (!wd) return ; - pos = elm_video_play_position_get(sd->video); - length = elm_video_play_length_get(sd->video); + pos = elm_video_play_position_get(wd->video); + length = elm_video_play_length_get(wd->video); pos += length * 0.3; - elm_video_play_position_set(sd->video, pos); + elm_video_play_position_set(wd->video, pos); - elm_layout_signal_emit(data, "elm,button,forward", "elm"); - evas_object_smart_callback_call(data, SIG_FORWARD_CLICKED, NULL); + edje_object_signal_emit(wd->layout, "elm,button,forward", "elm"); + evas_object_smart_callback_call(player, SIG_FORWARD_CLICKED, NULL); } static void -_info(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_info(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,button,info", "elm"); - evas_object_smart_callback_call(data, SIG_INFO_CLICKED, NULL); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); + + if (!wd) return ; + + edje_object_signal_emit(wd->layout, "elm,button,info", "elm"); + evas_object_smart_callback_call(player, SIG_INFO_CLICKED, NULL); } static void -_next(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_next(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); double pos, length; - ELM_PLAYER_DATA_GET(data, sd); + if (!wd) return ; - pos = elm_video_play_position_get(sd->video); - length = elm_video_play_length_get(sd->video); + pos = elm_video_play_position_get(wd->video); + length = elm_video_play_length_get(wd->video); pos += length * 0.1; - elm_video_play_position_set(sd->video, pos); + elm_video_play_position_set(wd->video, pos); - elm_layout_signal_emit(data, "elm,button,next", "elm"); - evas_object_smart_callback_call(data, SIG_NEXT_CLICKED, NULL); + edje_object_signal_emit(wd->layout, "elm,button,next", "elm"); + evas_object_smart_callback_call(player, SIG_NEXT_CLICKED, NULL); } static void -_pause(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_pause(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_PLAYER_DATA_GET(data, sd); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); - elm_layout_signal_emit(data, "elm,player,pause", "elm"); - elm_video_pause(sd->video); + if (!wd) return ; - elm_layout_signal_emit(data, "elm,button,pause", "elm"); - evas_object_smart_callback_call(data, SIG_PAUSE_CLICKED, NULL); + edje_object_signal_emit(wd->layout, "elm,player,pause", "elm"); + elm_video_pause(wd->video); + + edje_object_signal_emit(wd->layout, "elm,button,pause", "elm"); + evas_object_smart_callback_call(player, SIG_PAUSE_CLICKED, NULL); } static void -_play(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_play(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_PLAYER_DATA_GET(data, sd); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); - elm_video_play(sd->video); - elm_layout_signal_emit(data, "elm,button,play", "elm"); - evas_object_smart_callback_call(data, SIG_PLAY_CLICKED, NULL); + if (!wd) return ; + elm_video_play(wd->video); + edje_object_signal_emit(wd->layout, "elm,button,play", "elm"); + evas_object_smart_callback_call(player, SIG_PLAY_CLICKED, NULL); } static void -_prev(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_prev(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); double pos, length; - ELM_PLAYER_DATA_GET(data, sd); + if (!wd) return ; - pos = elm_video_play_position_get(sd->video); - length = elm_video_play_length_get(sd->video); + pos = elm_video_play_position_get(wd->video); + length = elm_video_play_length_get(wd->video); pos -= length * 0.1; - elm_video_play_position_set(sd->video, pos); - evas_object_smart_callback_call(data, SIG_PREV_CLICKED, NULL); - elm_layout_signal_emit(data, "elm,button,prev", "elm"); + elm_video_play_position_set(wd->video, pos); + evas_object_smart_callback_call(player, SIG_PREV_CLICKED, NULL); + edje_object_signal_emit(wd->layout, "elm,button,prev", "elm"); } static void -_rewind(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_rewind(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_PLAYER_DATA_GET(data, sd); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); - elm_video_play_position_set(sd->video, 0); - elm_layout_signal_emit(data, "elm,button,rewind", "elm"); - evas_object_smart_callback_call(data, SIG_REWIND_CLICKED, NULL); + if (!wd) return ; + elm_video_play_position_set(wd->video, 0); + edje_object_signal_emit(wd->layout, "elm,button,rewind", "elm"); + evas_object_smart_callback_call(player, SIG_REWIND_CLICKED, NULL); } static void -_stop(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_stop(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,button,stop", "elm"); - evas_object_smart_callback_call(data, SIG_STOP_CLICKED, NULL); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); + + if (!wd) return ; + + edje_object_signal_emit(wd->layout, "elm,button,stop", "elm"); + evas_object_smart_callback_call(player, SIG_STOP_CLICKED, NULL); } static void -_play_started(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_play_started(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,player,play", "elm"); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); + + if (!wd) return ; + + edje_object_signal_emit(wd->layout, "elm,player,play", "elm"); } static void -_play_finished(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_play_finished(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,player,pause", "elm"); + Evas_Object *player = data; + Widget_Data *wd = elm_widget_data_get(player); + + if (!wd) return ; + + edje_object_signal_emit(wd->layout, "elm,player,pause", "elm"); } static void -_on_video_del(Elm_Player_Smart_Data *sd) +_cleanup_callback(Widget_Data *wd) { - elm_object_disabled_set(sd->slider, EINA_TRUE); - elm_object_disabled_set(sd->forward, EINA_TRUE); - elm_object_disabled_set(sd->info, EINA_TRUE); - elm_object_disabled_set(sd->next, EINA_TRUE); - elm_object_disabled_set(sd->pause, EINA_TRUE); - elm_object_disabled_set(sd->play, EINA_TRUE); - elm_object_disabled_set(sd->prev, EINA_TRUE); - elm_object_disabled_set(sd->rewind, EINA_TRUE); - elm_object_disabled_set(sd->next, EINA_TRUE); - - sd->video = NULL; - sd->emotion = NULL; + if (!wd || !wd->emotion) return; + + evas_object_smart_callback_del(wd->emotion, "frame_decode", + _update_slider); + evas_object_smart_callback_del(wd->emotion, "frame_resize", + _update_slider); + evas_object_smart_callback_del(wd->emotion, "length_change", + _update_slider); + evas_object_smart_callback_del(wd->emotion, "position_update", + _update_slider); + evas_object_smart_callback_del(wd->emotion, "playback_started", + _play_started); + evas_object_smart_callback_del(wd->emotion, "playback_finished", + _play_finished); + elm_object_disabled_set(wd->slider, EINA_TRUE); + elm_object_disabled_set(wd->forward, EINA_TRUE); + elm_object_disabled_set(wd->info, EINA_TRUE); + elm_object_disabled_set(wd->next, EINA_TRUE); + elm_object_disabled_set(wd->pause, EINA_TRUE); + elm_object_disabled_set(wd->play, EINA_TRUE); + elm_object_disabled_set(wd->prev, EINA_TRUE); + elm_object_disabled_set(wd->rewind, EINA_TRUE); + elm_object_disabled_set(wd->next, EINA_TRUE); + wd->video = NULL; + wd->emotion = NULL; } static void -_video_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_track_video(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - _on_video_del(data); + _cleanup_callback(data); +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + + if (!wd) return; + evas_object_smart_callback_del(wd->forward, "clicked", _forward); + evas_object_smart_callback_del(wd->info, "clicked", _info); + evas_object_smart_callback_del(wd->next, "clicked", _next); + evas_object_smart_callback_del(wd->pause, "clicked", _pause); + evas_object_smart_callback_del(wd->play, "clicked", _play); + evas_object_smart_callback_del(wd->prev, "clicked", _prev); + evas_object_smart_callback_del(wd->rewind, "clicked", _rewind); + evas_object_smart_callback_del(wd->next, "clicked", _next); + _cleanup_callback(wd); + free(wd); } static Evas_Object * -_player_button_add(Evas_Object *obj, - const char *name, - Evas_Smart_Cb func) +_player_button_add(Evas_Object *parent, Evas_Object *obj, Evas_Object *layout, const char *name, Evas_Smart_Cb func) { Evas_Object *ic; Evas_Object *bt; - ic = elm_icon_add(obj); + ic = elm_icon_add(parent); elm_icon_standard_set(ic, name); evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); - - bt = elm_button_add(obj); + bt = elm_button_add(parent); elm_widget_mirrored_automatic_set(bt, EINA_FALSE); elm_object_part_content_set(bt, "icon", ic); evas_object_size_hint_align_set(bt, 0.0, 0.0); elm_object_style_set(bt, "anchor"); evas_object_smart_callback_add(bt, "clicked", func, obj); + elm_widget_sub_object_add(obj, bt); - if (!elm_layout_content_set(obj, name, bt)) - { - elm_widget_sub_object_add(obj, bt); - evas_object_hide(bt); - } - + if (!edje_object_part_swallow(layout, name, bt)) + evas_object_hide(bt); return bt; } @@ -409,7 +439,6 @@ _double_to_time(double value) pm = value / 60 - (ph * 60); ps = value - (pm * 60); pf = value * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100); - if (ph) snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i", ph, pm, ps, pf); @@ -424,156 +453,138 @@ _double_to_time(double value) } static void -_str_free(char *data) +_value_free(char *data) { eina_stringshare_del(data); } +#endif -/* a video object is never parented by a player one, just tracked. - * treating this special case here and delegating other objects to own - * layout */ -static Eina_Bool -_elm_player_smart_content_set(Evas_Object *obj, - const char *part, - Evas_Object *content) +#ifdef HAVE_EMOTION +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { + if (part && strcmp(part, "video")) return; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; double pos, length; Eina_Bool seekable; - if (part && strcmp(part, "video")) - return ELM_CONTAINER_CLASS(_elm_player_parent_sc)->content_set - (obj, part, content); - - ELM_PLAYER_DATA_GET(obj, sd); - - if (!_elm_video_check(content)) return EINA_FALSE; - if (sd->video == content) return EINA_TRUE; - - if (sd->video) evas_object_del(sd->video); - - sd->video = content; - - if (!content) return EINA_TRUE; + if (!_elm_video_check(content)) return; + if (wd->video == content) return; - elm_object_disabled_set(sd->slider, EINA_FALSE); - elm_object_disabled_set(sd->forward, EINA_FALSE); - elm_object_disabled_set(sd->info, EINA_FALSE); - elm_object_disabled_set(sd->next, EINA_FALSE); - elm_object_disabled_set(sd->pause, EINA_FALSE); - elm_object_disabled_set(sd->play, EINA_FALSE); - elm_object_disabled_set(sd->prev, EINA_FALSE); - elm_object_disabled_set(sd->rewind, EINA_FALSE); - elm_object_disabled_set(sd->next, EINA_FALSE); + if (wd->video) evas_object_del(wd->video); + _cleanup_callback(wd); - sd->emotion = elm_video_emotion_get(sd->video); - emotion_object_priority_set(sd->emotion, EINA_TRUE); - evas_object_event_callback_add - (sd->video, EVAS_CALLBACK_DEL, _video_del, sd); + wd->video = content; - seekable = elm_video_is_seekable_get(sd->video); - length = elm_video_play_length_get(sd->video); - pos = elm_video_play_position_get(sd->video); - - elm_object_disabled_set(sd->slider, !seekable); - elm_slider_min_max_set(sd->slider, 0, length); - elm_slider_value_set(sd->slider, pos); - - if (elm_video_is_playing_get(sd->video)) - elm_layout_signal_emit(obj, "elm,player,play", "elm"); - else elm_layout_signal_emit(obj, "elm,player,pause", "elm"); + if (!wd->video) + { + wd->emotion = NULL; + return ; + } - evas_object_smart_callback_add(sd->emotion, "frame_decode", + elm_object_disabled_set(wd->slider, EINA_FALSE); + elm_object_disabled_set(wd->forward, EINA_FALSE); + elm_object_disabled_set(wd->info, EINA_FALSE); + elm_object_disabled_set(wd->next, EINA_FALSE); + elm_object_disabled_set(wd->pause, EINA_FALSE); + elm_object_disabled_set(wd->play, EINA_FALSE); + elm_object_disabled_set(wd->prev, EINA_FALSE); + elm_object_disabled_set(wd->rewind, EINA_FALSE); + elm_object_disabled_set(wd->next, EINA_FALSE); + + wd->emotion = elm_video_emotion_get(wd->video); + emotion_object_priority_set(wd->emotion, EINA_TRUE); + evas_object_event_callback_add(wd->video, EVAS_CALLBACK_DEL, + _track_video, wd); + + seekable = elm_video_is_seekable_get(wd->video); + length = elm_video_play_length_get(wd->video); + pos = elm_video_play_position_get(wd->video); + + elm_object_disabled_set(wd->slider, !seekable); + elm_slider_min_max_set(wd->slider, 0, length); + elm_slider_value_set(wd->slider, pos); + + if (elm_video_is_playing_get(wd->video)) edje_object_signal_emit(wd->layout, "elm,player,play", "elm"); + else edje_object_signal_emit(wd->layout, "elm,player,pause", "elm"); + + evas_object_smart_callback_add(wd->emotion, "frame_decode", _update_slider, obj); - evas_object_smart_callback_add(sd->emotion, "frame_resize", + evas_object_smart_callback_add(wd->emotion, "frame_resize", _update_slider, obj); - evas_object_smart_callback_add(sd->emotion, "length_change", + evas_object_smart_callback_add(wd->emotion, "length_change", _update_slider, obj); - evas_object_smart_callback_add(sd->emotion, "position_update", + evas_object_smart_callback_add(wd->emotion, "position_update", _update_slider, obj); - evas_object_smart_callback_add(sd->emotion, "playback_started", + evas_object_smart_callback_add(wd->emotion, "playback_started", _play_started, obj); - evas_object_smart_callback_add(sd->emotion, "playback_finished", + evas_object_smart_callback_add(wd->emotion, "playback_finished", _play_finished, obj); /* FIXME: track info from video */ - - return EINA_TRUE; } - -static void -_elm_player_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Player_Smart_Data); - - ELM_WIDGET_CLASS(_elm_player_parent_sc)->base.add(obj); - - elm_layout_theme_set(obj, "player", "base", elm_widget_style_get(obj)); - - priv->forward = _player_button_add(obj, "media_player/forward", _forward); - priv->info = _player_button_add(obj, "media_player/info", _info); - priv->next = _player_button_add(obj, "media_player/next", _next); - priv->pause = _player_button_add(obj, "media_player/pause", _pause); - priv->play = _player_button_add(obj, "media_player/play", _play); - priv->prev = _player_button_add(obj, "media_player/prev", _prev); - priv->rewind = _player_button_add(obj, "media_player/rewind", _rewind); - priv->stop = _player_button_add(obj, "media_player/stop", _stop); - - priv->slider = elm_slider_add(obj); - elm_slider_indicator_format_function_set - (priv->slider, _double_to_time, _str_free); - elm_slider_units_format_function_set - (priv->slider, _double_to_time, _str_free); - elm_slider_min_max_set(priv->slider, 0, 0); - elm_slider_value_set(priv->slider, 0); - elm_object_disabled_set(priv->slider, EINA_TRUE); - evas_object_size_hint_align_set(priv->slider, EVAS_HINT_FILL, 0.5); - evas_object_size_hint_weight_set - (priv->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - - elm_layout_content_set(obj, "media_player/slider", priv->slider); - evas_object_smart_callback_add - (priv->slider, "changed", _update_position, obj); - - elm_layout_sizing_eval(obj); - elm_widget_can_focus_set(obj, EINA_TRUE); -} - -#endif - -static void -_elm_player_smart_set_user(Elm_Layout_Smart_Class *sc) -{ -#ifdef HAVE_EMOTION - ELM_WIDGET_CLASS(sc)->base.add = _elm_player_smart_add; - - ELM_WIDGET_CLASS(sc)->event = _elm_player_smart_event; - ELM_WIDGET_CLASS(sc)->theme = _elm_player_smart_theme; - - ELM_CONTAINER_CLASS(sc)->content_set = _elm_player_smart_content_set; - - sc->sizing_eval = _elm_player_smart_sizing_eval; #endif -} EAPI Evas_Object * elm_player_add(Evas_Object *parent) { #ifdef HAVE_EMOTION - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_player_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "player"); + elm_widget_type_set(obj, "player"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + 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, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + /* TODO: add content_unset and content_get hook */ + + wd->layout = edje_object_add(e); + _elm_theme_object_set(obj, wd->layout, "player", "base", "default"); + elm_widget_resize_object_set(obj, wd->layout); + elm_widget_sub_object_add(obj, wd->layout); + evas_object_show(wd->layout); + evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + wd->forward = _player_button_add(parent, obj, wd->layout, "media_player/forward", _forward); + wd->info = _player_button_add(parent, obj, wd->layout, "media_player/info", _info); + wd->next = _player_button_add(parent, obj, wd->layout, "media_player/next", _next); + wd->pause = _player_button_add(parent, obj, wd->layout, "media_player/pause", _pause); + wd->play = _player_button_add(parent, obj, wd->layout, "media_player/play", _play); + wd->prev = _player_button_add(parent, obj, wd->layout, "media_player/prev", _prev); + wd->rewind = _player_button_add(parent, obj, wd->layout, "media_player/rewind", _rewind); + wd->stop = _player_button_add(parent, obj, wd->layout, "media_player/stop", _stop); + + wd->slider = elm_slider_add(parent); + elm_widget_sub_object_add(obj, wd->slider); + elm_slider_indicator_format_function_set(wd->slider, _double_to_time, _value_free); + elm_slider_units_format_function_set(wd->slider, _double_to_time, _value_free); + elm_slider_min_max_set(wd->slider, 0, 0); + elm_slider_value_set(wd->slider, 0); + elm_object_disabled_set(wd->slider, EINA_TRUE); + evas_object_size_hint_align_set(wd->slider, EVAS_HINT_FILL, 0.5); + evas_object_size_hint_weight_set(wd->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + edje_object_part_swallow(wd->layout, "media_player/slider", wd->slider); + evas_object_smart_callback_add(wd->slider, "changed", _update_position, obj); + + wd->emotion = NULL; + wd->video = NULL; + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; #else + (void) parent; return NULL; #endif } diff --git a/src/lib/elm_actionslider.c b/src/lib/elm_actionslider.c index 53c9d7b28..ec3087b1e 100644 --- a/src/lib/elm_actionslider.c +++ b/src/lib/elm_actionslider.c @@ -1,512 +1,443 @@ #include <Elementary.h> #include <math.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char ACTIONSLIDER_SMART_NAME[] = "elm_actionslider"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Actionslider_Smart_Data Elm_Actionslider_Smart_Data; - -struct _Elm_Actionslider_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *drag_button_base; - Elm_Actionslider_Pos magnet_position, enabled_position; - Ecore_Animator *button_animator; - double final_position; - - Eina_Bool mouse_down : 1; + Evas_Object *as; // actionslider + Evas_Object *drag_button_base; + Elm_Actionslider_Pos magnet_position, enabled_position; + const char *text_left, *text_right, *text_center; + const char *indicator_label; + Ecore_Animator *button_animator; + double final_position; + Eina_Bool mouse_down : 1; }; -static const Elm_Layout_Part_Alias_Description _text_aliases[] = -{ - {"indicator", "elm.text.indicator"}, - {"left", "elm.text.left"}, - {"right", "elm.text.right"}, - {"center", "elm.text.center"}, - {NULL, NULL} -}; +static const char *widtype = NULL; static const char SIG_CHANGED[] = "pos_changed"; static const char SIG_SELECTED[] = "selected"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = + +static const Evas_Smart_Cb_Description _signals[] = { - {SIG_CHANGED, ""}, - {SIG_SELECTED, ""}, - {NULL, NULL} + {SIG_CHANGED, ""}, + {SIG_SELECTED, ""}, + {NULL, NULL} }; -#define ELM_ACTIONSLIDER_DATA_GET(o, sd) \ - Elm_Actionslider_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_ACTIONSLIDER_DATA_GET_OR_RETURN(o, ptr) \ - ELM_ACTIONSLIDER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_ACTIONSLIDER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_ACTIONSLIDER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_ACTIONSLIDER_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), ACTIONSLIDER_SMART_NAME, \ - __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (ACTIONSLIDER_SMART_NAME, _elm_actionslider, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->drag_button_base) + { + evas_object_del(wd->drag_button_base); + wd->drag_button_base = NULL; + } + if (wd->text_left) eina_stringshare_del(wd->text_left); + if (wd->text_right) eina_stringshare_del(wd->text_right); + if (wd->text_center) eina_stringshare_del(wd->text_center); + if (wd->indicator_label) eina_stringshare_del(wd->indicator_label); + free(wd); +} static Elm_Actionslider_Pos -_get_pos_by_orientation(const Evas_Object *obj, - Elm_Actionslider_Pos pos) +_get_pos_by_orientation(const Evas_Object *obj, Elm_Actionslider_Pos pos) { if (elm_widget_mirrored_get(obj)) { switch (pos) { case ELM_ACTIONSLIDER_LEFT: - pos = ELM_ACTIONSLIDER_RIGHT; - break; - + pos = ELM_ACTIONSLIDER_RIGHT; + break; case ELM_ACTIONSLIDER_RIGHT: - pos = ELM_ACTIONSLIDER_LEFT; - break; - + pos = ELM_ACTIONSLIDER_LEFT; + break; default: - break; + break; } } return pos; } static void -_elm_actionslider_smart_sizing_eval(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Evas_Coord minw = -1, minh = -1; + Widget_Data *wd = elm_widget_data_get(obj); + double pos; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); + if (!wd) return; + if (edje_object_mirrored_get(wd->as) == rtl) + return; + edje_object_mirrored_set(wd->as, rtl); + if (!elm_widget_mirrored_get(obj)) + { + edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_left); + edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_right); + } + else + { + edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_right); + edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_left); + } + edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &pos, NULL); + edje_object_part_drag_value_set(wd->as, "elm.drag_button_base", 1.0 - pos, 0.5); +} + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; + + if (!wd) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_size_hint_min_set(sd->drag_button_base, minw, minh); - evas_object_size_hint_max_set(sd->drag_button_base, -1, -1); + evas_object_size_hint_min_set(wd->drag_button_base, minw, minh); + evas_object_size_hint_max_set(wd->drag_button_base, -1, -1); minw = -1; minh = -1; elm_coords_finger_size_adjust(3, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(wd->as, &minw, &minh, minw, minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); } static void -_mirroredness_change_eval(Evas_Object *obj) -{ - double pos; - char *left; - - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - left = (char *)elm_layout_text_get(obj, "elm.text.left"); - if (left) left = strdup(left); - - elm_layout_text_set - (obj, "elm.text.left", elm_layout_text_get(obj, "elm.text.right")); - elm_layout_text_set(obj, "elm.text.right", left); - - free(left); - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &pos, NULL); - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", 1.0 - pos, 0.5); -} - -static Eina_Bool -_elm_actionslider_smart_theme(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - Eina_Bool mirrored; - - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - mirrored = elm_object_mirrored_get(obj); - - if (!ELM_WIDGET_CLASS(_elm_actionslider_parent_sc)->theme(obj)) - return EINA_FALSE; - - if (elm_object_mirrored_get(obj) != mirrored) - _mirroredness_change_eval(obj); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - return EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + if (!edje_object_part_swallow_get(wd->as, "elm.drag_button_base")) + edje_object_part_unswallow(wd->as, wd->drag_button_base); + + _elm_theme_object_set(obj, wd->as, "actionslider", + "base", elm_widget_style_get(obj)); + _elm_theme_object_set(obj, wd->drag_button_base, "actionslider", + "drag_button", elm_widget_style_get(obj)); + edje_object_part_swallow(wd->as, "elm.drag_button_base", wd->drag_button_base); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + edje_object_part_text_escaped_set(wd->as, "elm.text.center", wd->text_center); + edje_object_part_text_escaped_set(wd->as, "elm.text.indicator", wd->indicator_label); + edje_object_message_signal_process(wd->as); + _sizing_eval(obj); } static void -_drag_button_down_cb(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_drag_button_down_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - Elm_Actionslider_Smart_Data *sd = data; - - sd->mouse_down = EINA_TRUE; + Widget_Data *wd = elm_widget_data_get((Evas_Object *) data); + if (!wd) return; + wd->mouse_down = EINA_TRUE; } static void -_drag_button_move_cb(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_drag_button_move_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *obj = data; + Evas_Object *obj = (Evas_Object *) data; + Widget_Data *wd = elm_widget_data_get(obj); double pos = 0.0; + if (!wd) return; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - if (!sd->mouse_down) return; - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &pos, NULL); + if (!wd->mouse_down) return; + edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &pos, NULL); if (pos == 0.0) - evas_object_smart_callback_call - (obj, SIG_CHANGED, !elm_widget_mirrored_get(obj) ? "left" : "right"); + evas_object_smart_callback_call(obj, SIG_CHANGED, + (void *) ((!elm_widget_mirrored_get(obj)) ? + "left" : "right")); else if (pos == 1.0) - evas_object_smart_callback_call - (obj, SIG_CHANGED, !elm_widget_mirrored_get(obj) ? "right" : "left"); + evas_object_smart_callback_call(obj, SIG_CHANGED, + (void *) ((!elm_widget_mirrored_get(obj)) ? + "right" : "left")); else if (pos >= 0.45 && pos <= 0.55) - evas_object_smart_callback_call(obj, SIG_CHANGED, "center"); -} - -static void -_text_get(const Evas_Object *obj, - const char **left, - const char **right, - const char **center) -{ - /* mirroredness already evaluated by the two calls below */ - *left = elm_layout_text_get(obj, "left"); - *right = elm_layout_text_get(obj, "right"); - *center = elm_layout_text_get(obj, "center"); + evas_object_smart_callback_call(obj, SIG_CHANGED, (void *)"center"); } static Eina_Bool -_button_animator(void *data) +_button_animation(void *data) { Evas_Object *obj = data; + Widget_Data *wd = elm_widget_data_get(obj); + double cur_position = 0.0, new_position = 0.0; double move_amount = 0.05; Eina_Bool flag_finish_animation = EINA_FALSE; - double cur_position = 0.0, new_position = 0.0; + if (!wd) return ECORE_CALLBACK_CANCEL; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", - &cur_position, NULL); - { - double adjusted_final; - - adjusted_final = (!elm_widget_mirrored_get(obj)) ? - sd->final_position : 1.0 - sd->final_position; - - if ((adjusted_final == 0.0) || - (adjusted_final == 0.5 && cur_position >= adjusted_final)) - { - new_position = cur_position - move_amount; - - if (new_position <= adjusted_final) - { - new_position = adjusted_final; - flag_finish_animation = EINA_TRUE; - } - } - else if ((adjusted_final == 1.0) || - (adjusted_final == 0.5 && cur_position < adjusted_final)) - { - new_position = cur_position + move_amount; - - if (new_position >= adjusted_final) - { - new_position = adjusted_final; - flag_finish_animation = EINA_TRUE; - } - } - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", - new_position, 0.5); - } + edje_object_part_drag_value_get(wd->as, + "elm.drag_button_base", &cur_position, NULL); + { + double adjusted_final; + adjusted_final = (!elm_widget_mirrored_get(obj)) ? + wd->final_position : 1.0 - wd->final_position; + if ((adjusted_final == 0.0) || + (adjusted_final == 0.5 && cur_position >= adjusted_final)) + { + new_position = cur_position - move_amount; + if (new_position <= adjusted_final) + { + new_position = adjusted_final; + flag_finish_animation = EINA_TRUE; + } + } + else if ((adjusted_final == 1.0) || + (adjusted_final == 0.5 && cur_position < adjusted_final)) + { + new_position = cur_position + move_amount; + if (new_position >= adjusted_final) + { + new_position = adjusted_final; + flag_finish_animation = EINA_TRUE; + } + } + edje_object_part_drag_value_set(wd->as, + "elm.drag_button_base", new_position, 0.5); + } if (flag_finish_animation) { - const char *left, *right, *center; - - _text_get(obj, &left, &right, ¢er); - - if ((!sd->final_position) && - (sd->enabled_position & ELM_ACTIONSLIDER_LEFT)) - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)left); - else if ((sd->final_position == 0.5) && - (sd->enabled_position & ELM_ACTIONSLIDER_CENTER)) - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)center); - else if ((sd->final_position == 1) && - (sd->enabled_position & ELM_ACTIONSLIDER_RIGHT)) - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)right); - - sd->button_animator = NULL; - + if ((!wd->final_position) && + (wd->enabled_position & ELM_ACTIONSLIDER_LEFT)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_left); + else if ((wd->final_position == 0.5) && + (wd->enabled_position & ELM_ACTIONSLIDER_CENTER)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_center); + else if ((wd->final_position == 1) && + (wd->enabled_position & ELM_ACTIONSLIDER_RIGHT)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_right); + wd->button_animator = NULL; return ECORE_CALLBACK_CANCEL; } - return ECORE_CALLBACK_RENEW; } static void -_drag_button_up_cb(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_drag_button_up_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *obj = data; + Evas_Object *obj = (Evas_Object *) data; + Widget_Data *wd = elm_widget_data_get(obj); double position = 0.0; + if (!wd) return; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - sd->mouse_down = EINA_FALSE; + wd->mouse_down = EINA_FALSE; - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &position, - NULL); + edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", + &position, NULL); - const char *left, *right, *center; - - _text_get(obj, &left, &right, ¢er); - - if ((sd->enabled_position & ELM_ACTIONSLIDER_LEFT) && + if ((wd->enabled_position & ELM_ACTIONSLIDER_LEFT) && ((!elm_widget_mirrored_get(obj) && position == 0.0) || (elm_widget_mirrored_get(obj) && position == 1.0))) { - sd->final_position = 0; - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)left); - + wd->final_position = 0; + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *) wd->text_left); return; } - if (position >= 0.45 && position <= 0.55 && - (sd->enabled_position & ELM_ACTIONSLIDER_CENTER)) + (wd->enabled_position & ELM_ACTIONSLIDER_CENTER)) { - sd->final_position = 0.5; - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)center); - - if (sd->button_animator) ecore_animator_del(sd->button_animator); - sd->button_animator = ecore_animator_add(_button_animator, obj); - + wd->final_position = 0.5; + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_center); + if (wd->button_animator) ecore_animator_del(wd->button_animator); + wd->button_animator = ecore_animator_add(_button_animation, data); return; } - - if ((sd->enabled_position & ELM_ACTIONSLIDER_RIGHT) && + if ((wd->enabled_position & ELM_ACTIONSLIDER_RIGHT) && ((!elm_widget_mirrored_get(obj) && position == 1.0) || (elm_widget_mirrored_get(obj) && position == 0.0))) { - sd->final_position = 1; - evas_object_smart_callback_call(obj, SIG_SELECTED, (char *)right); + wd->final_position = 1; + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *) wd->text_right); return; } - if (sd->magnet_position == ELM_ACTIONSLIDER_NONE) return; + if (wd->magnet_position == ELM_ACTIONSLIDER_NONE) return; -#define _FIX_POS_ON_MIRROREDNESS(x) \ - ((!elm_widget_mirrored_get(obj)) ? x : 1.0 - x) +#define _FINAL_POS_BY_ORIENTATION(x) (x) +#define _POS_BY_ORIENTATION(x) \ + ((!elm_widget_mirrored_get(obj)) ? \ + x : 1.0 - x) - position = _FIX_POS_ON_MIRROREDNESS(position); + position = _POS_BY_ORIENTATION(position); if (position < 0.3) { - if (sd->magnet_position & ELM_ACTIONSLIDER_LEFT) - sd->final_position = 0; - else if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER) - sd->final_position = 0.5; - else if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT) - sd->final_position = 1; + if (wd->magnet_position & ELM_ACTIONSLIDER_LEFT) + wd->final_position = _FINAL_POS_BY_ORIENTATION(0); + else if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER) + wd->final_position = 0.5; + else if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT) + wd->final_position = _FINAL_POS_BY_ORIENTATION(1); } else if ((position >= 0.3) && (position <= 0.7)) { - if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER) - sd->final_position = 0.5; + if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER) + wd->final_position = 0.5; else if (position < 0.5) { - if (sd->magnet_position & ELM_ACTIONSLIDER_LEFT) - sd->final_position = 0; + if (wd->magnet_position & ELM_ACTIONSLIDER_LEFT) + wd->final_position = _FINAL_POS_BY_ORIENTATION(0); else - sd->final_position = 1; + wd->final_position = _FINAL_POS_BY_ORIENTATION(1); } else { - if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT) - sd->final_position = 1; + if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT) + wd->final_position = _FINAL_POS_BY_ORIENTATION(1); else - sd->final_position = 0; + wd->final_position = _FINAL_POS_BY_ORIENTATION(0); } } else { - if (sd->magnet_position & ELM_ACTIONSLIDER_RIGHT) - sd->final_position = 1; - else if (sd->magnet_position & ELM_ACTIONSLIDER_CENTER) - sd->final_position = 0.5; + if (wd->magnet_position & ELM_ACTIONSLIDER_RIGHT) + wd->final_position = _FINAL_POS_BY_ORIENTATION(1); + else if (wd->magnet_position & ELM_ACTIONSLIDER_CENTER) + wd->final_position = 0.5; else - sd->final_position = 0; + wd->final_position = _FINAL_POS_BY_ORIENTATION(0); } - if (sd->button_animator) ecore_animator_del(sd->button_animator); - sd->button_animator = ecore_animator_add(_button_animator, obj); + if (wd->button_animator) ecore_animator_del(wd->button_animator); + wd->button_animator = ecore_animator_add(_button_animation, data); -#undef _FINAL_FIX_POS_ON_MIRROREDNESS +#undef _FINAL_POS_BY_ORIENTATION } static void -_mirrored_part_fix(const Evas_Object *obj, - const char **part) +_elm_actionslider_label_set(Evas_Object *obj, const char *item, const char *label) { - if (elm_widget_mirrored_get(obj)) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (!item || !strcmp(item, "indicator")) { - /* exchange left and right */ - if (!strcmp(*part, "left")) *part = "right"; - else if (!strcmp(*part, "right")) - *part = "left"; - else if (!strcmp(*part, "elm.text.right")) - *part = "elm.text.left"; - else if (!strcmp(*part, "elm.text.left")) - *part = "elm.text.right"; + eina_stringshare_replace(&wd->indicator_label, label); + edje_object_part_text_escaped_set(wd->as, "elm.text.indicator", + wd->indicator_label); + } + else if (!strcmp(item, "left")) + { + eina_stringshare_replace(&wd->text_left, label); + if (!elm_widget_mirrored_get(obj)) + edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_left); + else + edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_left); + } + else if (!strcmp(item, "center")) + { + eina_stringshare_replace(&wd->text_center, label); + edje_object_part_text_escaped_set(wd->as, "elm.text.center", wd->text_center); + } + else if (!strcmp(item, "right")) + { + eina_stringshare_replace(&wd->text_right, label); + if (!elm_widget_mirrored_get(obj)) + edje_object_part_text_escaped_set(wd->as, "elm.text.right", wd->text_right); + else + edje_object_part_text_escaped_set(wd->as, "elm.text.left", wd->text_right); } -} - -static Eina_Bool -_elm_actionslider_smart_text_set(Evas_Object *obj, - const char *item, - const char *label) -{ - _mirrored_part_fix(obj, &item); - - return _elm_actionslider_parent_sc->text_set(obj, item, label); } static const char * -_elm_actionslider_smart_text_get(const Evas_Object *obj, - const char *item) -{ - _mirrored_part_fix(obj, &item); - - return _elm_actionslider_parent_sc->text_get(obj, item); -} - -static void -_elm_actionslider_smart_add(Evas_Object *obj) +_elm_actionslider_label_get(const Evas_Object *obj, const char *item) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Actionslider_Smart_Data); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + if (!item || !strcmp(item, "indicator")) + return wd->indicator_label; + else if (!strcmp(item, "left")) + return wd->text_left; + else if (!strcmp(item, "center")) + return wd->text_center; + else if (!strcmp(item, "right")) + return wd->text_right; - ELM_WIDGET_CLASS(_elm_actionslider_parent_sc)->base.add(obj); - - priv->mouse_down = EINA_FALSE; - priv->enabled_position = ELM_ACTIONSLIDER_ALL; - - priv->drag_button_base = - evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_color_set(priv->drag_button_base, 0, 0, 0, 0); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,up", "", - _drag_button_up_cb, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,down", "", - _drag_button_down_cb, priv); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.drag_button,mouse,move", "", - _drag_button_move_cb, obj); - - elm_layout_theme_set - (obj, "actionslider", "base", elm_widget_style_get(obj)); - - elm_layout_content_set(obj, "elm.drag_button_base", priv->drag_button_base); -} - -static void -_elm_actionslider_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_actionslider_smart_add; - - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - ELM_WIDGET_CLASS(sc)->theme = _elm_actionslider_smart_theme; - - sc->sizing_eval = _elm_actionslider_smart_sizing_eval; - sc->text_set = _elm_actionslider_smart_text_set; - sc->text_get = _elm_actionslider_smart_text_get; - - sc->text_aliases = _text_aliases; + return NULL; } EAPI Evas_Object * elm_actionslider_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Widget_Data *wd; + Evas *e; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_actionslider_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_sizing_eval(obj); - + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "actionslider"); + elm_widget_type_set(obj, "actionslider"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_text_set_hook_set(obj, _elm_actionslider_label_set); + elm_widget_text_get_hook_set(obj, _elm_actionslider_label_get); + + wd->mouse_down = EINA_FALSE; + wd->enabled_position = ELM_ACTIONSLIDER_ALL; + + wd->as = edje_object_add(e); + _elm_theme_object_set(obj, wd->as, "actionslider", "base", "default"); + elm_widget_resize_object_set(obj, wd->as); + + wd->drag_button_base = evas_object_rectangle_add(e); + evas_object_color_set(wd->drag_button_base, 0, 0, 0, 0); + edje_object_part_swallow(wd->as, "elm.drag_button_base", wd->drag_button_base); + + edje_object_signal_callback_add(wd->as, + "elm.drag_button,mouse,up", "", + _drag_button_up_cb, obj); + edje_object_signal_callback_add(wd->as, + "elm.drag_button,mouse,down", "", + _drag_button_down_cb, obj); + edje_object_signal_callback_add(wd->as, + "elm.drag_button,mouse,move", "", + _drag_button_move_cb, obj); + + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_actionslider_indicator_pos_set(Evas_Object *obj, - Elm_Actionslider_Pos pos) +elm_actionslider_indicator_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); double position = 0.0; - - ELM_ACTIONSLIDER_CHECK(obj); - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - + if (!wd) return; pos = _get_pos_by_orientation(obj, pos); if (pos == ELM_ACTIONSLIDER_CENTER) position = 0.5; - else if (pos == ELM_ACTIONSLIDER_RIGHT) - position = 1.0; - - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", position, 0.5); + else if (pos == ELM_ACTIONSLIDER_RIGHT) position = 1.0; + edje_object_part_drag_value_set(wd->as, "elm.drag_button_base", position, 0.5); } EAPI Elm_Actionslider_Pos elm_actionslider_indicator_pos_get(const Evas_Object *obj) { + ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); double position; + if (!wd) return ELM_ACTIONSLIDER_NONE; - ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.drag_button_base", &position, - NULL); + edje_object_part_drag_value_get(wd->as, "elm.drag_button_base", &position, NULL); if (position < 0.3) return _get_pos_by_orientation(obj, ELM_ACTIONSLIDER_LEFT); else if (position < 0.7) @@ -516,64 +447,59 @@ elm_actionslider_indicator_pos_get(const Evas_Object *obj) } EAPI void -elm_actionslider_magnet_pos_set(Evas_Object *obj, - Elm_Actionslider_Pos pos) +elm_actionslider_magnet_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos) { - ELM_ACTIONSLIDER_CHECK(obj); - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - sd->magnet_position = pos; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->magnet_position = pos; } EAPI Elm_Actionslider_Pos elm_actionslider_magnet_pos_get(const Evas_Object *obj) { - ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - return sd->magnet_position; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_ACTIONSLIDER_NONE; + return wd->magnet_position; } EAPI void -elm_actionslider_enabled_pos_set(Evas_Object *obj, - Elm_Actionslider_Pos pos) +elm_actionslider_enabled_pos_set(Evas_Object *obj, Elm_Actionslider_Pos pos) { - ELM_ACTIONSLIDER_CHECK(obj); - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - sd->enabled_position = pos; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->enabled_position = pos; } EAPI Elm_Actionslider_Pos elm_actionslider_enabled_pos_get(const Evas_Object *obj) { - ELM_ACTIONSLIDER_CHECK(obj) ELM_ACTIONSLIDER_NONE; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - return sd->enabled_position; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_ACTIONSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_ACTIONSLIDER_NONE; + return wd->enabled_position; } EAPI const char * elm_actionslider_selected_label_get(const Evas_Object *obj) { - const char *left, *right, *center; - - ELM_ACTIONSLIDER_CHECK(obj) NULL; - ELM_ACTIONSLIDER_DATA_GET(obj, sd); - - _text_get(obj, &left, &right, ¢er); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - if ((sd->final_position == 0.0) && - (sd->enabled_position & ELM_ACTIONSLIDER_LEFT)) - return left; + if ((wd->final_position == 0.0) && + (wd->enabled_position & ELM_ACTIONSLIDER_LEFT)) + return wd->text_left; - if ((sd->final_position == 0.5) && - (sd->enabled_position & ELM_ACTIONSLIDER_CENTER)) - return center; + if ((wd->final_position == 0.5) && + (wd->enabled_position & ELM_ACTIONSLIDER_CENTER)) + return wd->text_center; - if ((sd->final_position == 1.0) && - (sd->enabled_position & ELM_ACTIONSLIDER_RIGHT)) - return right; + if ((wd->final_position == 1.0) && + (wd->enabled_position & ELM_ACTIONSLIDER_RIGHT)) + return wd->text_right; return NULL; } diff --git a/src/lib/elm_actionslider.h b/src/lib/elm_actionslider.h index 7e60ab175..1be91fc53 100644 --- a/src/lib/elm_actionslider.h +++ b/src/lib/elm_actionslider.h @@ -21,15 +21,12 @@ * * @note By default all positions are set as enabled. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for actionslider objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @c "selected" - when user selects an enabled position (the - * label is passed as event info)". - * @li @c "pos_changed" - when the indicator reaches any of the - * positions("left", "right" or "center"). + * Signals that you can add callbacks for are: + * + * "selected" - when user selects an enabled position (the label is passed as + * event info)". + * "pos_changed" - when the indicator reaches any of the positions("left", + * "right" or "center"). * * Default text parts of the actionslider widget that you can use for are: * @li "indicator" - An indicator label of the actionslider diff --git a/src/lib/elm_bg.c b/src/lib/elm_bg.c index 83e8e5169..df29d5b24 100644 --- a/src/lib/elm_bg.c +++ b/src/lib/elm_bg.c @@ -1,90 +1,75 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char BG_SMART_NAME[] = "elm_bg"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Bg_Smart_Data Elm_Bg_Smart_Data; - -struct _Elm_Bg_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - -/* the basic background's edje object has three swallow spots, namely: - * - "elm.swallow.rectangle" (elm_bg_color_set), - * - "elm.swallow.background" (elm_bg_file_set) and - * - "elm.swallow.content" (elm_bg_overlay_set). - * the following three variables hold possible content to fit in each - * of them, respectively. */ - - Evas_Object *rect, *img; - const char *file, *group; /* path to file and group name - * to give life to "img" */ - Elm_Bg_Option option; + Evas_Object *base, *rect, *img, *overlay; + const char *file, *group; + Elm_Bg_Option option; struct - { - Evas_Coord w, h; - } load_opts; + { + Evas_Coord w, h; + } load_opts; }; -#define ELM_BG_DATA_GET(o, sd) \ - Elm_Bg_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_BG_DATA_GET_OR_RETURN(o, ptr) \ - ELM_BG_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_BG_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_BG_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_BG_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), BG_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +static const char *widtype = NULL; + +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _custom_resize(void *data, Evas *a, Evas_Object *obj, void *event_info); +static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part); + +static void +_del_hook(Evas_Object *obj) { - {"overlay", "elm.swallow.content"}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + free(wd); +} -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (BG_SMART_NAME, _elm_bg, Elm_Layout_Smart_Class, Elm_Layout_Smart_Class, - elm_layout_smart_class_get, NULL); +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord w, h; + + _elm_theme_object_set(obj, wd->base, "bg", "base", + elm_widget_style_get(obj)); + + if (wd->rect) + edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect); + if (wd->img) + edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img); + if (wd->overlay) + edje_object_part_swallow(wd->base, "elm.swallow.content", wd->overlay); + + // FIXME: if i don't do this, bg doesnt calc correctly. why? + evas_object_geometry_get(wd->base, NULL, NULL, &w, &h); + evas_object_resize(wd->base, w, h); +} static void -_elm_bg_smart_sizing_eval(Evas_Object *obj) +_custom_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Evas_Coord iw = 0, ih = 0, mw = -1, mh = -1; + Widget_Data *wd = data; Evas_Coord bx = 0, by = 0, bw = 0, bh = 0; + Evas_Coord iw = 0, ih = 0, mw = -1, mh = -1; Evas_Coord fx = 0, fy = 0, fw = 0, fh = 0; Evas_Coord nx = 0, ny = 0, nw = 0, nh = 0; const char *p; - ELM_BG_DATA_GET(obj, sd); - - if ((!sd->img) || (!sd->file)) return; - if (((p = strrchr(sd->file, '.'))) && (!strcasecmp(p, ".edj"))) return; + if ((!wd->img) || (!wd->file)) return; + if (((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj"))) return; /* grab image size */ - evas_object_image_size_get(sd->img, &iw, &ih); + evas_object_image_size_get(wd->img, &iw, &ih); if ((iw < 1) || (ih < 1)) return; /* grab base object dimensions */ - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, &bx, &by, &bw, &bh); + evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh); /* set some defaults */ nx = bx; @@ -92,246 +77,248 @@ _elm_bg_smart_sizing_eval(Evas_Object *obj) nw = bw; nh = bh; - switch (sd->option) + switch (wd->option) { case ELM_BG_OPTION_CENTER: - fw = nw = iw; - fh = nh = ih; - nx = ((bw - fw) / 2); - ny = ((bh - fh) / 2); - mw = iw; - mh = ih; - break; - + fw = nw = iw; + fh = nh = ih; + nx = ((bw - fw) / 2); + ny = ((bh - fh) / 2); + mw = iw; + mh = ih; + break; case ELM_BG_OPTION_SCALE: - fw = bw; - fh = ((ih * fw) / iw); - if (fh < bh) - { - fh = bh; - fw = ((iw * fh) / ih); - } - fx = ((bw - fw) / 2); - fy = ((bh - fh) / 2); - break; - + fw = bw; + fh = ((ih * fw) / iw); + if (fh < bh) + { + fh = bh; + fw = ((iw * fh) / ih); + } + fx = ((bw - fw) / 2); + fy = ((bh - fh) / 2); + break; case ELM_BG_OPTION_TILE: - fw = iw; - fh = ih; - break; - + fw = iw; + fh = ih; + break; case ELM_BG_OPTION_STRETCH: default: - fw = bw; - fh = bh; - break; + fw = bw; + fh = bh; + break; } - evas_object_move(sd->img, nx, ny); - evas_object_resize(sd->img, nw, nh); - evas_object_image_fill_set(sd->img, fx, fy, fw, fh); + evas_object_move(wd->img, nx, ny); + evas_object_resize(wd->img, nw, nh); + evas_object_image_fill_set(wd->img, fx, fy, fw, fh); - evas_object_size_hint_min_set(sd->img, mw, mh); - evas_object_size_hint_max_set(sd->img, mw, mh); + evas_object_size_hint_min_set(wd->img, mw, mh); + evas_object_size_hint_max_set(wd->img, mw, mh); } static void -_on_resize(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - elm_layout_sizing_eval(data); -} + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + if (part && strcmp(part, "overlay")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; -static void -_elm_bg_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Bg_Smart_Data); - - ELM_WIDGET_CLASS(_elm_bg_parent_sc)->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); + if (content == wd->overlay) return; + if (wd->overlay) evas_object_del(wd->overlay); - priv->option = ELM_BG_OPTION_SCALE; - - evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize, obj); + wd->overlay = content; + if (content) + { + edje_object_part_swallow(wd->base, "elm.swallow.content", content); + elm_widget_sub_object_add(obj, content); + } - elm_layout_theme_set(obj, "bg", "base", elm_widget_style_get(obj)); + _custom_resize(wd, NULL, NULL, NULL); } -static void -_elm_bg_smart_set_user(Elm_Layout_Smart_Class *sc) +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_bg_smart_add; - - sc->sizing_eval = _elm_bg_smart_sizing_eval; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + if (part && strcmp(part, "overlay")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->overlay; +} - sc->content_aliases = _content_aliases; +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + Evas_Object *overlay; + if (part && strcmp(part, "overlay")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd || !wd->overlay) return NULL; + overlay = wd->overlay; + elm_widget_sub_object_del(obj, wd->overlay); + edje_object_part_unswallow(wd->base, wd->overlay); + wd->overlay = NULL; + _custom_resize(wd, NULL, NULL, NULL); + return overlay; } EAPI Evas_Object * elm_bg_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - e = evas_object_evas_get(parent); - if (!e) return NULL; + ELM_SET_WIDTYPE(widtype, "bg"); + elm_widget_type_set(obj, "bg"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + elm_widget_can_focus_set(obj, EINA_FALSE); - obj = evas_object_smart_add(e, _elm_bg_smart_class_new()); + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "bg", "base", "default"); + elm_widget_resize_object_set(obj, wd->base); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, + _custom_resize, wd); + wd->option = ELM_BG_OPTION_SCALE; return obj; } EAPI Eina_Bool -elm_bg_file_set(Evas_Object *obj, - const char *file, - const char *group) +elm_bg_file_set(Evas_Object *obj, const char *file, const char *group) { - ELM_BG_CHECK(obj) EINA_FALSE; - ELM_BG_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); const char *p; - Eina_Bool ret; - if (sd->img) + if (wd->img) { - evas_object_del(sd->img); - sd->img = NULL; + evas_object_del(wd->img); + wd->img = NULL; } if (!file) { - eina_stringshare_del(sd->file); - sd->file = NULL; - eina_stringshare_del(sd->group); - sd->group = NULL; + eina_stringshare_del(wd->file); + wd->file = NULL; + eina_stringshare_del(wd->group); + wd->group = NULL; return EINA_TRUE; } - eina_stringshare_replace(&sd->file, file); - eina_stringshare_replace(&sd->group, group); + eina_stringshare_replace(&wd->file, file); + eina_stringshare_replace(&wd->group, group); if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj"))) { - sd->img = edje_object_add - (evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj)); - ret = edje_object_file_set(sd->img, file, group); + wd->img = edje_object_add(evas_object_evas_get(wd->base)); + edje_object_file_set(wd->img, file, group); } else { - int err; - - sd->img = evas_object_image_add - (evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj)); - if ((sd->load_opts.w > 0) && (sd->load_opts.h > 0)) - evas_object_image_load_size_set - (sd->img, sd->load_opts.w, sd->load_opts.h); - evas_object_image_file_set(sd->img, file, group); - - err = evas_object_image_load_error_get(sd->img); - if (err != EVAS_LOAD_ERROR_NONE) - { - ERR("Could not load image '%s': %s\n", - file, evas_load_error_str(err)); - ret = EINA_FALSE; - } - else - ret = EINA_TRUE; + wd->img = evas_object_image_add(evas_object_evas_get(wd->base)); + if ((wd->load_opts.w > 0) && (wd->load_opts.h > 0)) + evas_object_image_load_size_set(wd->img, wd->load_opts.w, wd->load_opts.h); + evas_object_image_file_set(wd->img, file, group); } + evas_object_repeat_events_set(wd->img, EINA_TRUE); + edje_object_part_swallow(wd->base, "elm.swallow.background", wd->img); + elm_widget_sub_object_add(obj, wd->img); + _custom_resize(wd, NULL, NULL, NULL); - evas_object_repeat_events_set(sd->img, EINA_TRUE); - - ret &= elm_layout_content_set(obj, "elm.swallow.background", sd->img); - - elm_layout_sizing_eval(obj); - - return ret; + return EINA_TRUE; } EAPI void -elm_bg_file_get(const Evas_Object *obj, - const char **file, - const char **group) +elm_bg_file_get(const Evas_Object *obj, const char **file, const char **group) { - ELM_BG_CHECK(obj); - ELM_BG_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (file) *file = wd->file; + if (group) *group = wd->group; - if (file) *file = sd->file; - if (group) *group = sd->group; + return; } EAPI void -elm_bg_option_set(Evas_Object *obj, - Elm_Bg_Option option) +elm_bg_option_set(Evas_Object *obj, Elm_Bg_Option option) { - ELM_BG_CHECK(obj); - ELM_BG_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; - sd->option = option; + wd = elm_widget_data_get(obj); + wd->option = option; + _custom_resize(wd, NULL, NULL, NULL); - elm_layout_sizing_eval(obj); + return; } EAPI Elm_Bg_Option elm_bg_option_get(const Evas_Object *obj) { - ELM_BG_CHECK(obj) EINA_FALSE; - ELM_BG_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_BG_OPTION_LAST); + ELM_CHECK_WIDTYPE(obj, widtype) ELM_BG_OPTION_LAST; + Widget_Data *wd; - return sd->option; + wd = elm_widget_data_get(obj); + return wd->option; } EAPI void -elm_bg_color_set(Evas_Object *obj, - int r, - int g, - int b) +elm_bg_color_set(Evas_Object *obj, int r, int g, int b) { - ELM_BG_CHECK(obj); - ELM_BG_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; - if (!sd->rect) + wd = elm_widget_data_get(obj); + if (!wd->rect) { - sd->rect = evas_object_rectangle_add - (evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj)); - - elm_layout_content_set(obj, "elm.swallow.rectangle", sd->rect); - - elm_layout_sizing_eval(obj); + wd->rect = evas_object_rectangle_add(evas_object_evas_get(wd->base)); + edje_object_part_swallow(wd->base, "elm.swallow.rectangle", wd->rect); + elm_widget_sub_object_add(obj, wd->rect); + _custom_resize(wd, NULL, NULL, NULL); } + evas_object_color_set(wd->rect, r, g, b, 255); - evas_object_color_set(sd->rect, r, g, b, 255); + return; } EAPI void -elm_bg_color_get(const Evas_Object *obj, - int *r, - int *g, - int *b) +elm_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b) { - ELM_BG_CHECK(obj); - ELM_BG_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + evas_object_color_get(wd->rect, r, g, b, NULL); - evas_object_color_get(sd->rect, r, g, b, NULL); + return; } EAPI void -elm_bg_load_size_set(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +elm_bg_load_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { - ELM_BG_CHECK(obj); - ELM_BG_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); const char *p; - - sd->load_opts.w = w; - sd->load_opts.h = h; - if (!sd->img) return; - - if (!(((p = strrchr(sd->file, '.'))) && (!strcasecmp(p, ".edj")))) - evas_object_image_load_size_set(sd->img, w, h); + if (!wd) return; + wd->load_opts.w = w; + wd->load_opts.h = h; + if (!wd->img) return; + if (!(((p = strrchr(wd->file, '.'))) && (!strcasecmp(p, ".edj")))) + evas_object_image_load_size_set(wd->img, w, h); + + return; } + diff --git a/src/lib/elm_bg.h b/src/lib/elm_bg.h index c1c9314de..6ba62b195 100644 --- a/src/lib/elm_bg.h +++ b/src/lib/elm_bg.h @@ -1,5 +1,5 @@ /** - * @defgroup Bg Background + * @defgroup Bg Bg * @ingroup Elementary * * @image html img/widget/bg/preview-00.png @@ -14,11 +14,8 @@ * properties useful to a background, like setting it to tiled, * centered, scaled or stretched. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for background objects. - * * Default content parts of the bg widget that you can use for are: - * @li @c "overlay" - overlay of the bg + * @li "overlay" - overlay of the bg * * Supported elm_object common APIs. * @li @ref elm_object_part_content_set diff --git a/src/lib/elm_box.c b/src/lib/elm_box.c index 440c08321..bcf0b382a 100644 --- a/src/lib/elm_box.c +++ b/src/lib/elm_box.c @@ -2,90 +2,81 @@ #include "elm_priv.h" #include "els_box.h" -static const char BOX_SMART_NAME[] = "elm_box"; +static const char SIG_CHILD_ADDED[] = "child,added"; +static const char SIG_CHILD_REMOVED[] = "child,removed"; + +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHILD_ADDED, ""}, + {SIG_CHILD_REMOVED, ""}, + {NULL, NULL} +}; -typedef struct _Elm_Box_Smart_Data Elm_Box_Smart_Data; + +typedef struct _Widget_Data Widget_Data; typedef struct _Transition_Animation_Data Transition_Animation_Data; -struct _Elm_Box_Smart_Data +struct _Widget_Data { - Elm_Widget_Smart_Data base; /* base widget smart data as - * first member obligatory, as - * we're inheriting from it */ - - Eina_Bool horizontal : 1; - Eina_Bool homogeneous : 1; - Eina_Bool recalc : 1; + Evas_Object *box; + Eina_Bool horizontal:1; + Eina_Bool homogeneous:1; + Eina_Bool recalc:1; }; struct _Elm_Box_Transition { - double initial_time; - double duration; + double initial_time; + double duration; + Eina_Bool animation_ended:1; + Eina_Bool recalculate:1; Ecore_Animator *animator; struct - { - Evas_Object_Box_Layout layout; - void *data; - void (*free_data)(void *data); - } start, end; - - void (*transition_end_cb)(void *data); - void *transition_end_data; - void (*transition_end_free_data)(void *data); - Eina_List *objs; - Evas_Object *box; - - Eina_Bool animation_ended : 1; - Eina_Bool recalculate : 1; + { + Evas_Object_Box_Layout layout; + void *data; + void(*free_data)(void *data); + } start, end; + + void(*transition_end_cb)(void *data); + void *transition_end_data; + void (*transition_end_free_data)(void *data); + Eina_List *objs; + Evas_Object *box; }; struct _Transition_Animation_Data { Evas_Object *obj; struct - { - Evas_Coord x, y, w, h; - } start, end; + { + Evas_Coord x, y, w, h; + } start, end; }; -#define ELM_BOX_DATA_GET(o, sd) \ - Elm_Box_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_BOX_DATA_GET_OR_RETURN(o, ptr) \ - ELM_BOX_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_BOX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_BOX_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_BOX_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), BOX_SMART_NAME, __func__)) \ - return - -EVAS_SMART_SUBCLASS_NEW - (BOX_SMART_NAME, _elm_box, Elm_Widget_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL); +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); -static const char SIG_CHILD_ADDED[] = "child,added"; -static const char SIG_CHILD_REMOVED[] = "child,removed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHILD_ADDED, ""}, - {SIG_CHILD_REMOVED, ""}, - {NULL, NULL} -}; +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_event_callback_del_full + (wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + evas_object_box_remove_all(wd->box, EINA_FALSE); +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} static void * _elm_box_list_data_get(const Eina_List *list) @@ -95,9 +86,7 @@ _elm_box_list_data_get(const Eina_List *list) } static void -_child_added_cb_proxy(void *data, - Evas_Object *o __UNUSED__, - void *event_info) +_cb_proxy_child_added(void *data, Evas_Object *o __UNUSED__, void *event_info) { Evas_Object *box = data; Evas_Object_Box_Option *opt = event_info; @@ -105,9 +94,7 @@ _child_added_cb_proxy(void *data, } static void -_child_removed_cb_proxy(void *data, - Evas_Object *o __UNUSED__, - void *event_info) +_cb_proxy_child_removed(void *data, Evas_Object *o __UNUSED__, void *event_info) { Evas_Object *box = data; Evas_Object *child = event_info; @@ -115,14 +102,14 @@ _child_removed_cb_proxy(void *data, } static Eina_Bool -_elm_box_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_box_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *items; - void *(*list_data_get)(const Eina_List *list); + void *(*list_data_get) (const Eina_List *list); - ELM_BOX_DATA_GET(obj, sd); + if ((!wd) || (!wd->box)) + return EINA_FALSE; /* Focus chain */ /* TODO: Change this to use other chain */ @@ -130,8 +117,7 @@ _elm_box_smart_focus_next(const Evas_Object *obj, list_data_get = eina_list_data_get; else { - Evas_Object_Box_Data *bd = - evas_object_smart_data_get(ELM_WIDGET_DATA(sd)->resize_obj); + Evas_Object_Box_Data *bd = evas_object_smart_data_get(wd->box); items = bd->children; list_data_get = _elm_box_list_data_get; @@ -141,76 +127,65 @@ _elm_box_smart_focus_next(const Evas_Object *obj, return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next); } -static Eina_Bool -_elm_box_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { - ELM_BOX_DATA_GET(obj, sd); - - if (!_elm_box_parent_sc->theme(obj)) return EINA_FALSE; - - evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj); - - return EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + evas_object_smart_calculate(wd->box); } 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; - - ELM_BOX_DATA_GET(obj, sd); - - evas_object_size_hint_min_get - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_max_get - (ELM_WIDGET_DATA(sd)->resize_obj, &maxw, &maxh); + Evas_Coord w, h; + if (!wd) return; + evas_object_size_hint_min_get(wd->box, &minw, &minh); + evas_object_size_hint_max_get(wd->box, &maxw, &maxh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, maxw, maxh); + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (w < minw) w = minw; + if (h < minh) h = minh; + if ((maxw >= 0) && (w > maxw)) w = maxw; + if ((maxh >= 0) && (h > maxh)) h = maxh; + evas_object_resize(obj, w, h); } static void -_on_size_hints_changed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { _sizing_eval(data); } -static Eina_Bool -_elm_box_smart_sub_object_del(Evas_Object *obj, - Evas_Object *child) +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - if (!_elm_box_parent_sc->sub_object_del(obj, child)) return EINA_FALSE; - _sizing_eval(obj); - - return EINA_TRUE; } static void -_elm_box_custom_layout(Evas_Object *o, - Evas_Object_Box_Data *priv, - void *data) +_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) { - ELM_BOX_DATA_GET(data, sd); - - _els_box_layout(o, priv, sd->horizontal, sd->homogeneous, - elm_widget_mirrored_get(data)); + Evas_Object *obj = (Evas_Object *) data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _els_box_layout(o, priv, wd->horizontal, wd->homogeneous, + elm_widget_mirrored_get(obj)); } static Eina_Bool _transition_animation(void *data) { evas_object_smart_changed(data); - return ECORE_CALLBACK_RENEW; } static void -_transition_layout_child_added(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_transition_layout_child_added(void *data, Evas_Object *obj __UNUSED__, void *event_info) { Transition_Animation_Data *tad; Evas_Object_Box_Option *opt = event_info; @@ -218,22 +193,19 @@ _transition_layout_child_added(void *data, tad = calloc(1, sizeof(Transition_Animation_Data)); if (!tad) return; - tad->obj = opt->obj; layout_data->objs = eina_list_append(layout_data->objs, tad); layout_data->recalculate = EINA_TRUE; } static void -_transition_layout_child_removed(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_transition_layout_child_removed(void *data, Evas_Object *obj __UNUSED__, void *event_info) { Eina_List *l; Transition_Animation_Data *tad; Elm_Box_Transition *layout_data = data; - EINA_LIST_FOREACH (layout_data->objs, l, tad) + EINA_LIST_FOREACH(layout_data->objs, l, tad) { if (tad->obj == event_info) { @@ -246,32 +218,27 @@ _transition_layout_child_removed(void *data, } static void -_transition_layout_obj_resize_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_transition_layout_obj_resize_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { Elm_Box_Transition *layout_data = data; - layout_data->recalculate = EINA_TRUE; } static void -_transition_layout_calculate_coords(Evas_Object *obj, - Evas_Object_Box_Data *priv, +_transition_layout_calculate_coords(Evas_Object *obj, Evas_Object_Box_Data *priv, Elm_Box_Transition *layout_data) { Eina_List *l; - Evas_Coord x, y, w, h; Transition_Animation_Data *tad; + Evas_Coord x, y, w, h; const double curtime = ecore_loop_time_get(); layout_data->duration = - layout_data->duration - (curtime - layout_data->initial_time); + layout_data->duration - (curtime - layout_data->initial_time); layout_data->initial_time = curtime; evas_object_geometry_get(obj, &x, &y, &w, &h); - EINA_LIST_FOREACH (layout_data->objs, l, tad) + EINA_LIST_FOREACH(layout_data->objs, l, tad) { evas_object_geometry_get(tad->obj, &tad->start.x, &tad->start.y, &tad->start.w, &tad->start.h); @@ -279,7 +246,7 @@ _transition_layout_calculate_coords(Evas_Object *obj, tad->start.y = tad->start.y - y; } layout_data->end.layout(obj, priv, layout_data->end.data); - EINA_LIST_FOREACH (layout_data->objs, l, tad) + EINA_LIST_FOREACH(layout_data->objs, l, tad) { evas_object_geometry_get(tad->obj, &tad->end.x, &tad->end.y, &tad->end.w, &tad->end.h); @@ -296,16 +263,16 @@ _transition_layout_load_children_list(Evas_Object_Box_Data *priv, Evas_Object_Box_Option *opt; Transition_Animation_Data *tad; - EINA_LIST_FREE (layout_data->objs, tad) - free(tad); + EINA_LIST_FREE(layout_data->objs, tad) + free(tad); - EINA_LIST_FOREACH (priv->children, l, opt) + EINA_LIST_FOREACH(priv->children, l, opt) { tad = calloc(1, sizeof(Transition_Animation_Data)); if (!tad) { - EINA_LIST_FREE (layout_data->objs, tad) - free(tad); + EINA_LIST_FREE(layout_data->objs, tad) + free(tad); layout_data->objs = NULL; return EINA_FALSE; } @@ -316,11 +283,8 @@ _transition_layout_load_children_list(Evas_Object_Box_Data *priv, } static Eina_Bool -_transition_layout_animation_start(Evas_Object *obj, - Evas_Object_Box_Data *priv, - Elm_Box_Transition *layout_data, - Eina_Bool (*transition_animation_cb) - (void *data)) +_transition_layout_animation_start(Evas_Object *obj, Evas_Object_Box_Data *priv, + Elm_Box_Transition *layout_data, Eina_Bool(*transition_animation_cb)(void *data)) { layout_data->start.layout(obj, priv, layout_data->start.data); layout_data->box = obj; @@ -328,22 +292,17 @@ _transition_layout_animation_start(Evas_Object *obj, if (!_transition_layout_load_children_list(priv, layout_data)) return EINA_FALSE; - _transition_layout_calculate_coords(obj, priv, layout_data); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb, - layout_data); - evas_object_smart_callback_add - (obj, SIG_CHILD_ADDED, _transition_layout_child_added, layout_data); - evas_object_smart_callback_add - (obj, SIG_CHILD_REMOVED, _transition_layout_child_removed, layout_data); - + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, + _transition_layout_obj_resize_cb, layout_data); + evas_object_smart_callback_add(obj, SIG_CHILD_ADDED, + _transition_layout_child_added, layout_data); + evas_object_smart_callback_add(obj, SIG_CHILD_REMOVED, + _transition_layout_child_removed, layout_data); if (!layout_data->animator) layout_data->animator = ecore_animator_add(transition_animation_cb, obj); - layout_data->animation_ended = EINA_FALSE; - return EINA_TRUE; } @@ -351,7 +310,6 @@ static void _transition_layout_animation_stop(Elm_Box_Transition *layout_data) { layout_data->animation_ended = EINA_TRUE; - if (layout_data->animator) { ecore_animator_del(layout_data->animator); @@ -363,21 +321,19 @@ _transition_layout_animation_stop(Elm_Box_Transition *layout_data) } static void -_transition_layout_animation_exec(Evas_Object *obj, - Evas_Object_Box_Data *priv __UNUSED__, - Elm_Box_Transition *layout_data, - const double curtime) +_transition_layout_animation_exec(Evas_Object *obj, Evas_Object_Box_Data *priv __UNUSED__, + Elm_Box_Transition *layout_data, const double curtime) { Eina_List *l; - double progress = 0.0; - Evas_Coord x, y, w, h; Transition_Animation_Data *tad; + Evas_Coord x, y, w, h; Evas_Coord cur_x, cur_y, cur_w, cur_h; + double progress = 0.0; progress = (curtime - layout_data->initial_time) / layout_data->duration; evas_object_geometry_get(obj, &x, &y, &w, &h); - EINA_LIST_FOREACH (layout_data->objs, l, tad) + EINA_LIST_FOREACH(layout_data->objs, l, tad) { cur_x = x + tad->start.x + ((tad->end.x - tad->start.x) * progress); cur_y = y + tad->start.y + ((tad->end.y - tad->start.y) * progress); @@ -388,236 +344,202 @@ _transition_layout_animation_exec(Evas_Object *obj, } } -static void -_elm_box_smart_add(Evas_Object *obj) +EAPI Evas_Object * +elm_box_add(Evas_Object *parent) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Box_Smart_Data); - - ELM_WIDGET_DATA(priv)->resize_obj = - evas_object_box_add(evas_object_evas_get(obj)); - evas_object_box_layout_set - (ELM_WIDGET_DATA(priv)->resize_obj, _elm_box_custom_layout, obj, NULL); - - evas_object_event_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_size_hints_changed, obj); + Evas_Object *obj; + Evas *e; + Widget_Data *wd; - _elm_box_parent_sc->base.add(obj); - - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, SIG_CHILD_ADDED, - _child_added_cb_proxy, obj); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, SIG_CHILD_REMOVED, - _child_removed_cb_proxy, obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "box"); + elm_widget_type_set(obj, "box"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_focus_next_hook_set(obj, _elm_box_focus_next_hook); elm_widget_can_focus_set(obj, EINA_FALSE); elm_widget_highlight_ignore_set(obj, EINA_TRUE); -} + elm_widget_theme_hook_set(obj, _theme_hook); -static void -_elm_box_smart_del(Evas_Object *obj) -{ - Eina_List *l; - Evas_Object *child; - - ELM_BOX_DATA_GET(obj, sd); - - evas_object_event_callback_del_full - (ELM_WIDGET_DATA(sd)->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_size_hints_changed, obj); - - /* let's make our box object the *last* to be processed, since it - * may (smart) parent other sub objects here */ - EINA_LIST_FOREACH (ELM_WIDGET_DATA(sd)->subobjs, l, child) - { - if (child == ELM_WIDGET_DATA(sd)->resize_obj) - { - ELM_WIDGET_DATA(sd)->subobjs = - eina_list_demote_list(ELM_WIDGET_DATA(sd)->subobjs, l); - break; - } - } - - _elm_box_parent_sc->base.del(obj); -} + wd->box = evas_object_box_add(e); + /*evas_object_box_layout_set(wd->box, evas_object_box_layout_vertical, + NULL, NULL);*/ + evas_object_box_layout_set(wd->box, _layout, obj, NULL); -static void -_elm_box_smart_set_user(Elm_Widget_Smart_Class *sc) -{ - sc->base.add = _elm_box_smart_add; - sc->base.del = _elm_box_smart_del; + evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + elm_widget_resize_object_set(obj, wd->box); - sc->sub_object_del = _elm_box_smart_sub_object_del; - sc->theme = _elm_box_smart_theme; - sc->focus_next = _elm_box_smart_focus_next; -} + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); -EAPI Evas_Object * -elm_box_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_box_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + evas_object_smart_callback_add + (wd->box, SIG_CHILD_ADDED, _cb_proxy_child_added, obj); + evas_object_smart_callback_add + (wd->box, SIG_CHILD_REMOVED, _cb_proxy_child_removed, obj); return obj; } EAPI void -elm_box_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) -{ - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - sd->horizontal = !!horizontal; - evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj); +elm_box_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->horizontal = !!horizontal; + evas_object_smart_calculate(wd->box); + /*if (wd->horizontal) + { + if (wd->homogeneous) + evas_object_box_layout_set(wd->box, + evas_object_box_layout_homogeneous_horizontal, NULL, NULL); + else + evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal, + NULL, NULL); + } + else + { + if (wd->homogeneous) + evas_object_box_layout_set(wd->box, + evas_object_box_layout_homogeneous_vertical, NULL, NULL); + else + evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal, + NULL, NULL); + } */ } EAPI Eina_Bool elm_box_horizontal_get(const Evas_Object *obj) { - ELM_BOX_CHECK(obj) EINA_FALSE; - ELM_BOX_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } EAPI void -elm_box_homogeneous_set(Evas_Object *obj, - Eina_Bool homogeneous) -{ - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - sd->homogeneous = !!homogeneous; - evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj); +elm_box_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->homogeneous = !!homogeneous; + evas_object_smart_calculate(wd->box); + /*if (wd->horizontal) + { + if (wd->homogeneous) + evas_object_box_layout_set(wd->box, + evas_object_box_layout_homogeneous_horizontal, NULL, NULL); + else + evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal, + NULL, NULL); + } + else + { + if (wd->homogeneous) + evas_object_box_layout_set(wd->box, + evas_object_box_layout_homogeneous_vertical, NULL, NULL); + else + evas_object_box_layout_set(wd->box, evas_object_box_layout_horizontal, + NULL, NULL); + } */ } EAPI Eina_Bool elm_box_homogeneous_get(const Evas_Object *obj) { - ELM_BOX_CHECK(obj) EINA_FALSE; - ELM_BOX_DATA_GET(obj, sd); - - return sd->homogeneous; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->homogeneous; } EAPI void -elm_box_pack_start(Evas_Object *obj, - Evas_Object *subobj) +elm_box_pack_start(Evas_Object *obj, Evas_Object *subobj) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_box_prepend(ELM_WIDGET_DATA(sd)->resize_obj, subobj); + evas_object_box_prepend(wd->box, subobj); } EAPI void -elm_box_pack_end(Evas_Object *obj, - Evas_Object *subobj) +elm_box_pack_end(Evas_Object *obj, Evas_Object *subobj) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_box_append(ELM_WIDGET_DATA(sd)->resize_obj, subobj); + evas_object_box_append(wd->box, subobj); } EAPI void -elm_box_pack_before(Evas_Object *obj, - Evas_Object *subobj, - Evas_Object *before) +elm_box_pack_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_box_insert_before - (ELM_WIDGET_DATA(sd)->resize_obj, subobj, before); + evas_object_box_insert_before(wd->box, subobj, before); } EAPI void -elm_box_pack_after(Evas_Object *obj, - Evas_Object *subobj, - Evas_Object *after) +elm_box_pack_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_box_insert_after(ELM_WIDGET_DATA(sd)->resize_obj, subobj, after); + evas_object_box_insert_after(wd->box, subobj, after); } EAPI void elm_box_clear(Evas_Object *obj) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - /* EINA_TRUE means to delete objects as well */ - evas_object_box_remove_all(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_box_remove_all(wd->box, EINA_TRUE); } EAPI void elm_box_unpack(Evas_Object *obj, Evas_Object *subobj) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - elm_widget_sub_object_del(obj, subobj); - evas_object_box_remove(ELM_WIDGET_DATA(sd)->resize_obj, subobj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_box_remove(wd->box, subobj); } EAPI void elm_box_unpack_all(Evas_Object *obj) { - Evas_Object_Box_Data *bd; - Evas_Object_Box_Option *opt; - Eina_List *l; - - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - bd = evas_object_smart_data_get(ELM_WIDGET_DATA(sd)->resize_obj); - EINA_LIST_FOREACH (bd->children, l, opt) - elm_widget_sub_object_del(obj, opt->obj); - - /* EINA_FALSE means to delete objects as well */ - evas_object_box_remove_all(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_box_remove_all(wd->box, EINA_FALSE); } EAPI void -elm_box_layout_set(Evas_Object *obj, - Evas_Object_Box_Layout cb, - const void *data, - Ecore_Cb free_data) +elm_box_layout_set(Evas_Object *obj, Evas_Object_Box_Layout cb, const void *data, Ecore_Cb free_data) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (cb) - evas_object_box_layout_set - (ELM_WIDGET_DATA(sd)->resize_obj, cb, data, free_data); + evas_object_box_layout_set(wd->box, cb, data, free_data); else - evas_object_box_layout_set - (ELM_WIDGET_DATA(sd)->resize_obj, _elm_box_custom_layout, obj, NULL); + evas_object_box_layout_set(wd->box, _layout, obj, NULL); } EAPI void -elm_box_layout_transition(Evas_Object *obj, - Evas_Object_Box_Data *priv, - void *data) +elm_box_layout_transition(Evas_Object *obj, Evas_Object_Box_Data *priv, void *data) { Elm_Box_Transition *box_data = data; const double curtime = ecore_loop_time_get(); @@ -651,11 +573,9 @@ elm_box_layout_transition(Evas_Object *obj, EAPI Elm_Box_Transition * elm_box_transition_new(const double duration, - Evas_Object_Box_Layout start_layout, - void *start_layout_data, + Evas_Object_Box_Layout start_layout, void *start_layout_data, Ecore_Cb start_layout_free_data, - Evas_Object_Box_Layout end_layout, - void *end_layout_data, + Evas_Object_Box_Layout end_layout, void *end_layout_data, Ecore_Cb end_layout_free_data, Ecore_Cb transition_end_cb, void *transition_end_data) @@ -666,7 +586,8 @@ elm_box_transition_new(const double duration, EINA_SAFETY_ON_NULL_RETURN_VAL(end_layout, NULL); box_data = calloc(1, sizeof(Elm_Box_Transition)); - if (!box_data) return NULL; + if (!box_data) + return NULL; box_data->start.layout = start_layout; box_data->start.data = start_layout_data; @@ -677,7 +598,6 @@ elm_box_transition_new(const double duration, box_data->duration = duration; box_data->transition_end_cb = transition_end_cb; box_data->transition_end_data = transition_end_data; - return box_data; } @@ -692,92 +612,72 @@ elm_box_transition_free(void *data) box_data->start.free_data(box_data->start.data); if ((box_data->end.free_data) && (box_data->end.data)) box_data->end.free_data(box_data->end.data); - EINA_LIST_FREE (box_data->objs, tad) - free(tad); - - evas_object_event_callback_del - (box_data->box, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb); - evas_object_smart_callback_del - (box_data->box, SIG_CHILD_ADDED, _transition_layout_child_added); - evas_object_smart_callback_del - (box_data->box, SIG_CHILD_REMOVED, _transition_layout_child_removed); + EINA_LIST_FREE(box_data->objs, tad) + free(tad); + evas_object_event_callback_del(box_data->box, EVAS_CALLBACK_RESIZE, _transition_layout_obj_resize_cb); + evas_object_smart_callback_del(box_data->box, SIG_CHILD_ADDED, _transition_layout_child_added); + evas_object_smart_callback_del(box_data->box, SIG_CHILD_REMOVED, _transition_layout_child_removed); if (box_data->animator) { ecore_animator_del(box_data->animator); box_data->animator = NULL; } - free(data); } EAPI Eina_List * elm_box_children_get(const Evas_Object *obj) { - ELM_BOX_CHECK(obj) NULL; - ELM_BOX_DATA_GET(obj, sd); - - return evas_object_box_children_get(ELM_WIDGET_DATA(sd)->resize_obj); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return evas_object_box_children_get(wd->box); } EAPI void -elm_box_padding_set(Evas_Object *obj, - Evas_Coord horizontal, - Evas_Coord vertical) +elm_box_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - evas_object_box_padding_set - (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_box_padding_set(wd->box, horizontal, vertical); } EAPI void -elm_box_padding_get(const Evas_Object *obj, - Evas_Coord *horizontal, - Evas_Coord *vertical) +elm_box_padding_get(const Evas_Object *obj, Evas_Coord *horizontal, Evas_Coord *vertical) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - evas_object_box_padding_get - (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_box_padding_get(wd->box, horizontal, vertical); } EAPI void -elm_box_align_set(Evas_Object *obj, - double horizontal, - double vertical) +elm_box_align_set(Evas_Object *obj, double horizontal, double vertical) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - evas_object_size_hint_align_set - (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_size_hint_align_set(wd->box, horizontal, vertical); } EAPI void -elm_box_align_get(const Evas_Object *obj, - double *horizontal, - double *vertical) +elm_box_align_get(const Evas_Object *obj, double *horizontal, double *vertical) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - evas_object_size_hint_align_get - (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_size_hint_align_get(wd->box, horizontal, vertical); } EAPI void elm_box_recalculate(Evas_Object *obj) { - ELM_BOX_CHECK(obj); - ELM_BOX_DATA_GET(obj, sd); - - if (sd->recalc) return; - - evas_object_smart_need_recalculate_set - (ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); - sd->recalc++; - evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj); - sd->recalc--; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (wd->recalc)) return; + evas_object_smart_need_recalculate_set(wd->box, EINA_TRUE); + wd->recalc++; + evas_object_smart_calculate(wd->box); + wd->recalc--; } diff --git a/src/lib/elm_bubble.c b/src/lib/elm_bubble.c index 695c5b690..0f3557876 100644 --- a/src/lib/elm_bubble.c +++ b/src/lib/elm_bubble.c @@ -1,220 +1,368 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char BUBBLE_SMART_NAME[] = "elm_bubble"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Bubble_Smart_Data Elm_Bubble_Smart_Data; - -struct _Elm_Bubble_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Elm_Bubble_Pos pos; + Evas_Object *bbl; + Evas_Object *content, *icon; + const char *label, *info, *corner; + Elm_Bubble_Pos pos; }; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); + static const char SIG_CLICKED[] = "clicked"; -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +static const Evas_Smart_Cb_Description _signals[] = { - {"default", "elm.swallow.content"}, - {"icon", "elm.swallow.icon"}, - {NULL, NULL} + {SIG_CLICKED, ""}, + {NULL, NULL} }; -static const Elm_Layout_Part_Alias_Description _text_aliases[] = +static const char *corner_string[] = { - {"default", "elm.text"}, - {"info", "elm.info"}, - {NULL, NULL} + "top_left", + "top_right", + "bottom_left", + "bottom_right" }; -static const Evas_Smart_Cb_Description _smart_callbacks[] = +static void +_del_hook(Evas_Object *obj) { - {SIG_CLICKED, ""}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + if (wd->info) eina_stringshare_del(wd->info); + if (wd->corner) eina_stringshare_del(wd->corner); + free(wd); +} -static const char *corner_string[] = +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - "top_left", - "top_right", - "bottom_left", - "bottom_right" -}; - -#define ELM_BUBBLE_DATA_GET(o, sd) \ - Elm_Bubble_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_BUBBLE_DATA_GET_OR_RETURN(o, ptr) \ - ELM_BUBBLE_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_BUBBLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_BUBBLE_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_BUBBLE_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), BUBBLE_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (BUBBLE_SMART_NAME, _elm_bubble, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->bbl, rtl); +} static void -_elm_bubble_smart_sizing_eval(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->bbl, "bubble", corner_string[wd->pos], + elm_widget_style_get(obj)); + edje_object_part_text_escaped_set(wd->bbl, "elm.text", wd->label); + if (wd->label) edje_object_signal_emit(wd->bbl, "elm,state,text,visible", "elm"); + else edje_object_signal_emit(wd->bbl, "elm,state,text,hidden", "elm"); + edje_object_part_text_escaped_set(wd->bbl, "elm.info", wd->info); + if (wd->info) edje_object_signal_emit(wd->bbl, "elm,state,info,visible", "elm"); + else edje_object_signal_emit(wd->bbl, "elm,state,info,hidden", "elm"); + if (wd->content) + { + edje_object_part_swallow(wd->bbl, "elm.swallow.content", wd->content); + edje_object_message_signal_process(wd->bbl); + } + if (wd->icon) + edje_object_signal_emit(wd->bbl, "elm,state,icon,visible", "elm"); + else + edje_object_signal_emit(wd->bbl, "elm,state,icon,hidden", "elm"); + edje_object_scale_set(wd->bbl, + elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); +} - ELM_BUBBLE_DATA_GET(obj, sd); +static void +_content_set(Evas_Object *obj, Evas_Object *content) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, maxw, maxh); + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->bbl, "elm.swallow.content", content); + } + _sizing_eval(obj); } -/* overriding layout's focus_next() in order to just cycle through the - * content's tree */ -static Eina_Bool -_elm_bubble_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +static Evas_Object * +_content_unset(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Object *content; + if (!wd) return NULL; + if (!wd->content) return NULL; + content = wd->content; + elm_widget_sub_object_del(obj, content); + evas_object_event_callback_del_full(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->bbl, content); + wd->content = NULL; + return content; +} - content = elm_layout_content_get(obj, NULL); - - if (!content) return EINA_FALSE; +static void +_icon_set(Evas_Object *obj, Evas_Object* icon) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->icon == icon) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = icon; + if (icon) + { + elm_widget_sub_object_add(obj, icon); + edje_object_part_swallow(wd->bbl, "elm.swallow.icon", icon); + evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_signal_emit(wd->bbl, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->bbl); + } + _sizing_eval(obj); +} - /* attempt to follow focus cycle into sub-object */ - return elm_widget_focus_next_get(content, dir, next); +static Evas_Object * +_icon_unset(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *icon; + if (!wd) return NULL; + if (!wd->icon) return NULL; + icon = wd->icon; + elm_widget_sub_object_del(obj, icon); + evas_object_event_callback_del_full(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->bbl, icon); + wd->icon = NULL; + return icon; } static void -_on_mouse_up(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - Evas_Event_Mouse_Up *ev = event_info; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (!part || !strcmp(part, "default")) + _content_set(obj, content); + else if (!strcmp(part, "icon")) + _icon_set(obj, content); +} - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) - return; +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!part || !strcmp(part, "default")) + return wd->content; + else if (!strcmp(part, "icon")) + return wd->icon; + return NULL; +} - evas_object_smart_callback_call(data, SIG_CLICKED, NULL); +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!part || !strcmp(part, "default")) + return _content_unset(obj); + else if (!strcmp(part, "icon")) + return _icon_unset(obj); + return NULL; } static Eina_Bool -_elm_bubble_smart_text_set(Evas_Object *obj, - const char *item, - const char *label) +_elm_bubble_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - if (!_elm_bubble_parent_sc->text_set(obj, item, label)) return EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *cur; - if (item && (!strcmp(item, "info") || !strcmp(item, "elm.info"))) - { - if (label) - elm_layout_signal_emit(obj, "elm,state,info,visible", "elm"); - else - elm_layout_signal_emit(obj, "elm,state,info,hidden", "elm"); - } + if ((!wd) || (!wd->content)) + return EINA_FALSE; - elm_layout_sizing_eval(obj); + cur = wd->content; - return EINA_TRUE; + /* Try Focus cycle in subitem */ + return elm_widget_focus_next_get(cur, dir, next); } static void -_elm_bubble_smart_add(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Bubble_Smart_Data); - - ELM_WIDGET_CLASS(_elm_bubble_parent_sc)->base.add(obj); - - priv->pos = ELM_BUBBLE_POS_TOP_LEFT; //default + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + if (!wd) return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->bbl, &minw, &minh, minw, minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); +} - elm_widget_can_focus_set(obj, EINA_FALSE); +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + _sizing_eval(data); +} - evas_object_event_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_MOUSE_UP, - _on_mouse_up, obj); +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + if (sub == wd->content) wd->content = NULL; + else if (sub == wd->icon) + { + edje_object_signal_emit(wd->bbl, "elm,state,icon,hidden", "elm"); + wd->icon = NULL; + edje_object_message_signal_process(wd->bbl); + } + _sizing_eval(obj); +} - elm_layout_theme_set(obj, "bubble", "base", elm_widget_style_get(obj)); +static void +_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Evas_Event_Mouse_Up *ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) + return; + evas_object_smart_callback_call(data, SIG_CLICKED, NULL); } static void -_elm_bubble_smart_set_user(Elm_Layout_Smart_Class *sc) +_elm_bubble_label_set(Evas_Object *obj, const char *item, const char *label) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_bubble_smart_add; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (!item || !strcmp(item, "default")) + { + eina_stringshare_replace(&wd->label, label); + edje_object_part_text_escaped_set(wd->bbl, "elm.text", label); + if (label) edje_object_signal_emit(wd->bbl, "elm,state,text,visible", + "elm"); + else edje_object_signal_emit(wd->bbl, "elm,state,text,hidden", "elm"); + _sizing_eval(obj); + } + else if (!strcmp(item, "info")) + { + eina_stringshare_replace(&wd->info, label); + edje_object_part_text_escaped_set(wd->bbl, "elm.info", label); + if (label) edje_object_signal_emit(wd->bbl, "elm,state,info,visible", + "elm"); + else edje_object_signal_emit(wd->bbl, "elm,state,info,hidden", "elm"); + _sizing_eval(obj); + } +} - ELM_WIDGET_CLASS(sc)->focus_next = _elm_bubble_smart_focus_next; +static const char* +_elm_bubble_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - sc->text_set = _elm_bubble_smart_text_set; - sc->sizing_eval = _elm_bubble_smart_sizing_eval; + if (!item || !strcmp(item, "default")) + { + return wd->label; + } + else if (!strcmp(item, "info")) + { + return wd->info; + } - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; + return NULL; } EAPI Evas_Object * elm_bubble_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_bubble_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_sizing_eval(obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "bubble"); + elm_widget_type_set(obj, "bubble"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_focus_next_hook_set(obj, _elm_bubble_focus_next_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_text_set_hook_set(obj, _elm_bubble_label_set); + elm_widget_text_get_hook_set(obj, _elm_bubble_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->corner = eina_stringshare_add("base"); + wd->pos = ELM_BUBBLE_POS_TOP_LEFT; //default + + wd->bbl = edje_object_add(e); + elm_widget_resize_object_set(obj, wd->bbl); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_event_callback_add(wd->bbl, EVAS_CALLBACK_MOUSE_UP, + _mouse_up, obj); + + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->bbl, "bubble", wd->corner, + elm_widget_style_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_bubble_pos_set(Evas_Object *obj, - Elm_Bubble_Pos pos) +elm_bubble_pos_set(Evas_Object *obj, Elm_Bubble_Pos pos) { - ELM_BUBBLE_CHECK(obj); - ELM_BUBBLE_DATA_GET_OR_RETURN(obj, sd); - - if (pos < ELM_BUBBLE_POS_TOP_LEFT || pos > ELM_BUBBLE_POS_BOTTOM_RIGHT) - return; - - sd->pos = pos; - - eina_stringshare_replace - (&(ELM_LAYOUT_DATA(sd)->group), corner_string[sd->pos]); - - ELM_WIDGET_DATA(sd)->api->theme(obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (pos<ELM_BUBBLE_POS_TOP_LEFT || pos>ELM_BUBBLE_POS_BOTTOM_RIGHT) return; + wd->pos = pos; + _theme_hook(obj); } EAPI Elm_Bubble_Pos elm_bubble_pos_get(const Evas_Object *obj) { - ELM_BUBBLE_CHECK(obj) ELM_BUBBLE_POS_INVALID; - ELM_BUBBLE_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_BUBBLE_POS_INVALID); - - return sd->pos; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_BUBBLE_POS_INVALID; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_BUBBLE_POS_INVALID; + return wd->pos; } diff --git a/src/lib/elm_bubble.h b/src/lib/elm_bubble.h index 8c21d9c49..9f97ec1a4 100644 --- a/src/lib/elm_bubble.h +++ b/src/lib/elm_bubble.h @@ -29,12 +29,8 @@ * @li "bottom_left" * @li "bottom_right" * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for bubble objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @c "clicked" - This is called when a user has clicked the bubble. + * Signals that you can add callbacks for are: + * @li "clicked" - This is called when a user has clicked the bubble. * * Default content parts of the bubble that you can use for are: * @li "default" - A content of the bubble diff --git a/src/lib/elm_button.c b/src/lib/elm_button.c index 963196e6c..be2506b02 100644 --- a/src/lib/elm_button.c +++ b/src/lib/elm_button.c @@ -1,138 +1,301 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_button.h" -static const char BUTTON_SMART_NAME[] = "elm_button"; +typedef struct _Widget_Data Widget_Data; + +struct _Widget_Data +{ + Evas_Object *btn, *icon; + const char *label; + double ar_threshold; + double ar_interval; + Ecore_Timer *timer; + Eina_Bool autorepeat : 1; + Eina_Bool repeating : 1; + Eina_Bool delete_me : 1; +}; + +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _del_pre_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _activate(Evas_Object *obj); +static void _activate_hook(Evas_Object *obj); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); static const char SIG_CLICKED[] = "clicked"; static const char SIG_REPEATED[] = "repeated"; static const char SIG_PRESSED[] = "pressed"; static const char SIG_UNPRESSED[] = "unpressed"; - -#define ELM_BUTTON_DATA_GET(o, sd) \ - Elm_Button_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_BUTTON_DATA_GET_OR_RETURN(o, ptr) \ - ELM_BUTTON_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_BUTTON_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_BUTTON_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_BUTTON_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), BUTTON_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"icon", "elm.swallow.icon"}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CLICKED, ""}, + {SIG_REPEATED, ""}, + {SIG_PRESSED, ""}, + {SIG_UNPRESSED, ""}, + {NULL, NULL} }; -static const Elm_Layout_Part_Alias_Description _text_aliases[] = +static Eina_Bool +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - {"default", "elm.text"}, - {NULL, NULL} -}; - -/* no *direct* instantiation of this class, so far */ -__UNUSED__ static Evas_Smart *_elm_button_smart_class_new(void); - -/* smart callbacks coming from elm button objects (besides the ones - * coming from elm layout): */ -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CLICKED, ""}, - {SIG_REPEATED, ""}, - {SIG_PRESSED, ""}, - {SIG_UNPRESSED, ""}, - {NULL, NULL} -}; + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (elm_widget_disabled_get(obj)) return EINA_FALSE; + if ((strcmp(ev->keyname, "Return")) && + (strcmp(ev->keyname, "KP_Enter")) && + (strcmp(ev->keyname, "space"))) + return EINA_FALSE; + _activate(obj); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + edje_object_signal_emit(wd->btn, "elm,anim,activate", "elm"); + return EINA_TRUE; +} -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (BUTTON_SMART_NAME, _elm_button, Elm_Button_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->delete_me = EINA_TRUE; +} static void -_activate(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + free(wd); +} - if (sd->timer) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + edje_object_signal_emit(wd->btn, "elm,action,focus", "elm"); + evas_object_focus_set(wd->btn, EINA_TRUE); } + else + { + edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->btn, EINA_FALSE); + } +} - sd->repeating = EINA_FALSE; +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->btn, rtl); +} - if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) || - (_elm_access_2nd_click_timeout(obj))) +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + const char *str; + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_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) + edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm"); + else + edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm"); + if (wd->icon) + edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm"); + else + edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm"); + edje_object_part_text_escaped_set(wd->btn, "elm.text", wd->label); + if (elm_object_disabled_get(obj)) + edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm"); + edje_object_message_signal_process(wd->btn); + edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale); + str = edje_object_data_get(wd->btn, "focus_highlight"); + if ((str) && (!strcmp(str, "on"))) + elm_widget_highlight_in_theme_set(obj, EINA_TRUE); + else + elm_widget_highlight_in_theme_set(obj, EINA_FALSE); + _sizing_eval(obj); +} + +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm"); + else + edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm"); +} + +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_emit(wd->btn, emission, source); +} + +static void +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_add(wd->btn, emission, source, func_cb, data); +} + +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_callback_del_full(wd->btn, emission, source, func_cb, + data); +} + +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (part && strcmp(part, "icon")) return; + if (wd->icon == content) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = content; + if (content) { - if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) - _elm_access_say(E_("Clicked")); - if (!elm_widget_disabled_get(obj) && - !evas_object_freeze_events_get(obj)) - evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->btn, "elm.swallow.content", content); + edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->btn); } + _sizing_eval(obj); +} + +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->icon; +} + +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->icon) return NULL; + Evas_Object *icon = wd->icon; + elm_widget_sub_object_del(obj, wd->icon); + edje_object_part_unswallow(wd->btn, icon); + return icon; } static void -_elm_button_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; - ELM_BUTTON_DATA_GET(obj, sd); - + if (!wd) return; + if (wd->delete_me) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh); elm_coords_finger_size_adjust(1, &minw, 1, &minh); evas_object_size_hint_min_set(obj, minw, minh); } -static Eina_Bool -_elm_button_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Event_Key_Down *ev = event_info; - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (obj != wd->icon) return; + _sizing_eval(data); +} - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->icon) + { + edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm"); + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->icon = NULL; + edje_object_message_signal_process(wd->btn); + _sizing_eval(obj); + } +} - if ((strcmp(ev->keyname, "Return")) && - (strcmp(ev->keyname, "KP_Enter")) && - (strcmp(ev->keyname, "space"))) - return EINA_FALSE; +static void +_activate(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->timer) + { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + wd->repeating = EINA_FALSE; + if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) || + (_elm_access_2nd_click_timeout(obj))) + { + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + _elm_access_say(E_("Clicked")); + if (!elm_widget_disabled_get(obj) && + !evas_object_freeze_events_get(obj)) + evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); + } +} +static void +_activate_hook(Evas_Object *obj) +{ _activate(obj); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - elm_layout_signal_emit(obj, "elm,anim,activate", "elm"); - - return EINA_TRUE; } static void -_on_clicked_signal(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { _activate(data); } @@ -140,12 +303,13 @@ _on_clicked_signal(void *data, static Eina_Bool _autorepeat_send(void *data) { - ELM_BUTTON_DATA_GET_OR_RETURN_VAL(data, sd, ECORE_CALLBACK_CANCEL); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; evas_object_smart_callback_call(data, SIG_REPEATED, NULL); - if (!sd->repeating) + if (!wd->repeating) { - sd->timer = NULL; + wd->timer = NULL; return ECORE_CALLBACK_CANCEL; } @@ -155,252 +319,216 @@ _autorepeat_send(void *data) static Eina_Bool _autorepeat_initial_send(void *data) { - ELM_BUTTON_DATA_GET_OR_RETURN_VAL(data, sd, ECORE_CALLBACK_CANCEL); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; - if (sd->timer) ecore_timer_del(sd->timer); - sd->repeating = EINA_TRUE; + if (wd->timer) ecore_timer_del(wd->timer); + wd->repeating = EINA_TRUE; _autorepeat_send(data); - sd->timer = ecore_timer_add(sd->ar_interval, _autorepeat_send, data); + wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data); return ECORE_CALLBACK_CANCEL; } static void -_on_pressed_signal(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_BUTTON_DATA_GET_OR_RETURN(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - if ((sd->autorepeat) && (!sd->repeating)) + if ((wd->autorepeat) && (!wd->repeating)) { - if (sd->ar_threshold <= 0.0) - _autorepeat_initial_send(data); /* call immediately */ + if (wd->ar_threshold <= 0.0) + _autorepeat_initial_send(data); /* call immediately */ else - sd->timer = ecore_timer_add - (sd->ar_threshold, _autorepeat_initial_send, data); + wd->timer = ecore_timer_add(wd->ar_threshold, _autorepeat_initial_send, data); } evas_object_smart_callback_call(data, SIG_PRESSED, NULL); } static void -_on_unpressed_signal(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_BUTTON_DATA_GET_OR_RETURN(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - if (sd->timer) + if (wd->timer) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + ecore_timer_del(wd->timer); + wd->timer = NULL; } - sd->repeating = EINA_FALSE; + wd->repeating = EINA_FALSE; evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL); } +static void +_elm_button_label_set(Evas_Object *obj, const char *item, const char *label) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return; + if (!wd) return; + eina_stringshare_replace(&wd->label, label); + if (label) + edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm"); + else + edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(wd->btn); + edje_object_part_text_escaped_set(wd->btn, "elm.text", label); + _sizing_eval(obj); +} + +static const char * +_elm_button_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if (!wd) return NULL; + return wd->label; +} + static char * -_access_info_cb(void *data __UNUSED__, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) { const char *txt = elm_widget_access_info_get(obj); - - if (!txt) txt = elm_layout_text_get(obj, NULL); + if (!txt) txt = _elm_button_label_get(obj, NULL); if (txt) return strdup(txt); - return NULL; } static char * -_access_state_cb(void *data __UNUSED__, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +_access_state_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) { if (elm_widget_disabled_get(obj)) return strdup(E_("State: Disabled")); - return NULL; } -static void -_elm_button_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Button_Smart_Data); - - ELM_WIDGET_CLASS(_elm_button_parent_sc)->base.add(obj); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "", - _on_clicked_signal, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,press", "", - _on_pressed_signal, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,unpress", "", - _on_unpressed_signal, obj); - - _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj); - _elm_access_text_set - (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Button")); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, priv); - - elm_widget_can_focus_set(obj, EINA_TRUE); - - elm_layout_theme_set(obj, "button", "base", elm_widget_style_get(obj)); -} - -static void -_elm_button_smart_set_user(Elm_Button_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_button_smart_add; - - ELM_WIDGET_CLASS(sc)->event = _elm_button_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_button_smart_sizing_eval; - - ELM_LAYOUT_CLASS(sc)->content_aliases = _content_aliases; - ELM_LAYOUT_CLASS(sc)->text_aliases = _text_aliases; -} - -EAPI const Elm_Button_Smart_Class * -elm_button_smart_class_get(void) -{ - static Elm_Button_Smart_Class _sc = - ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION(BUTTON_SMART_NAME); - static const Elm_Button_Smart_Class *class = NULL; - - if (class) return class; - - _elm_button_smart_set(&_sc); - class = &_sc; - - return class; -} - -/* new class here just to take advantage of - * ELM_BUTTON_SMART_CLASS_INIT() macro, which sets auto-repeat capability */ -EVAS_SMART_SUBCLASS_NEW - (BUTTON_SMART_NAME, _elm_button_widget, Elm_Button_Smart_Class, - Elm_Button_Smart_Class, elm_button_smart_class_get, NULL); - -static void -_elm_button_widget_smart_set_user(Elm_Button_Smart_Class *sc __UNUSED__) -{ - /* NOP: declared because it's obligatory for Evas macro */ -} - EAPI Evas_Object * elm_button_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_button_widget_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "button"); + elm_widget_type_set(obj, "button"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_activate_hook_set(obj, _activate_hook); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_text_set_hook_set(obj, _elm_button_label_set); + elm_widget_text_get_hook_set(obj, _elm_button_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->btn = edje_object_add(e); + _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", "", + _signal_pressed, obj); + edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "", + _signal_unpressed, obj); + elm_widget_resize_object_set(obj, wd->btn); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + + _theme_hook(obj); + + // TODO: convert Elementary to subclassing of Evas_Smart_Class + // TODO: and save some bytes, making descriptions per-class and not instance! + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _elm_access_object_register(obj, wd->btn); + _elm_access_text_set(_elm_access_object_get(obj), + ELM_ACCESS_TYPE, E_("Button")); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_INFO, _access_info_cb, obj); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_STATE, _access_state_cb, obj); return obj; } EAPI void -elm_button_autorepeat_set(Evas_Object *obj, - Eina_Bool on) +elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on) { - ELM_BUTTON_CHECK(obj); - ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd); - - if (sd->timer) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->timer) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + ecore_timer_del(wd->timer); + wd->timer = NULL; } - sd->autorepeat = on; - sd->repeating = EINA_FALSE; + wd->autorepeat = on; + wd->repeating = EINA_FALSE; } -#define _AR_CAPABLE(_sd) \ - (ELM_BUTTON_CLASS(ELM_WIDGET_DATA(_sd)->api)->admits_autorepeat) - EAPI Eina_Bool elm_button_autorepeat_get(const Evas_Object *obj) { - ELM_BUTTON_CHECK(obj) EINA_FALSE; - ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return _AR_CAPABLE(sd) & sd->autorepeat; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->autorepeat; } EAPI void -elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, - double t) +elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t) { - ELM_BUTTON_CHECK(obj); - ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd); - - if (!_AR_CAPABLE(sd)) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->ar_threshold == t) return; + if (wd->timer) { - ERR("this widget does not support auto repetition of clicks."); - return; + ecore_timer_del(wd->timer); + wd->timer = NULL; } - - if (sd->ar_threshold == t) return; - if (sd->timer) - { - ecore_timer_del(sd->timer); - sd->timer = NULL; - } - sd->ar_threshold = t; + wd->ar_threshold = t; } EAPI double elm_button_autorepeat_initial_timeout_get(const Evas_Object *obj) { - ELM_BUTTON_CHECK(obj) 0.0; - ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0); - - if (!_AR_CAPABLE(sd)) return 0.0; - - return sd->ar_threshold; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->ar_threshold; } EAPI void -elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, - double t) +elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t) { - ELM_BUTTON_CHECK(obj); - ELM_BUTTON_DATA_GET_OR_RETURN(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->ar_interval == t) return; - if (!_AR_CAPABLE(sd)) - { - ERR("this widget does not support auto repetition of clicks."); - return; - } - - if (sd->ar_interval == t) return; - - sd->ar_interval = t; - if ((sd->repeating) && (sd->timer)) ecore_timer_interval_set(sd->timer, t); + wd->ar_interval = t; + if ((wd->repeating) && (wd->timer)) ecore_timer_interval_set(wd->timer, t); } EAPI double elm_button_autorepeat_gap_timeout_get(const Evas_Object *obj) { - ELM_BUTTON_CHECK(obj) 0.0; - ELM_BUTTON_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0); - - return sd->ar_interval; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->ar_interval; } diff --git a/src/lib/elm_button.h b/src/lib/elm_button.h index d8773e1cf..58938980f 100644 --- a/src/lib/elm_button.h +++ b/src/lib/elm_button.h @@ -12,11 +12,7 @@ * This is a push-button. Press it and run some function. It can contain * a simple label and icon object and it also has an autorepeat feature. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for button objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * This widget emits the following signals: * @li "clicked": the user clicked the button (press/release). * @li "repeated": the user pressed the button without releasing it. * @li "pressed": button was pressed. diff --git a/src/lib/elm_calendar.c b/src/lib/elm_calendar.c index 17c746ac7..5ac5d8b30 100644 --- a/src/lib/elm_calendar.c +++ b/src/lib/elm_calendar.c @@ -1,8 +1,13 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#ifdef HAVE_EVIL +# include <Evil.h> +#endif + #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" - -static const char CALENDAR_SMART_NAME[] = "elm_calendar"; typedef enum _Day_Color // EINA_DEPRECATED { @@ -11,42 +16,46 @@ typedef enum _Day_Color // EINA_DEPRECATED DAY_SUNDAY = 2 } Day_Color; -typedef struct _Elm_Calendar_Smart_Data Elm_Calendar_Smart_Data; +typedef struct _Widget_Data Widget_Data; -struct _Elm_Calendar_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Eina_List *marks; - double interval, first_interval; - int year_min, year_max, spin_speed; - int today_it, selected_it, first_day_it; - Elm_Calendar_Weekday first_week_day; - Ecore_Timer *spin, *update_timer; - Elm_Calendar_Format_Cb format_func; - const char *weekdays[ELM_DAY_LAST]; - struct tm current_time, selected_time, shown_time; - Day_Color day_color[42]; // EINA_DEPRECATED + Evas_Object *calendar; + Eina_List *marks; + double interval, first_interval; + int year_min, year_max, spin_speed; + int today_it, selected_it, first_day_it; + Elm_Calendar_Weekday first_week_day; + Ecore_Timer *spin, *update_timer; + Elm_Calendar_Format_Cb format_func; + const char *weekdays[ELM_DAY_LAST]; + struct tm current_time, selected_time, showed_time; + Day_Color day_color[42]; // EINA_DEPRECATED Elm_Calendar_Select_Mode select_mode; - Eina_Bool selected : 1; + Eina_Bool selected:1; }; struct _Elm_Calendar_Mark { - Evas_Object *obj; - Eina_List *node; - struct tm mark_time; - const char *mark_type; + Evas_Object *obj; + Eina_List *node; + struct tm mark_time; + const char *mark_type; Elm_Calendar_Mark_Repeat_Type repeat; }; +static const char *widtype = NULL; +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); + static const char SIG_CHANGED[] = "changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {NULL, NULL} }; + /* Should not be translated, it's used if we failed * getting from locale. */ static const char *_days_abbrev[] = @@ -57,56 +66,23 @@ static const char *_days_abbrev[] = static int _days_in_month[2][12] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; -#define ELM_CALENDAR_DATA_GET(o, sd) \ - Elm_Calendar_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_CALENDAR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_CALENDAR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_CALENDAR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_CALENDAR_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), CALENDAR_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (CALENDAR_SMART_NAME, _elm_calendar, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static Elm_Calendar_Mark * -_mark_new(Evas_Object *obj, - const char *mark_type, - struct tm *mark_time, - Elm_Calendar_Mark_Repeat_Type repeat) +_mark_new(Evas_Object *obj, const char *mark_type, struct tm *mark_time, Elm_Calendar_Mark_Repeat_Type repeat) { + Widget_Data *wd = elm_widget_data_get(obj); Elm_Calendar_Mark *mark; + if (!wd) return NULL; mark = calloc(1, sizeof(Elm_Calendar_Mark)); if (!mark) return NULL; mark->obj = obj; mark->mark_type = eina_stringshare_add(mark_type); mark->mark_time = *mark_time; mark->repeat = repeat; - return mark; } @@ -118,15 +94,13 @@ _mark_free(Elm_Calendar_Mark *mark) } static void -_elm_calendar_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; - - ELM_CALENDAR_DATA_GET(obj, sd); - - elm_coords_finger_size_adjust(8, &minw, ELM_DAY_LAST, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + if (!wd) return; + elm_coords_finger_size_adjust(8, &minw, 7, &minh); + edje_object_size_min_restricted_calc(wd->calendar, &minw, &minh, minw, minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); } @@ -139,122 +113,107 @@ _maxdays_get(struct tm *selected_time) month = selected_time->tm_mon; year = selected_time->tm_year + 1900; - return _days_in_month - [((!(year % 4)) && ((!(year % 400)) || (year % 100)))][month]; + return _days_in_month[((!(year % 4)) && + ((!(year % 400)) || + (year % 100)))] + [month]; } static inline void -_unselect(Evas_Object *obj, - int selected) +_unselect(Widget_Data *wd, int selected) { char emission[32]; - snprintf(emission, sizeof(emission), "cit_%i,unselected", selected); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } static inline void -_select(Evas_Object *obj, - int selected) +_select(Widget_Data *wd, int selected) { char emission[32]; - - ELM_CALENDAR_DATA_GET(obj, sd); - - sd->selected_it = selected; + wd->selected_it = selected; snprintf(emission, sizeof(emission), "cit_%i,selected", selected); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } static inline void -_not_today(Elm_Calendar_Smart_Data *sd) +_not_today(Widget_Data *wd) { char emission[32]; - - snprintf(emission, sizeof(emission), "cit_%i,not_today", sd->today_it); - elm_layout_signal_emit(ELM_WIDGET_DATA(sd)->obj, emission, "elm"); - sd->today_it = -1; + snprintf(emission, sizeof(emission), "cit_%i,not_today", wd->today_it); + edje_object_signal_emit(wd->calendar, emission, "elm"); + wd->today_it = -1; } static inline void -_today(Elm_Calendar_Smart_Data *sd, - int it) +_today(Widget_Data *wd, int it) { char emission[32]; - snprintf(emission, sizeof(emission), "cit_%i,today", it); - elm_layout_signal_emit(ELM_WIDGET_DATA(sd)->obj, emission, "elm"); - sd->today_it = it; + edje_object_signal_emit(wd->calendar, emission, "elm"); + wd->today_it = it; } static char * _format_month_year(struct tm *selected_time) { char buf[32]; - if (!strftime(buf, sizeof(buf), E_("%B %Y"), selected_time)) return NULL; return strdup(buf); } static inline void -_cit_mark(Evas_Object *cal, - int cit, - const char *mtype) +_cit_mark(Evas_Object *cal, int cit, const char *mtype) { char sign[64]; - snprintf(sign, sizeof(sign), "cit_%i,%s", cit, mtype); - elm_layout_signal_emit(cal, sign, "elm"); + edje_object_signal_emit(cal, sign, "elm"); } static inline int -_weekday_get(int first_week_day, - int day) +_weekday_get(int first_week_day, int day) { return (day + first_week_day - 1) % ELM_DAY_LAST; } // EINA_DEPRECATED static void -_text_day_color_update(Elm_Calendar_Smart_Data *sd, - int pos) +_text_day_color_update(Widget_Data *wd, int pos) { char emission[32]; - switch (sd->day_color[pos]) + switch (wd->day_color[pos]) { case DAY_WEEKDAY: - snprintf(emission, sizeof(emission), "cit_%i,weekday", pos); - break; - + snprintf(emission, sizeof(emission), "cit_%i,weekday", pos); + break; case DAY_SATURDAY: - snprintf(emission, sizeof(emission), "cit_%i,saturday", pos); - break; - + snprintf(emission, sizeof(emission), "cit_%i,saturday", pos); + break; case DAY_SUNDAY: - snprintf(emission, sizeof(emission), "cit_%i,sunday", pos); - break; - + snprintf(emission, sizeof(emission), "cit_%i,sunday", pos); + break; default: - return; + return; } - elm_layout_signal_emit(ELM_WIDGET_DATA(sd)->obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } static void -_set_month_year(Elm_Calendar_Smart_Data *sd) +_set_month_year(Widget_Data *wd) { char *buf; /* Set selected month */ - buf = sd->format_func(&sd->shown_time); + buf = wd->format_func(&wd->showed_time); if (buf) { - elm_layout_text_set(ELM_WIDGET_DATA(sd)->obj, "month_text", buf); + edje_object_part_text_escaped_set(wd->calendar, "month_text", buf); free(buf); } - else elm_layout_text_set(ELM_WIDGET_DATA(sd)->obj, "month_text", ""); + else + edje_object_part_text_escaped_set(wd->calendar, "month_text", ""); } static void @@ -266,30 +225,31 @@ _populate(Evas_Object *obj) struct tm first_day; Eina_List *l; Eina_Bool last_row = EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(obj); - ELM_CALENDAR_DATA_GET(obj, sd); + if (!wd) return; - if (sd->today_it > 0) _not_today(sd); + if (wd->today_it > 0) _not_today(wd); - maxdays = _maxdays_get(&sd->shown_time); - mon = sd->shown_time.tm_mon; - yr = sd->shown_time.tm_year; + maxdays = _maxdays_get(&wd->showed_time); + mon = wd->showed_time.tm_mon; + yr = wd->showed_time.tm_year; - _set_month_year(sd); + _set_month_year(wd); /* Set days */ day = 0; - first_day = sd->shown_time; + first_day = wd->showed_time; first_day.tm_mday = 1; mktime(&first_day); // Layout of the calendar is changed for removing the unfilled last row. - if (first_day.tm_wday < (int)sd->first_week_day) - sd->first_day_it = first_day.tm_wday + ELM_DAY_LAST - sd->first_week_day; + if (first_day.tm_wday < (int)wd->first_week_day) + wd->first_day_it = first_day.tm_wday + ELM_DAY_LAST - wd->first_week_day; else - sd->first_day_it = first_day.tm_wday - sd->first_week_day; + wd->first_day_it = first_day.tm_wday - wd->first_week_day; - if ((35 - sd->first_day_it) > (maxdays - 1)) last_row = EINA_FALSE; + if ((35 - wd->first_day_it) > (maxdays - 1)) last_row = EINA_FALSE; if (!last_row) { @@ -298,19 +258,19 @@ _populate(Evas_Object *obj) for (i = 0; i < 5; i++) { snprintf(emission, sizeof(emission), "cseph_%i,row_hide", i); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } snprintf(emission, sizeof(emission), "cseph_%i,row_invisible", 5); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); for (i = 0; i < 35; i++) { snprintf(emission, sizeof(emission), "cit_%i,cell_expanded", i); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } for (i = 35; i < 42; i++) { snprintf(emission, sizeof(emission), "cit_%i,cell_invisible", i); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } } else @@ -320,42 +280,41 @@ _populate(Evas_Object *obj) for (i = 0; i < 6; i++) { snprintf(emission, sizeof(emission), "cseph_%i,row_show", i); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } for (i = 0; i < 42; i++) { snprintf(emission, sizeof(emission), "cit_%i,cell_default", i); - elm_layout_signal_emit(obj, emission, "elm"); + edje_object_signal_emit(wd->calendar, emission, "elm"); } } for (i = 0; i < 42; i++) { - _text_day_color_update(sd, i); // EINA_DEPRECATED - if ((!day) && (i == sd->first_day_it)) day = 1; + _text_day_color_update(wd, i); // EINA_DEPRECATED + if ((!day) && (i == wd->first_day_it)) day = 1; - if ((day == sd->current_time.tm_mday) - && (mon == sd->current_time.tm_mon) - && (yr == sd->current_time.tm_year)) - _today(sd, i); + if ((day == wd->current_time.tm_mday) + && (mon == wd->current_time.tm_mon) + && (yr == wd->current_time.tm_year)) + _today(wd, i); - if (day == sd->selected_time.tm_mday) + if (day == wd->selected_time.tm_mday) { - if ((sd->selected_it > -1) && (sd->selected_it != i)) - _unselect(obj, sd->selected_it); - - if (sd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) + if ((wd->selected_it > -1) && (wd->selected_it != i)) + _unselect(wd, wd->selected_it); + if (wd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) { - if ((mon == sd->selected_time.tm_mon) - && (yr == sd->selected_time.tm_year) - && (sd->selected)) + if ((mon == wd->selected_time.tm_mon) + && (yr == wd->selected_time.tm_year) + && (wd->selected)) { - _select(obj, i); + _select(wd, i); } } - else if (sd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE) + else if (wd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE) { - _select(obj, i); + _select(wd, i); } } @@ -365,66 +324,61 @@ _populate(Evas_Object *obj) day_s[0] = 0; snprintf(part, sizeof(part), "cit_%i.text", i); - elm_layout_text_set(obj, part, day_s); - + edje_object_part_text_set(wd->calendar, part, day_s); /* Clear previous marks */ - _cit_mark(obj, i, "clear"); + _cit_mark(wd->calendar, i, "clear"); } /* Set marks */ - EINA_LIST_FOREACH (sd->marks, l, mark) + EINA_LIST_FOREACH(wd->marks, l, mark) { struct tm *mtime = &mark->mark_time; - int month = sd->shown_time.tm_mon; - int year = sd->shown_time.tm_year; - int mday_it = mtime->tm_mday + sd->first_day_it - 1; + int month = wd->showed_time.tm_mon; + int year = wd->showed_time.tm_year; + int mday_it = mtime->tm_mday + wd->first_day_it - 1; switch (mark->repeat) { case ELM_CALENDAR_UNIQUE: - if ((mtime->tm_mon == month) && (mtime->tm_year == year)) - _cit_mark(obj, mday_it, mark->mark_type); - break; - + if ((mtime->tm_mon == month) && (mtime->tm_year == year)) + _cit_mark(wd->calendar, mday_it, mark->mark_type); + break; case ELM_CALENDAR_DAILY: - if (((mtime->tm_year == year) && (mtime->tm_mon < month)) || - (mtime->tm_year < year)) - day = 1; - else if ((mtime->tm_year == year) && (mtime->tm_mon == month)) - day = mtime->tm_mday; - else - break; - for (; day <= maxdays; day++) - _cit_mark(obj, day + sd->first_day_it - 1, - mark->mark_type); - break; - + if (((mtime->tm_year == year) && (mtime->tm_mon < month)) || + (mtime->tm_year < year)) + day = 1; + else if ((mtime->tm_year == year) && (mtime->tm_mon == month)) + day = mtime->tm_mday; + else + break; + for (; day <= maxdays; day++) + _cit_mark(wd->calendar, day + wd->first_day_it - 1, + mark->mark_type); + break; case ELM_CALENDAR_WEEKLY: - if (((mtime->tm_year == year) && (mtime->tm_mon < month)) || - (mtime->tm_year < year)) - day = 1; - else if ((mtime->tm_year == year) && (mtime->tm_mon == month)) - day = mtime->tm_mday; - else - break; - for (; day <= maxdays; day++) - if (mtime->tm_wday == _weekday_get(sd->first_day_it, day)) - _cit_mark(obj, day + sd->first_day_it - 1, - mark->mark_type); - break; - + if (((mtime->tm_year == year) && (mtime->tm_mon < month)) || + (mtime->tm_year < year)) + day = 1; + else if ((mtime->tm_year == year) && (mtime->tm_mon == month)) + day = mtime->tm_mday; + else + break; + for (; day <= maxdays; day++) + if (mtime->tm_wday == _weekday_get(wd->first_day_it, day)) + _cit_mark(wd->calendar, day + wd->first_day_it - 1, + mark->mark_type); + break; case ELM_CALENDAR_MONTHLY: - if (((mtime->tm_year < year) || - ((mtime->tm_year == year) && (mtime->tm_mon <= month))) && - (mtime->tm_mday <= maxdays)) - _cit_mark(obj, mday_it, mark->mark_type); - break; - + if (((mtime->tm_year < year) || + ((mtime->tm_year == year) && (mtime->tm_mon <= month))) && + (mtime->tm_mday <= maxdays)) + _cit_mark(wd->calendar, mday_it, mark->mark_type); + break; case ELM_CALENDAR_ANNUALLY: - if ((mtime->tm_year <= year) && (mtime->tm_mon == month) && - (mtime->tm_mday <= maxdays)) - _cit_mark(obj, mday_it, mark->mark_type); - break; + if ((mtime->tm_year <= year) && (mtime->tm_mon == month) && + (mtime->tm_mday <= maxdays)) + _cit_mark(wd->calendar, mday_it, mark->mark_type); + break; } } } @@ -434,90 +388,167 @@ _set_headers(Evas_Object *obj) { static char part[] = "ch_0.text"; int i; - ELM_CALENDAR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; for (i = 0; i < ELM_DAY_LAST; i++) { part[3] = i + '0'; - elm_layout_text_set - (obj, part, sd->weekdays[(i + sd->first_week_day) % ELM_DAY_LAST]); + edje_object_part_text_escaped_set + (wd->calendar, part, + wd->weekdays[(i + wd->first_week_day) % ELM_DAY_LAST]); } } -static Eina_Bool -_elm_calendar_smart_theme(Evas_Object *obj) +static void +_del_hook(Evas_Object *obj) { - ELM_CALENDAR_DATA_GET(obj, sd); + int i; + Elm_Calendar_Mark *mark; + Widget_Data *wd = elm_widget_data_get(obj); - if (!ELM_WIDGET_CLASS(_elm_calendar_parent_sc)->theme(obj)) - return EINA_FALSE; + if (!wd) return; + + if (wd->spin) ecore_timer_del(wd->spin); + if (wd->update_timer) ecore_timer_del(wd->update_timer); + + if (wd->marks) + { + EINA_LIST_FREE(wd->marks, mark) + { + _mark_free(mark); + } + } + + for (i = 0; i < ELM_DAY_LAST; i++) + eina_stringshare_del(wd->weekdays[i]); + free(wd); +} + +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->calendar, "elm,action,focus", "elm"); + evas_object_focus_set(wd->calendar, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->calendar, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->calendar, EINA_FALSE); + } +} + +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->calendar, rtl); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _elm_theme_object_set(obj, wd->calendar, "calendar", "base", + elm_widget_style_get(obj)); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); _set_headers(obj); _populate(obj); + edje_object_message_signal_process(wd->calendar); + edje_object_scale_set(wd->calendar, + elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); +} - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_emit(wd->calendar, emission, source); +} - elm_layout_sizing_eval(obj); +static void +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_add(wd->calendar, emission, + source, func_cb, data); +} - return EINA_TRUE; +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_del_full(wd->calendar, emission, source, func_cb, + data); } /* Set correct tm_wday and tm_yday after other fields changes*/ static inline void -_fix_selected_time(Elm_Calendar_Smart_Data *sd) +_fix_selected_time(Widget_Data *wd) { - if (sd->selected_time.tm_mon != sd->shown_time.tm_mon) - sd->selected_time.tm_mon = sd->shown_time.tm_mon; - if (sd->selected_time.tm_year != sd->shown_time.tm_year) - sd->selected_time.tm_year = sd->shown_time.tm_year; - mktime(&sd->selected_time); + if (wd->selected_time.tm_mon != wd->showed_time.tm_mon) + wd->selected_time.tm_mon = wd->showed_time.tm_mon; + if (wd->selected_time.tm_year != wd->showed_time.tm_year) + wd->selected_time.tm_year = wd->showed_time.tm_year; + mktime(&wd->selected_time); } static Eina_Bool -_update_month(Evas_Object *obj, - int delta) +_update_month(Evas_Object *obj, int delta) { struct tm time_check; int maxdays; - - ELM_CALENDAR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; /* check if it's a valid time. for 32 bits, year greater than 2037 is not */ - time_check = sd->shown_time; + time_check = wd->showed_time; time_check.tm_mon += delta; if (mktime(&time_check) == -1) return EINA_FALSE; - sd->shown_time.tm_mon += delta; - if (sd->shown_time.tm_mon < 0) + wd->showed_time.tm_mon += delta; + if (wd->showed_time.tm_mon < 0) { - if (sd->shown_time.tm_year == sd->year_min) + if (wd->showed_time.tm_year == wd->year_min) { - sd->shown_time.tm_mon++; + wd->showed_time.tm_mon++; return EINA_FALSE; } - sd->shown_time.tm_mon = 11; - sd->shown_time.tm_year--; + wd->showed_time.tm_mon = 11; + wd->showed_time.tm_year--; } - else if (sd->shown_time.tm_mon > 11) + else if (wd->showed_time.tm_mon > 11) { - if (sd->shown_time.tm_year == sd->year_max) + if (wd->showed_time.tm_year == wd->year_max) { - sd->shown_time.tm_mon--; + wd->showed_time.tm_mon--; return EINA_FALSE; } - sd->shown_time.tm_mon = 0; - sd->shown_time.tm_year++; + wd->showed_time.tm_mon = 0; + wd->showed_time.tm_year++; } - if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - && (sd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE)) + if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + && (wd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE)) { - maxdays = _maxdays_get(&sd->shown_time); - if (sd->selected_time.tm_mday > maxdays) - sd->selected_time.tm_mday = maxdays; + maxdays = _maxdays_get(&wd->showed_time); + if (wd->selected_time.tm_mday > maxdays) + wd->selected_time.tm_mday = maxdays; - _fix_selected_time(sd); + _fix_selected_time(wd); evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); } @@ -527,113 +558,91 @@ _update_month(Evas_Object *obj, static Eina_Bool _spin_value(void *data) { - ELM_CALENDAR_DATA_GET(data, sd); - - if (_update_month(data, sd->spin_speed)) _populate(data); - sd->interval = sd->interval / 1.05; - ecore_timer_interval_set(sd->spin, sd->interval); - + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; + if (_update_month(data, wd->spin_speed)) _populate(data); + wd->interval = wd->interval / 1.05; + ecore_timer_interval_set(wd->spin, wd->interval); return ECORE_CALLBACK_RENEW; } static void -_button_inc_start(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_button_inc_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_CALENDAR_DATA_GET(data, sd); - - sd->interval = sd->first_interval; - sd->spin_speed = 1; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _spin_value, data); - + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->interval = wd->first_interval; + wd->spin_speed = 1; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _spin_value, data); _spin_value(data); } static void -_button_dec_start(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_button_dec_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_CALENDAR_DATA_GET(data, sd); - - sd->interval = sd->first_interval; - sd->spin_speed = -1; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _spin_value, data); - + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->interval = wd->first_interval; + wd->spin_speed = -1; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _spin_value, data); _spin_value(data); } static void -_button_stop(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_button_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_CALENDAR_DATA_GET(data, sd); - - sd->interval = sd->first_interval; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->interval = wd->first_interval; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; } static int -_get_item_day(Evas_Object *obj, - int selected_it) +_get_item_day(Evas_Object *obj, int selected_it) { int day; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; - ELM_CALENDAR_DATA_GET(obj, sd); - - day = selected_it - sd->first_day_it + 1; - if ((day < 0) || (day > _maxdays_get(&sd->shown_time))) + day = selected_it - wd->first_day_it + 1; + if ((day < 0) || (day > _maxdays_get(&wd->showed_time))) return 0; return day; } static void -_update_sel_it(Evas_Object *obj, - int sel_it) +_update_sel_it(Evas_Object *obj, int sel_it) { int day; - - ELM_CALENDAR_DATA_GET(obj, sd); - - if (sd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE) + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (wd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE)) return; day = _get_item_day(obj, sel_it); if (!day) return; - _unselect(obj, sd->selected_it); - if (!sd->selected) - sd->selected = EINA_TRUE; + _unselect(wd, wd->selected_it); + if (!wd->selected) + wd->selected = EINA_TRUE; - sd->selected_time.tm_mday = day; - _fix_selected_time(sd); - _select(obj, sel_it); + wd->selected_time.tm_mday = day; + _fix_selected_time(wd); + _select(wd, sel_it); evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); } static void -_day_selected(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source) +_day_selected(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source) { int sel_it; - - ELM_CALENDAR_DATA_GET(data, sd); - - if (sd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE) + Widget_Data *wd = elm_widget_data_get(data); + if ((!wd) || (wd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE)) return; - sel_it = atoi(source); _update_sel_it(data, sel_it); @@ -650,36 +659,34 @@ _update_cur_date(void *data) { time_t current_time; int t, day; - ELM_CALENDAR_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_RENEW; - if (sd->today_it > 0) _not_today(sd); + if (wd->today_it > 0) _not_today(wd); current_time = time(NULL); - localtime_r(¤t_time, &sd->current_time); - t = _time_to_next_day(&sd->current_time); - ecore_timer_interval_set(sd->update_timer, t); + localtime_r(¤t_time, &wd->current_time); + t = _time_to_next_day(&wd->current_time); + ecore_timer_interval_set(wd->update_timer, t); - if ((sd->current_time.tm_mon != sd->shown_time.tm_mon) || - (sd->current_time.tm_year != sd->shown_time.tm_year)) + if ((wd->current_time.tm_mon != wd->showed_time.tm_mon) || + (wd->current_time.tm_year!= wd->showed_time.tm_year)) return ECORE_CALLBACK_RENEW; - day = sd->current_time.tm_mday + sd->first_day_it - 1; - _today(sd, day); + day = wd->current_time.tm_mday + wd->first_day_it - 1; + _today(wd, day); return ECORE_CALLBACK_RENEW; } static Eina_Bool -_elm_calendar_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + if (!wd) return EINA_FALSE; if (elm_widget_disabled_get(obj)) return EINA_FALSE; if ((!strcmp(ev->keyname, "Prior")) || @@ -692,41 +699,42 @@ _elm_calendar_smart_event(Evas_Object *obj, { if (_update_month(obj, 1)) _populate(obj); } - else if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE) - && ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - || (sd->selected))) + + else if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_NONE) + && ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + || (wd->selected))) { if ((!strcmp(ev->keyname, "Left")) || ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { - if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - || ((sd->shown_time.tm_year == sd->selected_time.tm_year) - && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it - 1); + if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + || ((wd->showed_time.tm_year == wd->selected_time.tm_year) + && (wd->showed_time.tm_mon == wd->selected_time.tm_mon))) + _update_sel_it(obj, wd->selected_it-1); } else if ((!strcmp(ev->keyname, "Right")) || ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) { - if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - || ((sd->shown_time.tm_year == sd->selected_time.tm_year) - && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it + 1); + if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + || ((wd->showed_time.tm_year == wd->selected_time.tm_year) + && (wd->showed_time.tm_mon == wd->selected_time.tm_mon))) + _update_sel_it(obj, wd->selected_it+1); } - else if ((!strcmp(ev->keyname, "Up")) || + else if ((!strcmp(ev->keyname, "Up")) || ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) { - if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - || ((sd->shown_time.tm_year == sd->selected_time.tm_year) - && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it - ELM_DAY_LAST); + if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + || ((wd->showed_time.tm_year == wd->selected_time.tm_year) + && (wd->showed_time.tm_mon == wd->selected_time.tm_mon))) + _update_sel_it(obj, wd->selected_it-ELM_DAY_LAST); } else if ((!strcmp(ev->keyname, "Down")) || ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) { - if ((sd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) - || ((sd->shown_time.tm_year == sd->selected_time.tm_year) - && (sd->shown_time.tm_mon == sd->selected_time.tm_mon))) - _update_sel_it(obj, sd->selected_it + ELM_DAY_LAST); + if ((wd->select_mode != ELM_CALENDAR_SELECT_MODE_ONDEMAND) + || ((wd->showed_time.tm_year == wd->selected_time.tm_year) + && (wd->showed_time.tm_mon == wd->selected_time.tm_mon))) + _update_sel_it(obj, wd->selected_it+ELM_DAY_LAST); } else return EINA_FALSE; } @@ -735,38 +743,54 @@ _elm_calendar_smart_event(Evas_Object *obj, return EINA_TRUE; } -static void -_elm_calendar_smart_add(Evas_Object *obj) +EAPI Evas_Object * +elm_calendar_add(Evas_Object *parent) { - time_t weekday = 259200; /* Just the first sunday since epoch */ time_t current_time; + time_t weekday = 259200; /* Just the first sunday since epoch */ + Evas_Object *obj; + Widget_Data *wd; int i, t; + Evas *e; - EVAS_SMART_DATA_ALLOC(obj, Elm_Calendar_Smart_Data); - - ELM_WIDGET_CLASS(_elm_calendar_parent_sc)->base.add(obj); - - priv->first_interval = 0.85; - priv->year_min = 2; - priv->year_max = -1; - priv->today_it = -1; - priv->selected_it = -1; - priv->first_day_it = -1; - priv->format_func = _format_month_year; - priv->marks = NULL; - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,increment,start", "*", - _button_inc_start, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,decrement,start", "*", - _button_dec_start, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,stop", "*", - _button_stop, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,selected", "*", - _day_selected, obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "calendar"); + elm_widget_type_set(obj, "calendar"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + + wd->first_interval = 0.85; + wd->year_min = 2; + wd->year_max = -1; + wd->today_it = -1; + wd->selected_it = -1; + wd->first_day_it = -1; + wd->format_func = _format_month_year; + wd->marks = NULL; + + wd->calendar = edje_object_add(e); + _elm_theme_object_set(obj, wd->calendar, "calendar", "base", "default"); + elm_widget_resize_object_set(obj, wd->calendar); + + edje_object_signal_callback_add(wd->calendar, "elm,action,increment,start", + "*", _button_inc_start, obj); + edje_object_signal_callback_add(wd->calendar, "elm,action,decrement,start", + "*", _button_dec_start, obj); + edje_object_signal_callback_add(wd->calendar, "elm,action,stop", + "*", _button_stop, obj); + edje_object_signal_callback_add(wd->calendar, "elm,action,selected", + "*", _day_selected, obj); + + evas_object_smart_callbacks_descriptions_set(obj, _signals); for (i = 0; i < ELM_DAY_LAST; i++) { @@ -776,12 +800,12 @@ _elm_calendar_smart_add(Evas_Object *obj) /* I don't know of a better way of doing it */ if (strftime(buf, sizeof(buf), "%a", gmtime(&weekday))) { - priv->weekdays[i] = eina_stringshare_add(buf); + wd->weekdays[i] = eina_stringshare_add(buf); } else { /* If we failed getting day, get a default value */ - priv->weekdays[i] = _days_abbrev[i]; + wd->weekdays[i] = _days_abbrev[i]; WRN("Failed getting weekday name for '%s' from locale.", _days_abbrev[i]); } @@ -789,165 +813,97 @@ _elm_calendar_smart_add(Evas_Object *obj) } current_time = time(NULL); - localtime_r(¤t_time, &priv->shown_time); - priv->current_time = priv->shown_time; - priv->selected_time = priv->shown_time; - t = _time_to_next_day(&priv->current_time); - priv->update_timer = ecore_timer_add(t, _update_cur_date, obj); - - elm_widget_can_focus_set(obj, EINA_TRUE); -} - -static void -_elm_calendar_smart_del(Evas_Object *obj) -{ - int i; - Elm_Calendar_Mark *mark; - ELM_CALENDAR_DATA_GET(obj, sd); - - if (sd->spin) ecore_timer_del(sd->spin); - if (sd->update_timer) ecore_timer_del(sd->update_timer); - - if (sd->marks) - { - EINA_LIST_FREE (sd->marks, mark) - { - _mark_free(mark); - } - } - - for (i = 0; i < ELM_DAY_LAST; i++) - eina_stringshare_del(sd->weekdays[i]); - - ELM_WIDGET_CLASS(_elm_calendar_parent_sc)->base.del(obj); -} - -static void -_elm_calendar_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_calendar_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_calendar_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_calendar_smart_theme; - ELM_WIDGET_CLASS(sc)->event = _elm_calendar_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_calendar_smart_sizing_eval; -} - -EAPI Evas_Object * -elm_calendar_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_calendar_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_theme_set(obj, "calendar", "base", elm_object_style_get(obj)); + localtime_r(¤t_time, &wd->showed_time); + wd->current_time = wd->showed_time; + wd->selected_time = wd->showed_time; + t = _time_to_next_day(&wd->current_time); + wd->update_timer = ecore_timer_add(t, _update_cur_date, obj); _set_headers(obj); _populate(obj); - - elm_layout_sizing_eval(obj); - + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_calendar_weekdays_names_set(Evas_Object *obj, - const char *weekdays[]) +elm_calendar_weekdays_names_set(Evas_Object *obj, const char *weekdays[]) { int i; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); EINA_SAFETY_ON_NULL_RETURN(weekdays); for (i = 0; i < ELM_DAY_LAST; i++) { - eina_stringshare_replace(&sd->weekdays[i], weekdays[i]); + eina_stringshare_replace(&wd->weekdays[i], weekdays[i]); } - _set_headers(obj); } EAPI const char ** elm_calendar_weekdays_names_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) NULL; - ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->weekdays; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->weekdays; } EAPI void -elm_calendar_interval_set(Evas_Object *obj, - double interval) +elm_calendar_interval_set(Evas_Object *obj, double interval) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - - sd->first_interval = interval; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->first_interval = interval; } EAPI double elm_calendar_interval_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) 0.0; - ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0); - - return sd->first_interval; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->first_interval; } EAPI void -elm_calendar_min_max_year_set(Evas_Object *obj, - int min, - int max) +elm_calendar_min_max_year_set(Evas_Object *obj, int min, int max) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; min -= 1900; max -= 1900; - if ((sd->year_min == min) && (sd->year_max == max)) return; - sd->year_min = min > 2 ? min : 2; - if (max > sd->year_min) - sd->year_max = max; + if ((wd->year_min == min) && (wd->year_max == max)) return; + wd->year_min = min > 2 ? min : 2; + if (max > wd->year_min) + wd->year_max = max; else - sd->year_max = sd->year_min; - if (sd->shown_time.tm_year > sd->year_max) - sd->shown_time.tm_year = sd->year_max; - if (sd->shown_time.tm_year < sd->year_min) - sd->shown_time.tm_year = sd->year_min; + wd->year_max = wd->year_min; + if (wd->showed_time.tm_year > wd->year_max) + wd->showed_time.tm_year = wd->year_max; + if (wd->showed_time.tm_year < wd->year_min) + wd->showed_time.tm_year = wd->year_min; _populate(obj); } EAPI void -elm_calendar_min_max_year_get(const Evas_Object *obj, - int *min, - int *max) +elm_calendar_min_max_year_get(const Evas_Object *obj, int *min, int *max) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - - if (min) *min = sd->year_min + 1900; - if (max) *max = sd->year_max + 1900; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (min) *min = wd->year_min + 1900; + if (max) *max = wd->year_max + 1900; } EINA_DEPRECATED EAPI void -elm_calendar_day_selection_disabled_set(Evas_Object *obj, - Eina_Bool disabled) +elm_calendar_day_selection_disabled_set(Evas_Object *obj, Eina_Bool disabled) { - ELM_CALENDAR_CHECK(obj); - if (disabled) elm_calendar_select_mode_set(obj, ELM_CALENDAR_SELECT_MODE_NONE); else @@ -957,129 +913,127 @@ elm_calendar_day_selection_disabled_set(Evas_Object *obj, EINA_DEPRECATED EAPI Eina_Bool elm_calendar_day_selection_disabled_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) EINA_FALSE; - ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return !!(sd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return !!(wd->select_mode == ELM_CALENDAR_SELECT_MODE_NONE); } EAPI void -elm_calendar_selected_time_set(Evas_Object *obj, - struct tm *selected_time) +elm_calendar_selected_time_set(Evas_Object *obj, struct tm *selected_time) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - EINA_SAFETY_ON_NULL_RETURN(selected_time); - - sd->selected_time = *selected_time; - if (!sd->selected) - sd->selected = EINA_TRUE; - if (sd->selected_time.tm_year != sd->shown_time.tm_year) - sd->shown_time.tm_year = sd->selected_time.tm_year; - if (sd->selected_time.tm_mon != sd->shown_time.tm_mon) - sd->shown_time.tm_mon = sd->selected_time.tm_mon; - - _fix_selected_time(sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + EINA_SAFETY_ON_NULL_RETURN(selected_time); + wd->selected_time = *selected_time; + if (!wd->selected) + wd->selected = EINA_TRUE; + if (wd->selected_time.tm_year != wd->showed_time.tm_year) + wd->showed_time.tm_year = wd->selected_time.tm_year; + if (wd->selected_time.tm_mon != wd->showed_time.tm_mon) + wd->showed_time.tm_mon = wd->selected_time.tm_mon; + + _fix_selected_time(wd); _populate(obj); + return; } EAPI Eina_Bool -elm_calendar_selected_time_get(const Evas_Object *obj, - struct tm *selected_time) +elm_calendar_selected_time_get(const Evas_Object *obj, struct tm *selected_time) { - ELM_CALENDAR_CHECK(obj) EINA_FALSE; - ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(selected_time, EINA_FALSE); - - if ((sd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) - && (!sd->selected)) + if ((wd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) + && (!wd->selected)) return EINA_FALSE; - *selected_time = sd->selected_time; - + *selected_time = wd->selected_time; return EINA_TRUE; } EAPI void -elm_calendar_format_function_set(Evas_Object *obj, - Elm_Calendar_Format_Cb format_function) +elm_calendar_format_function_set(Evas_Object *obj, Elm_Calendar_Format_Cb format_function) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - - sd->format_func = format_function; - _set_month_year(sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->format_func = format_function; + _set_month_year(wd); } EAPI Elm_Calendar_Mark * -elm_calendar_mark_add(Evas_Object *obj, - const char *mark_type, - struct tm *mark_time, - Elm_Calendar_Mark_Repeat_Type repeat) +elm_calendar_mark_add(Evas_Object *obj, const char *mark_type, struct tm *mark_time, Elm_Calendar_Mark_Repeat_Type repeat) { - ELM_CALENDAR_CHECK(obj) NULL; - ELM_CALENDAR_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Calendar_Mark *mark; + if (!wd) return NULL; mark = _mark_new(obj, mark_type, mark_time, repeat); - sd->marks = eina_list_append(sd->marks, mark); - mark->node = eina_list_last(sd->marks); - + wd->marks = eina_list_append(wd->marks, mark); + mark->node = eina_list_last(wd->marks); return mark; } EAPI void elm_calendar_mark_del(Elm_Calendar_Mark *mark) { + Evas_Object *obj; + Widget_Data *wd; + EINA_SAFETY_ON_NULL_RETURN(mark); - ELM_CALENDAR_CHECK(mark->obj); - ELM_CALENDAR_DATA_GET(mark->obj, sd); - sd->marks = eina_list_remove_list(sd->marks, mark->node); + obj = mark->obj; + wd = elm_widget_data_get(obj); + if (!wd) return; + + wd->marks = eina_list_remove_list(wd->marks, mark->node); _mark_free(mark); } EAPI void elm_calendar_marks_clear(Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); Elm_Calendar_Mark *mark; - EINA_LIST_FREE (sd->marks, mark) - _mark_free(mark); + if (!wd) return; + EINA_LIST_FREE(wd->marks, mark) + _mark_free(mark); } EAPI const Eina_List * elm_calendar_marks_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) NULL; - ELM_CALENDAR_DATA_GET(obj, sd); - - return sd->marks; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->marks; } EAPI void elm_calendar_marks_draw(Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; _populate(obj); } EAPI void -elm_calendar_first_day_of_week_set(Evas_Object *obj, - Elm_Calendar_Weekday day) +elm_calendar_first_day_of_week_set(Evas_Object *obj, Elm_Calendar_Weekday day) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (day >= ELM_DAY_LAST) return; - if (sd->first_week_day != day) + if (wd->first_week_day != day) { - sd->first_week_day = day; + wd->first_week_day = day; _set_headers(obj); _populate(obj); } @@ -1088,38 +1042,39 @@ elm_calendar_first_day_of_week_set(Evas_Object *obj, EAPI Elm_Calendar_Weekday elm_calendar_first_day_of_week_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) - 1; - ELM_CALENDAR_DATA_GET(obj, sd); - - return sd->first_week_day; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1; + return wd->first_week_day; } EAPI void -elm_calendar_select_mode_set(Evas_Object *obj, - Elm_Calendar_Select_Mode mode) +elm_calendar_select_mode_set(Evas_Object *obj, Elm_Calendar_Select_Mode mode) { - ELM_CALENDAR_CHECK(obj); - ELM_CALENDAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if ((mode <= ELM_CALENDAR_SELECT_MODE_ONDEMAND) - && (sd->select_mode != mode)) + && (wd->select_mode != mode)) { - sd->select_mode = mode; - if (sd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) - sd->selected = EINA_FALSE; - if ((sd->select_mode == ELM_CALENDAR_SELECT_MODE_ALWAYS) - || (sd->select_mode == ELM_CALENDAR_SELECT_MODE_DEFAULT)) - _select(obj, sd->selected_it); + wd->select_mode = mode; + if (wd->select_mode == ELM_CALENDAR_SELECT_MODE_ONDEMAND) + wd->selected = EINA_FALSE; + if ((wd->select_mode == ELM_CALENDAR_SELECT_MODE_ALWAYS) + || (wd->select_mode == ELM_CALENDAR_SELECT_MODE_DEFAULT)) + _select(wd, wd->selected_it); else - _unselect(obj, sd->selected_it); + _unselect(wd, wd->selected_it); } } EAPI Elm_Calendar_Select_Mode elm_calendar_select_mode_get(const Evas_Object *obj) { - ELM_CALENDAR_CHECK(obj) - 1; - ELM_CALENDAR_DATA_GET(obj, sd); - - return sd->select_mode; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1; + return wd->select_mode; } + + diff --git a/src/lib/elm_calendar.h b/src/lib/elm_calendar.h index 8dcde5ebe..d7c50269d 100644 --- a/src/lib/elm_calendar.h +++ b/src/lib/elm_calendar.h @@ -2,23 +2,17 @@ * @defgroup Calendar Calendar * @ingroup Elementary * - * This is a calendar widget. It helps applications to flexibly - * display a calender with day of the week, date, year and - * month. Applications are able to set specific dates to be reported - * back, when selected, in the smart callbacks of the calendar - * widget. The API of this widget lets the applications perform other - * functions, like: - * - * - placing marks on specific dates - * - setting the bounds for the calendar (minimum and maximum years) - * - setting the day names of the week (e.g. "Thu" or "Thursday") - * - setting the year and month format. - * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for calendar objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * This is a Calendar widget. Calender widget helps applications to flexibly + * display a calender with day of the week, day, year and month. Applications will be + * able to choose a specific date that will be reported in the smart_callbacks for + * the calendar widget. The APIs of calendar widget let the applications perform + * other functions like, + * placing marks on specific dates + * Setting the bounds for the calendar (minimum and maximum years) + * Setting the day names of the week. ( for ex. Thu. or Thursday) + * Setting the year and month format. + * + * Signals that you can add callbacks for are: * - @c "changed" - emitted when the date in the calendar is changed. * * Supported elm_object common APIs. diff --git a/src/lib/elm_check.c b/src/lib/elm_check.c index 417daca8e..e3f40b4fb 100644 --- a/src/lib/elm_check.c +++ b/src/lib/elm_check.c @@ -1,375 +1,518 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char CHECK_SMART_NAME[] = "elm_check"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Check_Smart_Data Elm_Check_Smart_Data; - -struct _Elm_Check_Smart_Data -{ - Elm_Layout_Smart_Data base; - - Eina_Bool state; - Eina_Bool *statep; -}; - -#define ELM_CHECK_DATA_GET(o, sd) \ - Elm_Check_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_CHECK_DATA_GET_OR_RETURN(o, ptr) \ - ELM_CHECK_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_CHECK_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_CHECK_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_CHECK_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), CHECK_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"icon", "elm.swallow.icon"}, - {NULL, NULL} -}; - -static const Elm_Layout_Part_Alias_Description _text_aliases[] = +struct _Widget_Data { - {"default", "elm.text"}, - {"on", "elm.ontext"}, - {"off", "elm.offtext"}, - {NULL, NULL} + Evas_Object *chk, *icon; + Eina_Bool state; + Eina_Bool *statep; + const char *label; + const char *ontext, *offtext; }; +static const char *widtype = NULL; +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, + void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _signal_check_off(void *data, Evas_Object *obj, + const char *emission, const char *source); +static void _signal_check_on(void *data, Evas_Object *obj, + const char *emission, const char *source); +static void _signal_check_toggle(void *data, Evas_Object *obj, + const char *emission, const char *source); +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _activate_hook(Evas_Object *obj); +static void _content_set_hook(Evas_Object *obj, const char *part, + Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part); +static void _activate(Evas_Object *obj); static const char SIG_CHANGED[] = "changed"; - -/* smart callbacks coming from elm check objects: */ -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHANGED, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHANGED, ""}, + {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (CHECK_SMART_NAME, _elm_check, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static Eina_Bool +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, + Evas_Callback_Type type, void *event_info) +{ + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (elm_widget_disabled_get(obj)) return EINA_FALSE; + if ((strcmp(ev->keyname, "Return")) && + (strcmp(ev->keyname, "KP_Enter")) && + (strcmp(ev->keyname, "space"))) + return EINA_FALSE; + _activate(obj); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; +} static void -_activate(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - ELM_CHECK_DATA_GET(obj, sd); - - if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF) && - (!_elm_access_2nd_click_timeout(obj))) - return; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + if (wd->ontext) eina_stringshare_del(wd->ontext); + if (wd->offtext) eina_stringshare_del(wd->offtext); + free(wd); +} - sd->state = !sd->state; - if (sd->statep) *sd->statep = sd->state; - if (sd->state) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) { - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); - if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) - { - if (!elm_layout_text_get(obj, "on")) - { - _elm_access_say(E_("State: On")); - } - else - _elm_access_say(E_("State: On")); - } + edje_object_signal_emit(wd->chk, "elm,action,focus", "elm"); + evas_object_focus_set(wd->chk, EINA_TRUE); } else { - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); - if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) - { - if (!elm_layout_text_get(obj, "off")) - { - _elm_access_say(E_("State: Off")); - } - else - _elm_access_say(E_("State: Off")); - } + edje_object_signal_emit(wd->chk, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->chk, EINA_FALSE); } - - evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); } -static Eina_Bool -_elm_check_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Evas_Event_Key_Down *ev = event_info; - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; - - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - - if ((strcmp(ev->keyname, "Return")) && - (strcmp(ev->keyname, "KP_Enter")) && - (strcmp(ev->keyname, "space"))) - return EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->chk, rtl); +} - _activate(obj); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_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 + edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm"); + if (wd->state) + edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm"); + else + edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm"); + if (wd->label) + edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm"); + else + edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm"); + edje_object_part_text_escaped_set(wd->chk, "elm.text", wd->label); + edje_object_part_text_escaped_set(wd->chk, "elm.ontext", wd->ontext); + edje_object_part_text_escaped_set(wd->chk, "elm.offtext", wd->offtext); + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->chk, "elm,state,disabled", "elm"); + edje_object_message_signal_process(wd->chk); + edje_object_scale_set(wd->chk, elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); +} - return EINA_TRUE; +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->chk, "elm,state,disabled", "elm"); + else + edje_object_signal_emit(wd->chk, "elm,state,enabled", "elm"); } static void -_elm_check_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; - - ELM_CHECK_DATA_GET(obj, sd); - + if (!wd) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(wd->chk, &minw, &minh, minw, minh); elm_coords_finger_size_adjust(1, &minw, 1, &minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, maxw, maxh); } -static Eina_Bool -_elm_check_smart_theme(Evas_Object *obj) +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_CHECK_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_check_parent_sc)->theme(obj)) return EINA_FALSE; - - if (!sd->state) elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); - else elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (obj != wd->icon) return; + _sizing_eval(data); +} - return EINA_TRUE; +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->icon) + { + edje_object_signal_emit(wd->chk, "elm,state,icon,hidden", "elm"); + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->icon = NULL; + _sizing_eval(obj); + edje_object_message_signal_process(wd->chk); + } } -static char * -_access_info_cb(void *data __UNUSED__, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +static void +_signal_check_off(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - const char *txt = elm_widget_access_info_get(obj); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->state = EINA_FALSE; + if (wd->statep) *wd->statep = wd->state; + edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm"); + evas_object_smart_callback_call(data, SIG_CHANGED, NULL); +} - if (!txt) txt = elm_layout_text_get(obj, NULL); - if (txt) return strdup(txt); +static void +_signal_check_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->state = EINA_TRUE; + if (wd->statep) *wd->statep = wd->state; + edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm"); + evas_object_smart_callback_call(data, SIG_CHANGED, NULL); +} - return NULL; +static void +_signal_check_toggle(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + _activate(data); } -static char * -_access_state_cb(void *data, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +static void +_activate_hook(Evas_Object *obj) { - Elm_Check_Smart_Data *sd = data; - const char *on_text, *off_text; + _activate(obj); +} - if (elm_widget_disabled_get(obj)) - return strdup(E_("State: Disabled")); - if (sd->state) - { - on_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "on"); +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (on_text) - { - char buf[1024]; + edje_object_signal_emit(wd->chk, emission, source); +} - snprintf(buf, sizeof(buf), "%s: %s", E_("State"), on_text); - return strdup(buf); - } - else - return strdup(E_("State: On")); - } +static void +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_add(wd->chk, emission, source, func_cb, data); +} - off_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "off"); +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_callback_del_full(wd->chk, emission, source, func_cb, + data); +} - if (off_text) +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + if (part && strcmp(part, "icon")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->icon == content) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = content; + if (content) { - char buf[1024]; - - snprintf(buf, sizeof(buf), "%s: %s", E_("State"), off_text); - return strdup(buf); + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->chk, "elm.swallow.content", content); + edje_object_signal_emit(wd->chk, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->chk); } - return strdup(E_("State: Off")); + _sizing_eval(obj); } -static void -_on_check_off(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) { - Evas_Object *obj = data; - - ELM_CHECK_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; - sd->state = EINA_FALSE; - if (sd->statep) *sd->statep = sd->state; - - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); - evas_object_smart_callback_call(data, SIG_CHANGED, NULL); + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->icon; } -static void -_on_check_on(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) { - Evas_Object *obj = data; - - ELM_CHECK_DATA_GET(obj, sd); - - sd->state = EINA_TRUE; - if (sd->statep) *sd->statep = sd->state; - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); - evas_object_smart_callback_call(data, SIG_CHANGED, NULL); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->icon) return NULL; + Evas_Object *icon = wd->icon; + elm_widget_sub_object_del(obj, wd->icon); + edje_object_part_unswallow(wd->chk, icon); + return icon; } static void -_on_check_toggle(void *data, - Evas_Object *o __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_activate(Evas_Object *obj) { - _activate(data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) || + (_elm_access_2nd_click_timeout(obj))) + { + wd->state = !wd->state; + if (wd->statep) *wd->statep = wd->state; + if (wd->state) + { + edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm"); + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + { + if (!wd->ontext) + { + _elm_access_say(E_("State: On")); + } + else + _elm_access_say(E_("State: On")); + } + } + else + { + edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm"); + if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) + { + if (!wd->offtext) + { + _elm_access_say(E_("State: Off")); + } + else + _elm_access_say(E_("State: Off")); + } + } + evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); + } } static void -_elm_check_smart_add(Evas_Object *obj) +_elm_check_label_set(Evas_Object *obj, const char *item, const char *label) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Check_Smart_Data); - - ELM_WIDGET_CLASS(_elm_check_parent_sc)->base.add(obj); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,on", "", - _on_check_on, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,off", "", - _on_check_off, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,toggle", "", - _on_check_toggle, obj); - - _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj); - _elm_access_text_set - (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Check")); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, priv); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, priv); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if ((!item) || (!strcmp(item, "default"))) + { + eina_stringshare_replace(&wd->label, label); + if (label) + edje_object_signal_emit(wd->chk, "elm,state,text,visible", "elm"); + else + edje_object_signal_emit(wd->chk, "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(wd->chk); + edje_object_part_text_escaped_set(wd->chk, "elm.text", label); + } + else if ((item) && (!strcmp(item, "on"))) + { + eina_stringshare_replace(&wd->ontext, label); + edje_object_part_text_escaped_set(wd->chk, "elm.ontext", wd->ontext); + } + else if ((item) && (!strcmp(item, "off"))) + { + eina_stringshare_replace(&wd->offtext, label); + edje_object_part_text_escaped_set(wd->chk, "elm.offtext", wd->offtext); + } + _sizing_eval(obj); +} - elm_widget_can_focus_set(obj, EINA_TRUE); +static const char * +_elm_check_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if ((!item) || (!strcmp(item, "default"))) + return wd->label; + else if ((item) && (!strcmp(item, "on"))) + return wd->ontext; + else if ((item) && (!strcmp(item, "off"))) + return wd->offtext; + return NULL; } -static void -_elm_check_smart_set_user(Elm_Layout_Smart_Class *sc) +static char * +_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_check_smart_add; + const char *txt = elm_widget_access_info_get(obj); + if (!txt) txt = _elm_check_label_get(obj, NULL); + if (txt) return strdup(txt); + return NULL; +} - ELM_WIDGET_CLASS(sc)->theme = _elm_check_smart_theme; - ELM_WIDGET_CLASS(sc)->event = _elm_check_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ +static char * +_access_state_cb(void *data, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) +{ + Evas_Object *o = data; + Widget_Data *wd = elm_widget_data_get(o); + if (!wd) return NULL; + if (elm_widget_disabled_get(obj)) + return strdup(E_("State: Disabled")); + if (wd->state) + { + if (wd->ontext) + { + char buf[1024]; - sc->sizing_eval = _elm_check_smart_sizing_eval; + snprintf(buf, sizeof(buf), "%s: %s", E_("State"), wd->ontext); + return strdup(buf); + } + else + return strdup(E_("State: On")); + } + if (wd->offtext) + { + char buf[1024]; - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; + snprintf(buf, sizeof(buf), "%s: %s", E_("State"), wd->offtext); + return strdup(buf); + } + return strdup(E_("State: Off")); } EAPI Evas_Object * elm_check_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_check_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj)); - elm_layout_sizing_eval(obj); - + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "check"); + elm_widget_type_set(obj, "check"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_activate_hook_set(obj, _activate_hook); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_text_set_hook_set(obj, _elm_check_label_set); + elm_widget_text_get_hook_set(obj, _elm_check_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->chk = edje_object_add(e); + _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", "", + _signal_check_off, obj); + edje_object_signal_callback_add(wd->chk, "elm,action,check,toggle", "", + _signal_check_toggle, obj); + elm_widget_resize_object_set(obj, wd->chk); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + + // TODO: convert Elementary to subclassing of Evas_Smart_Class + // TODO: and save some bytes, making descriptions per-class and not instance! + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _elm_access_object_register(obj, wd->chk); + _elm_access_text_set(_elm_access_object_get(obj), + ELM_ACCESS_TYPE, E_("Check")); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_INFO, _access_info_cb, obj); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_STATE, _access_state_cb, obj); return obj; } EAPI void -elm_check_state_set(Evas_Object *obj, - Eina_Bool state) +elm_check_state_set(Evas_Object *obj, Eina_Bool state) { - ELM_CHECK_CHECK(obj); - ELM_CHECK_DATA_GET(obj, sd); - - if (state != sd->state) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (state != wd->state) { - sd->state = state; - if (sd->statep) *sd->statep = sd->state; - if (sd->state) - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); + wd->state = state; + if (wd->statep) *wd->statep = wd->state; + if (wd->state) + edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm"); else - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); + edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm"); } - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + edje_object_message_signal_process(wd->chk); } EAPI Eina_Bool elm_check_state_get(const Evas_Object *obj) { - ELM_CHECK_CHECK(obj) EINA_FALSE; - ELM_CHECK_DATA_GET(obj, sd); - - return sd->state; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->state; } EAPI void -elm_check_state_pointer_set(Evas_Object *obj, - Eina_Bool *statep) +elm_check_state_pointer_set(Evas_Object *obj, Eina_Bool *statep) { - ELM_CHECK_CHECK(obj); - ELM_CHECK_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (statep) { - sd->statep = statep; - if (*sd->statep != sd->state) + wd->statep = statep; + if (*wd->statep != wd->state) { - sd->state = *sd->statep; - if (sd->state) - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); + wd->state = *wd->statep; + if (wd->state) + edje_object_signal_emit(wd->chk, "elm,state,check,on", "elm"); else - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); + edje_object_signal_emit(wd->chk, "elm,state,check,off", "elm"); } } else - sd->statep = NULL; + wd->statep = NULL; } diff --git a/src/lib/elm_check.h b/src/lib/elm_check.h index 15db73bef..7bdf13b7d 100644 --- a/src/lib/elm_check.h +++ b/src/lib/elm_check.h @@ -9,24 +9,20 @@ * @image html img/widget/check/preview-02.png * @image latex img/widget/check/preview-02.eps * - * @brief The check widget allows for toggling a value between true - * and false. - * - * Check objects are a lot like radio objects in layout and - * functionality, except they do not work as a group, but - * independently, and only toggle the value of a boolean between false - * and true. elm_check_state_set() sets the boolean state and - * elm_check_state_get() returns the current state. For convenience, - * like the radio objects, you can set a pointer to a boolean directly - * with elm_check_state_pointer_set() for it to modify. - * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for check objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "changed" - This is called whenever the user changes the state of - * the check objects (@c event_info is always @c NULL). + * @brief The check widget allows for toggling a value between true and + * false. + * + * Check objects are a lot like radio objects in layout and functionality + * except they do not work as a group, but independently and only toggle the + * value of a boolean from false to true (0 or 1). elm_check_state_set() sets + * the boolean state (1 for true, 0 for false), and elm_check_state_get() + * returns the current state. For convenience, like the radio objects, you + * can set a pointer to a boolean directly with elm_check_state_pointer_set() + * for it to modify. + * + * Signals that you can add callbacks for are: + * "changed" - This is called whenever the user changes the state of the check + * objects(event_info is NULL). * * Default content parts of the check widget that you can use for are: * @li "icon" - An icon of the check diff --git a/src/lib/elm_clock.c b/src/lib/elm_clock.c index a258b3925..3bd0b2d2c 100644 --- a/src/lib/elm_clock.c +++ b/src/lib/elm_clock.c @@ -1,620 +1,593 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" - -static const char CLOCK_SMART_NAME[] = "elm_clock"; #define DEFAULT_FIRST_INTERVAL 0.85 -typedef struct _Elm_Clock_Smart_Data Elm_Clock_Smart_Data; +typedef struct _Widget_Data Widget_Data; -struct _Elm_Clock_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - double interval, first_interval; - Elm_Clock_Edit_Mode digedit; - int hrs, min, sec, timediff; - Evas_Object *digit[6]; - Evas_Object *am_pm_obj; - Evas_Object *sel_obj; - Ecore_Timer *ticker, *spin; - + Evas_Object *clk; + double interval, first_interval; + Eina_Bool seconds : 1; + Eina_Bool am_pm : 1; + Eina_Bool edit : 1; + Elm_Clock_Edit_Mode digedit; + int hrs, min, sec, timediff; + Evas_Object *digit[6]; + Evas_Object *ampm; + Evas_Object *sel_obj; + Ecore_Timer *ticker, *spin; struct { - int hrs, min, sec; - char ampm; + int hrs, min, sec; + char ampm; + Eina_Bool seconds : 1; + Eina_Bool am_pm : 1; + Eina_Bool edit : 1; Elm_Clock_Edit_Mode digedit; - - Eina_Bool seconds : 1; - Eina_Bool am_pm : 1; - Eina_Bool edit : 1; } cur; - - Eina_Bool seconds : 1; - Eina_Bool am_pm : 1; - Eina_Bool edit : 1; }; -#define ELM_CLOCK_DATA_GET(o, sd) \ - Elm_Clock_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_CLOCK_DATA_GET_OR_RETURN(o, ptr) \ - ELM_CLOCK_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_CLOCK_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_CLOCK_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_CLOCK_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), CLOCK_SMART_NAME, __func__)) \ - return - +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _on_focus_hook(void *data, Evas_Object *obj); +static Eina_Bool _ticker(void *data); +static Eina_Bool _signal_clock_val_up(void *data); +static Eina_Bool _signal_clock_val_down(void *data); static void _time_update(Evas_Object *obj); static const char SIG_CHANGED[] = "changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (CLOCK_SMART_NAME, _elm_clock, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + int i; + for (i = 0; i < 6; i++) + { + if (wd->digit[i]) evas_object_del(wd->digit[i]); + } + if (wd->ampm) evas_object_del(wd->ampm); + if (wd->ticker) ecore_timer_del(wd->ticker); + if (wd->spin) ecore_timer_del(wd->spin); + free(wd); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + edje_object_signal_emit(wd->clk, "elm,action,focus", "elm"); + else + edje_object_signal_emit(wd->clk, "elm,action,unfocus", "elm"); + wd->cur.am_pm = !wd->cur.am_pm; /* hack - force update */ + _time_update(obj); +} + +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->clk, "elm,action,focus", "elm"); + evas_object_focus_set(wd->clk, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->clk, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->clk, EINA_FALSE); + } +} + +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + int i; + if (!wd) return; + edje_object_signal_emit(wd->clk, emission, source); + for (i = 0; i < 6; i++) + { + if (wd->digit[i]) + edje_object_signal_emit(wd->digit[i], emission, source); + } +} + +static void +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + int i; + if (!wd) return; + edje_object_signal_callback_add(wd->clk, emission, source, func_cb, data); + for (i = 0; i < 6; i++) + { + if (wd->digit[i]) + edje_object_signal_callback_add(wd->digit[i], emission, source, + func_cb, data); + } +} + +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + int i; + for (i = 0; i < 6; i++) + { + edje_object_signal_callback_del_full(wd->digit[i], emission, source, + func_cb, data); + } + edje_object_signal_callback_del_full(wd->clk, emission, source, func_cb, + data); +} + +static void +_timediff_set(Widget_Data *wd) +{ + struct timeval timev; + struct tm *tm; + time_t tt; + gettimeofday(&timev, NULL); + tt = (time_t)(timev.tv_sec); + tzset(); + tm = localtime(&tt); + wd->timediff = (((wd->hrs - tm->tm_hour) * 60 + + wd->min - tm->tm_min) * 60) + wd->sec - tm->tm_sec; +} static Eina_Bool -_on_clock_val_up(void *data) +_ticker(void *data) { - ELM_CLOCK_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + double t; + struct timeval timev; + struct tm *tm; + time_t tt; + if (!wd) return ECORE_CALLBACK_CANCEL; + gettimeofday(&timev, NULL); + t = ((double)(1000000 - timev.tv_usec)) / 1000000.0; + wd->ticker = ecore_timer_add(t, _ticker, data); + if (!wd->edit) + { + tt = (time_t)(timev.tv_sec) + wd->timediff; + tzset(); + tm = localtime(&tt); + if (tm) + { + wd->hrs = tm->tm_hour; + wd->min = tm->tm_min; + wd->sec = tm->tm_sec; + _time_update(data); + } + } + return ECORE_CALLBACK_CANCEL; +} - if (!sd->edit) goto clock_val_up_cancel; - if (!sd->sel_obj) goto clock_val_up_cancel; - if (sd->sel_obj == sd->digit[0]) +static Eina_Bool +_signal_clock_val_up(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) goto clock_val_up_exit_on_error; + if (!wd->edit) goto clock_val_up_cancel; + if (!wd->sel_obj) goto clock_val_up_cancel; + if (wd->sel_obj == wd->digit[0]) { - sd->hrs = sd->hrs + 10; - if (sd->hrs >= 24) sd->hrs -= 24; + wd->hrs = wd->hrs + 10; + if (wd->hrs >= 24) wd->hrs -= 24; } - if (sd->sel_obj == sd->digit[1]) + if (wd->sel_obj == wd->digit[1]) { - sd->hrs = sd->hrs + 1; - if (sd->hrs >= 24) sd->hrs -= 24; + wd->hrs = wd->hrs + 1; + if (wd->hrs >= 24) wd->hrs -= 24; } - if (sd->sel_obj == sd->digit[2]) + if (wd->sel_obj == wd->digit[2]) { - sd->min = sd->min + 10; - if (sd->min >= 60) sd->min -= 60; + wd->min = wd->min + 10; + if (wd->min >= 60) wd->min -= 60; } - if (sd->sel_obj == sd->digit[3]) + if (wd->sel_obj == wd->digit[3]) { - sd->min = sd->min + 1; - if (sd->min >= 60) sd->min -= 60; + wd->min = wd->min + 1; + if (wd->min >= 60) wd->min -= 60; } - if (sd->sel_obj == sd->digit[4]) + if (wd->sel_obj == wd->digit[4]) { - sd->sec = sd->sec + 10; - if (sd->sec >= 60) sd->sec -= 60; + wd->sec = wd->sec + 10; + if (wd->sec >= 60) wd->sec -= 60; } - if (sd->sel_obj == sd->digit[5]) + if (wd->sel_obj == wd->digit[5]) { - sd->sec = sd->sec + 1; - if (sd->sec >= 60) sd->sec -= 60; + wd->sec = wd->sec + 1; + if (wd->sec >= 60) wd->sec -= 60; } - if (sd->sel_obj == sd->am_pm_obj) + if (wd->sel_obj == wd->ampm) { - sd->hrs = sd->hrs + 12; - if (sd->hrs > 23) sd->hrs -= 24; + wd->hrs = wd->hrs + 12; + if (wd->hrs > 23) wd->hrs -= 24; } - - sd->interval = sd->interval / 1.05; - ecore_timer_interval_set(sd->spin, sd->interval); + wd->interval = wd->interval / 1.05; + ecore_timer_interval_set(wd->spin, wd->interval); _time_update(data); evas_object_smart_callback_call(data, SIG_CHANGED, NULL); return ECORE_CALLBACK_RENEW; - clock_val_up_cancel: - - sd->spin = NULL; - + wd->spin = NULL; +clock_val_up_exit_on_error: return ECORE_CALLBACK_CANCEL; } static Eina_Bool -_on_clock_val_down(void *data) +_signal_clock_val_down(void *data) { - ELM_CLOCK_DATA_GET(data, sd); - - if (!sd->edit) goto clock_val_down_cancel; - if (!sd->sel_obj) goto clock_val_down_cancel; - if (sd->sel_obj == sd->digit[0]) + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) goto clock_val_down_exit_on_error; + if (!wd->edit) goto clock_val_down_cancel; + if (!wd->sel_obj) goto clock_val_down_cancel; + if (wd->sel_obj == wd->digit[0]) { - sd->hrs = sd->hrs - 10; - if (sd->hrs < 0) sd->hrs += 24; + wd->hrs = wd->hrs - 10; + if (wd->hrs < 0) wd->hrs += 24; } - if (sd->sel_obj == sd->digit[1]) + if (wd->sel_obj == wd->digit[1]) { - sd->hrs = sd->hrs - 1; - if (sd->hrs < 0) sd->hrs += 24; + wd->hrs = wd->hrs - 1; + if (wd->hrs < 0) wd->hrs += 24; } - if (sd->sel_obj == sd->digit[2]) + if (wd->sel_obj == wd->digit[2]) { - sd->min = sd->min - 10; - if (sd->min < 0) sd->min += 60; + wd->min = wd->min - 10; + if (wd->min < 0) wd->min += 60; } - if (sd->sel_obj == sd->digit[3]) + if (wd->sel_obj == wd->digit[3]) { - sd->min = sd->min - 1; - if (sd->min < 0) sd->min += 60; + wd->min = wd->min - 1; + if (wd->min < 0) wd->min += 60; } - if (sd->sel_obj == sd->digit[4]) + if (wd->sel_obj == wd->digit[4]) { - sd->sec = sd->sec - 10; - if (sd->sec < 0) sd->sec += 60; + wd->sec = wd->sec - 10; + if (wd->sec < 0) wd->sec += 60; } - if (sd->sel_obj == sd->digit[5]) + if (wd->sel_obj == wd->digit[5]) { - sd->sec = sd->sec - 1; - if (sd->sec < 0) sd->sec += 60; + wd->sec = wd->sec - 1; + if (wd->sec < 0) wd->sec += 60; } - if (sd->sel_obj == sd->am_pm_obj) + if (wd->sel_obj == wd->ampm) { - sd->hrs = sd->hrs - 12; - if (sd->hrs < 0) sd->hrs += 24; + wd->hrs = wd->hrs - 12; + if (wd->hrs < 0) wd->hrs += 24; } - sd->interval = sd->interval / 1.05; - ecore_timer_interval_set(sd->spin, sd->interval); + wd->interval = wd->interval / 1.05; + ecore_timer_interval_set(wd->spin, wd->interval); _time_update(data); evas_object_smart_callback_call(data, SIG_CHANGED, NULL); return ECORE_CALLBACK_RENEW; - clock_val_down_cancel: - sd->spin = NULL; - + wd->spin = NULL; +clock_val_down_exit_on_error: return ECORE_CALLBACK_CANCEL; } static void -_on_clock_val_up_start(void *data, - Evas_Object *obj, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_clock_val_up_start(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_CLOCK_DATA_GET(data, sd); - - sd->interval = sd->first_interval; - sd->sel_obj = obj; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _on_clock_val_up, data); - - _on_clock_val_up(data); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->interval = wd->first_interval; + wd->sel_obj = obj; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _signal_clock_val_up, data); + _signal_clock_val_up(data); } static void -_on_clock_val_down_start(void *data, - Evas_Object *obj, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_clock_val_down_start(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_CLOCK_DATA_GET(data, sd); - - sd->interval = sd->first_interval; - sd->sel_obj = obj; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _on_clock_val_down, data); - - _on_clock_val_down(data); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->interval = wd->first_interval; + wd->sel_obj = obj; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _signal_clock_val_down, data); + _signal_clock_val_down(data); } static void -_on_clock_val_change_stop(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_clock_val_change_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - Elm_Clock_Smart_Data *sd = data; - - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; - sd->sel_obj = NULL; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; + wd->sel_obj = NULL; } static void _time_update(Evas_Object *obj) { - ELM_CLOCK_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); Edje_Message_Int msg; int ampm = 0; const char *style = elm_widget_style_get(obj); - - if ((sd->cur.seconds != sd->seconds) || (sd->cur.am_pm != sd->am_pm) || - (sd->cur.edit != sd->edit) || (sd->cur.digedit != sd->digedit)) + if (!wd) return; + if ((wd->cur.seconds != wd->seconds) || (wd->cur.am_pm != wd->am_pm) || + (wd->cur.edit != wd->edit) || (wd->cur.digedit != wd->digedit)) { int i; Evas_Coord mw, mh; for (i = 0; i < 6; i++) { - if (sd->digit[i]) + if (wd->digit[i]) { - evas_object_del(sd->digit[i]); - sd->digit[i] = NULL; + evas_object_del(wd->digit[i]); + wd->digit[i] = NULL; } } - if (sd->am_pm_obj) + if (wd->ampm) { - evas_object_del(sd->am_pm_obj); - sd->am_pm_obj = NULL; + evas_object_del(wd->ampm); + wd->ampm = NULL; } - if ((sd->seconds) && (sd->am_pm)) - elm_layout_theme_set(obj, "clock", "base-all", style); - else if (sd->seconds) - elm_layout_theme_set(obj, "clock", "base-seconds", style); - else if (sd->am_pm) - elm_layout_theme_set(obj, "clock", "base-am_pm", style); + if ((wd->seconds) && (wd->am_pm)) + _elm_theme_object_set(obj, wd->clk, "clock", "base-all", style); + else if (wd->seconds) + _elm_theme_object_set(obj, wd->clk, "clock", "base-seconds", style); + else if (wd->am_pm) + _elm_theme_object_set(obj, wd->clk, "clock", "base-am_pm", style); else - elm_layout_theme_set(obj, "clock", "base", style); - - edje_object_scale_set - (ELM_WIDGET_DATA(sd)->resize_obj, elm_widget_scale_get(obj) * - elm_config_scale_get()); + _elm_theme_object_set(obj, wd->clk, "clock", "base", style); + edje_object_scale_set(wd->clk, elm_widget_scale_get(obj) * + _elm_config->scale); for (i = 0; i < 6; i++) { char buf[16]; - if ((!sd->seconds) && (i >= 4)) break; - sd->digit[i] = edje_object_add - (evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj)); - elm_widget_theme_object_set - (obj, sd->digit[i], "clock", "flipdigit", style); - edje_object_scale_set - (sd->digit[i], elm_widget_scale_get(obj) * - elm_config_scale_get()); - - if ((sd->edit) && (sd->digedit & (1 << i))) - edje_object_signal_emit - (sd->digit[i], "elm,state,edit,on", "elm"); - edje_object_signal_callback_add - (sd->digit[i], "elm,action,up,start", "", - _on_clock_val_up_start, obj); - edje_object_signal_callback_add - (sd->digit[i], "elm,action,up,stop", "", - _on_clock_val_change_stop, sd); - edje_object_signal_callback_add - (sd->digit[i], "elm,action,down,start", "", - _on_clock_val_down_start, obj); - edje_object_signal_callback_add - (sd->digit[i], "elm,action,down,stop", "", - _on_clock_val_change_stop, sd); - + if ((!wd->seconds) && (i >= 4)) break; + wd->digit[i] = edje_object_add(evas_object_evas_get(wd->clk)); + _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))) + edje_object_signal_emit(wd->digit[i], "elm,state,edit,on", "elm"); + edje_object_signal_callback_add(wd->digit[i], "elm,action,up,start", + "", _signal_clock_val_up_start, obj); + edje_object_signal_callback_add(wd->digit[i], "elm,action,up,stop", + "", _signal_clock_val_change_stop, obj); + edje_object_signal_callback_add(wd->digit[i], "elm,action,down,start", + "", _signal_clock_val_down_start, obj); + edje_object_signal_callback_add(wd->digit[i], "elm,action,down,stop", + "", _signal_clock_val_change_stop, obj); mw = mh = -1; elm_coords_finger_size_adjust(1, &mw, 2, &mh); - edje_object_size_min_restricted_calc - (sd->digit[i], &mw, &mh, mw, mh); + edje_object_size_min_restricted_calc(wd->digit[i], &mw, &mh, mw, mh); elm_coords_finger_size_adjust(1, &mw, 2, &mh); - edje_extern_object_min_size_set(sd->digit[i], mw, mh); + edje_extern_object_min_size_set(wd->digit[i], mw, mh); snprintf(buf, sizeof(buf), "d%i", i); - elm_layout_content_set(obj, buf, sd->digit[i]); - evas_object_show(sd->digit[i]); + edje_object_part_swallow(wd->clk , buf, wd->digit[i]); + evas_object_show(wd->digit[i]); } - if (sd->am_pm) + if (wd->am_pm) { - sd->am_pm_obj = - edje_object_add(evas_object_evas_get(ELM_WIDGET_DATA(sd)->resize_obj)); - elm_widget_theme_object_set - (obj, sd->am_pm_obj, "clock", "flipampm", style); - edje_object_scale_set(sd->am_pm_obj, elm_widget_scale_get(obj) * + wd->ampm = edje_object_add(evas_object_evas_get(wd->clk)); + _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 (sd->edit) - edje_object_signal_emit - (sd->am_pm_obj, "elm,state,edit,on", "elm"); - edje_object_signal_callback_add - (sd->am_pm_obj, "elm,action,up,start", "", - _on_clock_val_up_start, obj); - edje_object_signal_callback_add - (sd->am_pm_obj, "elm,action,up,stop", "", - _on_clock_val_change_stop, sd); - edje_object_signal_callback_add - (sd->am_pm_obj, "elm,action,down,start", "", - _on_clock_val_down_start, obj); - edje_object_signal_callback_add - (sd->am_pm_obj, "elm,action,down,stop", "", - _on_clock_val_change_stop, sd); - + if (wd->edit) + edje_object_signal_emit(wd->ampm, "elm,state,edit,on", "elm"); + edje_object_signal_callback_add(wd->ampm, "elm,action,up,start", + "", _signal_clock_val_up_start, obj); + edje_object_signal_callback_add(wd->ampm, "elm,action,up,stop", + "", _signal_clock_val_change_stop, obj); + edje_object_signal_callback_add(wd->ampm, "elm,action,down,start", + "", _signal_clock_val_down_start, obj); + edje_object_signal_callback_add(wd->ampm, "elm,action,down,stop", + "", _signal_clock_val_change_stop, obj); mw = mh = -1; elm_coords_finger_size_adjust(1, &mw, 2, &mh); - edje_object_size_min_restricted_calc - (sd->am_pm_obj, &mw, &mh, mw, mh); + edje_object_size_min_restricted_calc(wd->ampm, &mw, &mh, mw, mh); elm_coords_finger_size_adjust(1, &mw, 2, &mh); - edje_extern_object_min_size_set(sd->am_pm_obj, mw, mh); - elm_layout_content_set(obj, "ampm", sd->am_pm_obj); - evas_object_show(sd->am_pm_obj); + edje_extern_object_min_size_set(wd->ampm, mw, mh); + edje_object_part_swallow(wd->clk , "ampm", wd->ampm); + evas_object_show(wd->ampm); } - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &mw, &mh); + edje_object_size_min_calc(wd->clk, &mw, &mh); evas_object_size_hint_min_set(obj, mw, mh); - sd->cur.hrs = 0; - sd->cur.min = 0; - sd->cur.sec = 0; - sd->cur.ampm = -1; - sd->cur.seconds = sd->seconds; - sd->cur.am_pm = sd->am_pm; - sd->cur.edit = sd->edit; - sd->cur.digedit = sd->digedit; + wd->cur.hrs = 0; + wd->cur.min = 0; + wd->cur.sec = 0; + wd->cur.ampm = -1; + wd->cur.seconds = wd->seconds; + wd->cur.am_pm = wd->am_pm; + wd->cur.edit = wd->edit; + wd->cur.digedit = wd->digedit; } - if (sd->hrs != sd->cur.hrs) + if (wd->hrs != wd->cur.hrs) { int hrs; int d1, d2, dc1, dc2; - hrs = sd->hrs; - if (sd->am_pm) + hrs = wd->hrs; + if (wd->am_pm) { if (hrs >= 12) { if (hrs > 12) hrs -= 12; ampm = 1; } - else if (!hrs) - hrs = 12; + else if (!hrs) hrs = 12; } d1 = hrs / 10; d2 = hrs % 10; - dc1 = sd->cur.hrs / 10; - dc2 = sd->cur.hrs % 10; + dc1 = wd->cur.hrs / 10; + dc2 = wd->cur.hrs % 10; if (d1 != dc1) { msg.val = d1; - edje_object_message_send(sd->digit[0], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[0], EDJE_MESSAGE_INT, 1, &msg); } if (d2 != dc2) { msg.val = d2; - edje_object_message_send(sd->digit[1], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[1], EDJE_MESSAGE_INT, 1, &msg); } - sd->cur.hrs = hrs; + wd->cur.hrs = hrs; } - if (sd->min != sd->cur.min) + if (wd->min != wd->cur.min) { int d1, d2, dc1, dc2; - d1 = sd->min / 10; - d2 = sd->min % 10; - dc1 = sd->cur.min / 10; - dc2 = sd->cur.min % 10; + d1 = wd->min / 10; + d2 = wd->min % 10; + dc1 = wd->cur.min / 10; + dc2 = wd->cur.min % 10; if (d1 != dc1) { msg.val = d1; - edje_object_message_send(sd->digit[2], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[2], EDJE_MESSAGE_INT, 1, &msg); } if (d2 != dc2) { msg.val = d2; - edje_object_message_send(sd->digit[3], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[3], EDJE_MESSAGE_INT, 1, &msg); } - sd->cur.min = sd->min; + wd->cur.min = wd->min; } - if (sd->seconds) + if (wd->seconds) { - if (sd->sec != sd->cur.sec) + if (wd->sec != wd->cur.sec) { int d1, d2, dc1, dc2; - d1 = sd->sec / 10; - d2 = sd->sec % 10; - dc1 = sd->cur.sec / 10; - dc2 = sd->cur.sec % 10; + d1 = wd->sec / 10; + d2 = wd->sec % 10; + dc1 = wd->cur.sec / 10; + dc2 = wd->cur.sec % 10; if (d1 != dc1) { msg.val = d1; - edje_object_message_send - (sd->digit[4], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[4], EDJE_MESSAGE_INT, 1, &msg); } if (d2 != dc2) { msg.val = d2; - edje_object_message_send - (sd->digit[5], EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->digit[5], EDJE_MESSAGE_INT, 1, &msg); } - sd->cur.sec = sd->sec; + wd->cur.sec = wd->sec; } } else - sd->cur.sec = -1; + wd->cur.sec = -1; - if (sd->am_pm) + if (wd->am_pm) { - if (sd->hrs >= 12) ampm = 1; - if (ampm != sd->cur.ampm) + if (wd->hrs >= 12) ampm = 1; + if (ampm != wd->cur.ampm) { - if (sd->cur.ampm != ampm) + if (wd->cur.ampm != ampm) { msg.val = ampm; - edje_object_message_send - (sd->am_pm_obj, EDJE_MESSAGE_INT, 1, &msg); + edje_object_message_send(wd->ampm, EDJE_MESSAGE_INT, 1, &msg); } - sd->cur.ampm = ampm; + wd->cur.ampm = ampm; } } else - sd->cur.ampm = -1; -} - -static Eina_Bool -_elm_clock_smart_theme(Evas_Object *obj) -{ - if (!ELM_WIDGET_CLASS(_elm_clock_parent_sc)->theme(obj)) return EINA_FALSE; - - _time_update(obj); - - return EINA_TRUE; -} - -static Eina_Bool -_ticker(void *data) -{ - ELM_CLOCK_DATA_GET(data, sd); - - double t; - struct timeval timev; - struct tm *tm; - time_t tt; - - gettimeofday(&timev, NULL); - t = ((double)(1000000 - timev.tv_usec)) / 1000000.0; - sd->ticker = ecore_timer_add(t, _ticker, data); - if (!sd->edit) - { - tt = (time_t)(timev.tv_sec) + sd->timediff; - tzset(); - tm = localtime(&tt); - if (tm) - { - sd->hrs = tm->tm_hour; - sd->min = tm->tm_min; - sd->sec = tm->tm_sec; - _time_update(data); - } - } - - return ECORE_CALLBACK_CANCEL; -} - -static void -_elm_clock_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Clock_Smart_Data); - - ELM_WIDGET_CLASS(_elm_clock_parent_sc)->base.add(obj); - - priv->cur.ampm = -1; - priv->cur.seconds = EINA_TRUE; - priv->cur.am_pm = EINA_TRUE; - priv->cur.edit = EINA_TRUE; - priv->cur.digedit = ELM_CLOCK_EDIT_DEFAULT; - priv->first_interval = DEFAULT_FIRST_INTERVAL; - priv->timediff = 0; - - elm_widget_can_focus_set(obj, EINA_TRUE); -} - -static void -_elm_clock_smart_del(Evas_Object *obj) -{ - ELM_CLOCK_DATA_GET(obj, sd); - - if (sd->ticker) ecore_timer_del(sd->ticker); - if (sd->spin) ecore_timer_del(sd->spin); - - /* NB: digits are killed for being sub objects, automatically */ - - ELM_WIDGET_CLASS(_elm_clock_parent_sc)->base.del(obj); -} - -static void -_elm_clock_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_clock_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_clock_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_clock_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + wd->cur.ampm = -1; } EAPI Evas_Object * elm_clock_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "clock"); + elm_widget_type_set(obj, "clock"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_clock_smart_class_new()); + wd->clk = edje_object_add(e); + elm_widget_resize_object_set(obj, wd->clk); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + wd->cur.ampm = -1; + wd->cur.seconds = EINA_TRUE; + wd->cur.am_pm = EINA_TRUE; + wd->cur.edit = EINA_TRUE; + wd->cur.digedit = ELM_CLOCK_EDIT_DEFAULT; + wd->first_interval = DEFAULT_FIRST_INTERVAL; + wd->timediff = 0; _time_update(obj); _ticker(obj); - return obj; -} + evas_object_smart_callbacks_descriptions_set(obj, _signals); -static void -_timediff_set(Elm_Clock_Smart_Data *sd) -{ - struct timeval timev; - struct tm *tm; - time_t tt; - - gettimeofday(&timev, NULL); - tt = (time_t)(timev.tv_sec); - tzset(); - tm = localtime(&tt); - sd->timediff = (((sd->hrs - tm->tm_hour) * 60 + - sd->min - tm->tm_min) * 60) + sd->sec - tm->tm_sec; + return obj; } EAPI void -elm_clock_time_set(Evas_Object *obj, - int hrs, - int min, - int sec) +elm_clock_time_set(Evas_Object *obj, int hrs, int min, int sec) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->hrs = hrs; - sd->min = min; - sd->sec = sec; - - _timediff_set(sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hrs = hrs; + wd->min = min; + wd->sec = sec; + _timediff_set(wd); _time_update(obj); } EAPI void -elm_clock_time_get(const Evas_Object *obj, - int *hrs, - int *min, - int *sec) +elm_clock_time_get(const Evas_Object *obj, int *hrs, int *min, int *sec) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - if (hrs) *hrs = sd->hrs; - if (min) *min = sd->min; - if (sec) *sec = sd->sec; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (hrs) *hrs = wd->hrs; + if (min) *min = wd->min; + if (sec) *sec = wd->sec; } EAPI void -elm_clock_edit_set(Evas_Object *obj, - Eina_Bool edit) +elm_clock_edit_set(Evas_Object *obj, Eina_Bool edit) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->edit = edit; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->edit = edit; if (!edit) - _timediff_set(sd); - if ((edit) && (sd->digedit == ELM_CLOCK_EDIT_DEFAULT)) + _timediff_set(wd); + if ((edit) && (wd->digedit == ELM_CLOCK_EDIT_DEFAULT)) elm_clock_edit_mode_set(obj, ELM_CLOCK_EDIT_ALL); else _time_update(obj); @@ -623,20 +596,19 @@ elm_clock_edit_set(Evas_Object *obj, EAPI Eina_Bool elm_clock_edit_get(const Evas_Object *obj) { - ELM_CLOCK_CHECK(obj) EINA_FALSE; - ELM_CLOCK_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->edit; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->edit; } EAPI void -elm_clock_edit_mode_set(Evas_Object *obj, - Elm_Clock_Edit_Mode digedit) +elm_clock_edit_mode_set(Evas_Object *obj, Elm_Clock_Edit_Mode digedit) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->digedit = digedit; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->digedit = digedit; if (digedit == ELM_CLOCK_EDIT_DEFAULT) elm_clock_edit_set(obj, EINA_FALSE); else @@ -646,67 +618,64 @@ elm_clock_edit_mode_set(Evas_Object *obj, EAPI Elm_Clock_Edit_Mode elm_clock_edit_mode_get(const Evas_Object *obj) { - ELM_CLOCK_CHECK(obj) 0; - ELM_CLOCK_DATA_GET_OR_RETURN_VAL(obj, sd, 0); - - return sd->digedit; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->digedit; } EAPI void -elm_clock_show_am_pm_set(Evas_Object *obj, - Eina_Bool am_pm) +elm_clock_show_am_pm_set(Evas_Object *obj, Eina_Bool am_pm) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->am_pm = !!am_pm; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->am_pm = !!am_pm; _time_update(obj); } EAPI Eina_Bool elm_clock_show_am_pm_get(const Evas_Object *obj) { - ELM_CLOCK_CHECK(obj) EINA_FALSE; - ELM_CLOCK_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->am_pm; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->am_pm; } EAPI void -elm_clock_show_seconds_set(Evas_Object *obj, - Eina_Bool seconds) +elm_clock_show_seconds_set(Evas_Object *obj, Eina_Bool seconds) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->seconds = !!seconds; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->seconds = !!seconds; _time_update(obj); } EAPI Eina_Bool elm_clock_show_seconds_get(const Evas_Object *obj) { - ELM_CLOCK_CHECK(obj) EINA_FALSE; - ELM_CLOCK_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->seconds; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->seconds; } EAPI void -elm_clock_first_interval_set(Evas_Object *obj, - double interval) +elm_clock_first_interval_set(Evas_Object *obj, double interval) { - ELM_CLOCK_CHECK(obj); - ELM_CLOCK_DATA_GET(obj, sd); - - sd->first_interval = !!interval; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->first_interval = !!interval; } EAPI double elm_clock_first_interval_get(const Evas_Object *obj) { - ELM_CLOCK_CHECK(obj) 0.0; - ELM_CLOCK_DATA_GET_OR_RETURN_VAL(obj, sd, 0.0); - - return sd->first_interval; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->first_interval; } diff --git a/src/lib/elm_clock.h b/src/lib/elm_clock.h index e3e5a0a1f..a6426560f 100644 --- a/src/lib/elm_clock.h +++ b/src/lib/elm_clock.h @@ -30,12 +30,8 @@ * am/pm indicator may be optionally shown, too, when it will * switch to 12h. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for clock objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "changed" - the clock's user changed the time + * Smart callbacks one can register to: + * - "changed" - the clock's user changed the time * * Supported elm_object common APIs. * @li @ref elm_object_signal_emit diff --git a/src/lib/elm_colorselector.c b/src/lib/elm_colorselector.c index 05d2b0776..f65085508 100644 --- a/src/lib/elm_colorselector.c +++ b/src/lib/elm_colorselector.c @@ -1,14 +1,11 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char COLORSELECTOR_SMART_NAME[] = "elm_colorselector"; - -#define BASE_STEP 360.0 -#define HUE_STEP 360.0 -#define SAT_STEP 128.0 -#define LIG_STEP 256.0 -#define ALP_STEP 256.0 +#define BASE_STEP 360.0 +#define HUE_STEP 360.0 +#define SAT_STEP 128.0 +#define LIG_STEP 256.0 +#define ALP_STEP 256.0 #define DEFAULT_HOR_PAD 10 #define DEFAULT_VER_PAD 10 @@ -20,8 +17,8 @@ typedef enum _Color_Type ALPHA } Color_Type; -typedef struct _Color_Bar_Data Color_Bar_Data; -struct _Color_Bar_Data +typedef struct _Colorselector_Data Colorselector_Data; +struct _Colorselector_Data { Evas_Object *parent; Evas_Object *colorbar; @@ -31,85 +28,78 @@ struct _Color_Bar_Data Evas_Object *bg_rect; Evas_Object *arrow; Evas_Object *touch_area; - Color_Type color_type; + Color_Type color_type; }; -typedef struct _Elm_Colorselector_Smart_Data Elm_Colorselector_Smart_Data; -typedef struct _Elm_Color_Item Elm_Color_Item; -struct _Elm_Colorselector_Smart_Data +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Color_Item Elm_Color_Item; +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - /* for the 2 displaying modes of the widget */ - Evas_Object *col_bars_area; - Evas_Object *palette_box; - - Eina_List *items; - Color_Bar_Data *cb_data[4]; - - Ecore_Timer *longpress_timer; - const char *palette_name; - Evas_Coord _x, _y, _w, _h; - - /* color components */ - int r, g, b, a; - int er, eg, eb; - int sr, sg, sb; - int lr, lg, lb; - - double h, s, l; + Evas_Object *sel; + Evas_Object *base; + Evas_Object *box; + Eina_List *items; + Colorselector_Data *cp[4]; + Ecore_Timer *longpress_timer; + const char *palette_name; + Evas_Coord _x, _y, _w, _h; + int r, g, b, a; + int er, eg, eb; + int sr, sg, sb; + int lr, lg, lb; + double h, s, l; Elm_Colorselector_Mode mode; - - Eina_Bool longpressed : 1; - Eina_Bool config_load : 1; + Eina_Bool longpressed : 1; + Eina_Bool config_load: 1; }; struct _Elm_Color_Item { ELM_WIDGET_ITEM; - - Evas_Object *color_obj; + Evas_Object *color_obj; Elm_Color_RGBA *color; }; -#define ELM_COLORSELECTOR_DATA_GET(o, sd) \ - Elm_Colorselector_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_COLORSELECTOR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_COLORSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_COLORSELECTOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_COLORSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_COLORSELECTOR_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), COLORSELECTOR_SMART_NAME, __func__)) \ - return - -#define ELM_COLORSELECTOR_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_COLORSELECTOR_CHECK(it->base.widget); - -#define ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_COLORSELECTOR_CHECK(it->base.widget) __VA_ARGS__; +static const char *widtype = NULL; + +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _resize_cb(void *data, Evas *a, Evas_Object *obj, void *event_info); +static void _rgb_to_hsl(void *data); +static void _hsl_to_rgb(void *data); +static void _color_with_saturation(void *data); +static void _color_with_lightness(void *data); +static void _draw_rects(void *data, double x); +static void _arrow_cb(void *data, Evas_Object *obj, const char *emission, + const char *source); +static void _colorbar_cb(void *data, Evas *e, Evas_Object *obj, + void *event_info); +static void _left_button_clicked_cb(void *data, Evas_Object * obj, + void *event_info); +static void _left_button_repeat_cb(void *data, Evas_Object * obj, + void *event_info); +static void _right_button_clicked_cb(void *data, Evas_Object * obj, + void *event_info); +static void _right_button_repeat_cb(void *data, Evas_Object * obj, + void *event_info); +static void _add_colorbar(Evas_Object *obj); +static void _set_color(Evas_Object *obj, int r, int g, int b, int a); +static Elm_Color_Item *_item_new(Evas_Object *obj); +static void _item_sizing_eval(Elm_Color_Item *item); +static void _item_highlight(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _item_unhighlight(void *data, Evas *e, Evas_Object *obj, void *event_info); +static Eina_Bool _long_press(void *data); +static void _remove_items(Widget_Data *wd); +static void _colors_remove(Evas_Object *obj); +static void _colors_save(Evas_Object *obj); +static void _colors_load_apply(Evas_Object *obj); static const char SIG_CHANGED[] = "changed"; static const char SIG_COLOR_ITEM_SELECTED[] = "color,item,selected"; static const char SIG_COLOR_ITEM_LONGPRESSED[] = "color,item,longpressed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = + +static const Evas_Smart_Cb_Description _signals[] = { {SIG_COLOR_ITEM_SELECTED, ""}, {SIG_COLOR_ITEM_LONGPRESSED, ""}, @@ -117,634 +107,84 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (COLORSELECTOR_SMART_NAME, _elm_colorselector, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - -static void -_items_del(Elm_Colorselector_Smart_Data *sd) -{ - Elm_Color_Item *item; - - if (!sd->items) return; - - EINA_LIST_FREE (sd->items, item) - { - free(item->color); - elm_widget_item_free(item); - } - - sd->items = NULL; -} - -static void -_color_with_saturation(Elm_Colorselector_Smart_Data *sd) -{ - if (sd->er > 127) - sd->sr = 127 + (int)((double)(sd->er - 127) * sd->s); - else - sd->sr = 127 - (int)((double)(127 - sd->er) * sd->s); - - if (sd->eg > 127) - sd->sg = 127 + (int)((double)(sd->eg - 127) * sd->s); - else - sd->sg = 127 - (int)((double)(127 - sd->eg) * sd->s); - - if (sd->eb > 127) - sd->sb = 127 + (int)((double)(sd->eb - 127) * sd->s); - else - sd->sb = 127 - (int)((double)(127 - sd->eb) * sd->s); -} - -static void -_color_with_lightness(Elm_Colorselector_Smart_Data *sd) -{ - if (sd->l > 0.5) - { - sd->lr = sd->er + (int)((double)(255 - sd->er) * (sd->l - 0.5) * 2.0); - sd->lg = sd->eg + (int)((double)(255 - sd->eg) * (sd->l - 0.5) * 2.0); - sd->lb = sd->eb + (int)((double)(255 - sd->eb) * (sd->l - 0.5) * 2.0); - } - else if (sd->l < 0.5) - { - sd->lr = (double)sd->er * sd->l * 2.0; - sd->lg = (double)sd->eg * sd->l * 2.0; - sd->lb = (double)sd->eb * sd->l * 2.0; - } - else - { - sd->lr = sd->er; - sd->lg = sd->eg; - sd->lb = sd->eb; - } -} - static void -_hsl_to_rgb(Elm_Colorselector_Smart_Data *sd) +_del_hook(Evas_Object *obj) { - double sv, vsf, f, p, q, t, v; - double r = 0, g = 0, b = 0; - double _h, _s, _l; + Widget_Data *wd = elm_widget_data_get(obj); int i = 0; - _h = sd->h; - _s = sd->s; - _l = sd->l; - - if (_s == 0.0) r = g = b = _l; - else - { - if (_h == 360.0) _h = 0.0; - _h /= 60.0; - - v = (_l <= 0.5) ? (_l * (1.0 + _s)) : (_l + _s - (_l * _s)); - p = _l + _l - v; - - if (v) sv = (v - p) / v; - else sv = 0; - - i = (int)_h; - f = _h - i; - - vsf = v * sv * f; - - t = p + vsf; - q = v - vsf; - - switch (i) - { - case 0: - r = v; - g = t; - b = p; - break; - - case 1: - r = q; - g = v; - b = p; - break; - - case 2: - r = p; - g = v; - b = t; - break; - - case 3: - r = p; - g = q; - b = v; - break; - - case 4: - r = t; - g = p; - b = v; - break; - - case 5: - r = v; - g = p; - b = q; - break; - } - } - i = (int)(r * 255.0); - f = (r * 255.0) - i; - sd->r = (f <= 0.5) ? i : (i + 1); - - i = (int)(g * 255.0); - f = (g * 255.0) - i; - sd->g = (f <= 0.5) ? i : (i + 1); - - i = (int)(b * 255.0); - f = (b * 255.0) - i; - sd->b = (f <= 0.5) ? i : (i + 1); -} - -static void -_rectangles_redraw(Color_Bar_Data *cb_data, double x) -{ - double one_six = 1.0 / 6.0; - - ELM_COLORSELECTOR_DATA_GET(cb_data->parent, sd); - - switch (cb_data->color_type) - { - case HUE: - sd->h = 360.0 * x; - - if (x < one_six) - { - sd->er = 255; - sd->eg = (255.0 * x * 6.0); - sd->eb = 0; - } - else if (x < 2 * one_six) - { - sd->er = 255 - (int)(255.0 * (x - one_six) * 6.0); - sd->eg = 255; - sd->eb = 0; - } - else if (x < 3 * one_six) - { - sd->er = 0; - sd->eg = 255; - sd->eb = (int)(255.0 * (x - (2.0 * one_six)) * 6.0); - } - else if (x < 4 * one_six) - { - sd->er = 0; - sd->eg = 255 - (int)(255.0 * (x - (3.0 * one_six)) * 6.0); - sd->eb = 255; - } - else if (x < 5 * one_six) - { - sd->er = 255.0 * (x - (4.0 * one_six)) * 6.0; - sd->eg = 0; - sd->eb = 255; - } - else - { - sd->er = 255; - sd->eg = 0; - sd->eb = 255 - (int)(255.0 * (x - (5.0 * one_six)) * 6.0); - } - - evas_object_color_set - (sd->cb_data[0]->arrow, sd->er, sd->eg, sd->eb, 255); - evas_object_color_set - (sd->cb_data[1]->bg_rect, sd->er, sd->eg, sd->eb, 255); - evas_object_color_set - (sd->cb_data[2]->bg_rect, sd->er, sd->eg, sd->eb, 255); - evas_object_color_set - (sd->cb_data[3]->bar, sd->er, sd->eg, sd->eb, 255); - - _color_with_saturation(sd); - evas_object_color_set - (sd->cb_data[1]->arrow, sd->sr, sd->sg, sd->sb, 255); - - _color_with_lightness(sd); - evas_object_color_set - (sd->cb_data[2]->arrow, sd->lr, sd->lg, sd->lb, 255); - - evas_object_color_set(sd->cb_data[3]->arrow, - (sd->er * sd->a) / 255, - (sd->eg * sd->a) / 255, - (sd->eb * sd->a) / 255, - sd->a); - break; - - case SATURATION: - sd->s = 1.0 - x; - _color_with_saturation(sd); - evas_object_color_set - (sd->cb_data[1]->arrow, sd->sr, sd->sg, sd->sb, 255); - break; - - case LIGHTNESS: - sd->l = x; - _color_with_lightness(sd); - evas_object_color_set - (sd->cb_data[2]->arrow, sd->lr, sd->lg, sd->lb, 255); - break; - - case ALPHA: - sd->a = 255.0 * x; - evas_object_color_set(sd->cb_data[3]->arrow, - (sd->er * sd->a) / 255, - (sd->eg * sd->a) / 255, - (sd->eb * sd->a) / 255, - sd->a); - break; - - default: - break; - } - - _hsl_to_rgb(sd); + if (!wd) return; + if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer); + if (wd->palette_name) eina_stringshare_del(wd->palette_name); + _remove_items(wd); + for (i = 0; i < 4; i++) free(wd->cp[i]); + free(wd); } static void -_arrow_cb(void *data, - Evas_Object *obj, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_theme_hook(Evas_Object *obj) { - Color_Bar_Data *cb_data = data; - double x, y; - - edje_object_part_drag_value_get(obj, "elm.arrow", &x, &y); - - _rectangles_redraw(data, x); - evas_object_smart_callback_call(cb_data->parent, SIG_CHANGED, NULL); -} - -static void -_colorbar_cb(void *data, - Evas *e, - Evas_Object *obj __UNUSED__, - void *event_info) -{ - Evas_Event_Mouse_Down *ev = event_info; - Color_Bar_Data *cb_data = data; - double arrow_x = 0, arrow_y; - Evas_Coord x, y, w, h; - - evas_object_geometry_get(cb_data->bar, &x, &y, &w, &h); - edje_object_part_drag_value_get - (cb_data->colorbar, "elm.arrow", &arrow_x, &arrow_y); - - if (w > 0) arrow_x = (double)(ev->canvas.x - x) / (double)w; - if (arrow_x > 1) arrow_x = 1; - if (arrow_x < 0) arrow_x = 0; - edje_object_part_drag_value_set - (cb_data->colorbar, "elm.arrow", arrow_x, arrow_y); - - _rectangles_redraw(data, arrow_x); - evas_object_smart_callback_call(cb_data->parent, SIG_CHANGED, NULL); - evas_event_feed_mouse_cancel(e, 0, NULL); - evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, 0, NULL); -} - -static void -_button_clicked_cb(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) -{ - Eina_Bool is_right = EINA_FALSE; - Color_Bar_Data *cb_data = data; - double x, y, step; - char buf[1024]; - - if (obj == cb_data->rbt) - { - is_right = EINA_TRUE; - step = 1.0; - } - else step = -1.0; - - snprintf(buf, sizeof(buf), "elm,state,%s,button,down", is_right ? "right" : - "left"); - - edje_object_signal_emit - (cb_data->lbt, buf, is_right ? "right_button" : "left_button"); - edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y); - - switch (cb_data->color_type) - { - case HUE: - x += step / HUE_STEP; - break; - - case SATURATION: - x += step / SAT_STEP; - break; - - case LIGHTNESS: - x += step / LIG_STEP; - break; - - case ALPHA: - x += step / ALP_STEP; - break; - - default: - break; - } - - if (is_right) - { - if (x > 1.0) x = 1.0; - } - else - { - if (x < 0.0) x = 0.0; - } - - edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y); - _rectangles_redraw(data, x); - evas_object_smart_callback_call(cb_data->parent, SIG_CHANGED, NULL); -} - -static void -_button_repeat_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Eina_Bool is_right = EINA_FALSE; - Color_Bar_Data *cb_data = data; - double x, y, step; - - if (obj == cb_data->rbt) - { - is_right = EINA_TRUE; - step = 1.0; - } - else step = -1.0; - - edje_object_part_drag_value_get(cb_data->colorbar, "elm.arrow", &x, &y); - x += step / BASE_STEP; - - if (is_right) - { - if (x > 1.0) x = 1.0; - } - else - { - if (x < 0.0) x = 0.0; - } - - edje_object_part_drag_value_set(cb_data->colorbar, "elm.arrow", x, y); - _rectangles_redraw(data, x); - evas_object_smart_callback_call(cb_data->parent, SIG_CHANGED, NULL); -} - -static void -_color_bars_add(Evas_Object *obj) -{ - char colorbar_name[128]; - char colorbar_s[128]; - char buf[1024]; - int i = 0; - Evas *e; - - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - e = evas_object_evas_get(obj); - - for (i = 0; i < 4; i++) - { - sd->cb_data[i] = ELM_NEW(Color_Bar_Data); - sd->cb_data[i]->parent = obj; - - switch (i) - { - case 0: - sd->cb_data[i]->color_type = HUE; - break; - - case 1: - sd->cb_data[i]->color_type = SATURATION; - break; - - case 2: - sd->cb_data[i]->color_type = LIGHTNESS; - break; - - case 3: - sd->cb_data[i]->color_type = ALPHA; - break; - - default: - break; - } - - /* load colorbar area */ - sd->cb_data[i]->colorbar = edje_object_add(e); - elm_widget_theme_object_set - (obj, sd->cb_data[i]->colorbar, "colorselector", "base", - elm_widget_style_get(obj)); - snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i); - snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i); - edje_object_signal_callback_add - (sd->cb_data[i]->colorbar, "drag", "*", _arrow_cb, sd->cb_data[i]); - edje_object_part_swallow - (sd->col_bars_area, colorbar_s, sd->cb_data[i]->colorbar); - elm_widget_sub_object_add(obj, sd->cb_data[i]->colorbar); - - /* load colorbar image */ - sd->cb_data[i]->bar = edje_object_add(e); - snprintf(buf, sizeof(buf), "%s/%s", colorbar_name, - elm_widget_style_get(obj)); - elm_widget_theme_object_set - (obj, sd->cb_data[i]->bar, "colorselector", "image", buf); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.bar", sd->cb_data[i]->bar); - elm_widget_sub_object_add(obj, sd->cb_data[i]->bar); - - /* provide expanded touch area */ - sd->cb_data[i]->touch_area = evas_object_rectangle_add(e); - evas_object_color_set(sd->cb_data[i]->touch_area, 0, 0, 0, 0); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.arrow_bg", - sd->cb_data[i]->touch_area); - evas_object_event_callback_add - (sd->cb_data[i]->touch_area, EVAS_CALLBACK_MOUSE_DOWN, _colorbar_cb, - sd->cb_data[i]); - elm_widget_sub_object_add(obj, sd->cb_data[i]->touch_area); - - /* load background rectangle of the colorbar. used for - changing color of the opacity bar */ - if ((i == 1) || (i == 2)) - { - sd->cb_data[i]->bg_rect = evas_object_rectangle_add(e); - evas_object_color_set - (sd->cb_data[i]->bg_rect, sd->er, sd->eg, sd->eb, 255); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.bar_bg", - sd->cb_data[i]->bg_rect); - - elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect); - } - if (i == 3) - { - sd->cb_data[i]->bg_rect = edje_object_add(e); - snprintf(buf, sizeof(buf), "%s/%s", colorbar_name, - elm_widget_style_get(obj)); - elm_widget_theme_object_set - (obj, sd->cb_data[i]->bg_rect, "colorselector", "bg_image", - buf); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.bar_bg", - sd->cb_data[i]->bg_rect); - elm_widget_sub_object_add(obj, sd->cb_data[i]->bg_rect); - evas_object_color_set - (sd->cb_data[i]->bar, sd->er, sd->eg, sd->eb, 255); - } - - /* load arrow image, pointing the colorbar */ - sd->cb_data[i]->arrow = edje_object_add(e); - elm_widget_theme_object_set - (obj, sd->cb_data[i]->arrow, "colorselector", "arrow", - elm_widget_style_get(obj)); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.arrow_icon", - sd->cb_data[i]->arrow); - elm_widget_sub_object_add(obj, sd->cb_data[i]->arrow); - - if (i == 2) - evas_object_color_set(sd->cb_data[i]->arrow, 0, 0, 0, 255); - else - evas_object_color_set - (sd->cb_data[i]->arrow, sd->er, sd->eg, sd->eb, 255); - - /* load left button */ - sd->cb_data[i]->lbt = elm_button_add(obj); - snprintf(buf, sizeof(buf), "colorselector/left/%s", - elm_widget_style_get(obj)); - elm_object_style_set(sd->cb_data[i]->lbt, buf); - elm_widget_sub_object_add(obj, sd->cb_data[i]->lbt); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.l_button", sd->cb_data[i]->lbt); - evas_object_smart_callback_add - (sd->cb_data[i]->lbt, "clicked", _button_clicked_cb, - sd->cb_data[i]); - elm_button_autorepeat_set(sd->cb_data[i]->lbt, EINA_TRUE); - elm_button_autorepeat_initial_timeout_set - (sd->cb_data[i]->lbt, _elm_config->longpress_timeout); - elm_button_autorepeat_gap_timeout_set - (sd->cb_data[i]->lbt, (1.0 / _elm_config->fps)); - evas_object_smart_callback_add - (sd->cb_data[i]->lbt, "repeated", _button_repeat_cb, - sd->cb_data[i]); - - /* load right button */ - sd->cb_data[i]->rbt = elm_button_add(obj); - snprintf(buf, sizeof(buf), "colorselector/right/%s", - elm_widget_style_get(obj)); - elm_object_style_set(sd->cb_data[i]->rbt, buf); - elm_widget_sub_object_add(obj, sd->cb_data[i]->rbt); - edje_object_part_swallow - (sd->cb_data[i]->colorbar, "elm.r_button", sd->cb_data[i]->rbt); - evas_object_smart_callback_add - (sd->cb_data[i]->rbt, "clicked", _button_clicked_cb, - sd->cb_data[i]); - elm_button_autorepeat_set(sd->cb_data[i]->rbt, EINA_TRUE); - elm_button_autorepeat_initial_timeout_set - (sd->cb_data[i]->rbt, _elm_config->longpress_timeout); - elm_button_autorepeat_gap_timeout_set - (sd->cb_data[i]->rbt, (1.0 / _elm_config->fps)); - evas_object_smart_callback_add - (sd->cb_data[i]->rbt, "repeated", _button_repeat_cb, - sd->cb_data[i]); - } -} - -static Eina_Bool -_elm_colorselector_smart_theme(Evas_Object *obj) -{ - int i; + Widget_Data *wd = elm_widget_data_get(obj); Eina_List *elist; Elm_Color_Item *item; + int i; const char *hpadstr, *vpadstr; unsigned int h_pad = DEFAULT_HOR_PAD; unsigned int v_pad = DEFAULT_VER_PAD; - ELM_COLORSELECTOR_DATA_GET(obj, sd); + if ((!wd) || (!wd->sel)) return; - if (!ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->theme(obj)) - return EINA_FALSE; - - if (!sd->col_bars_area) return EINA_FALSE; - - elm_widget_theme_object_set - (obj, sd->col_bars_area, "colorselector", "bg", - elm_widget_style_get(obj)); - - hpadstr = edje_object_data_get - (ELM_WIDGET_DATA(sd)->resize_obj, "horizontal_pad"); + _elm_theme_object_set(obj, wd->base, "colorselector", "palette", + elm_widget_style_get(obj)); + _elm_theme_object_set(obj, wd->sel, "colorselector", "bg", + elm_widget_style_get(obj)); + hpadstr = edje_object_data_get(wd->base, "horizontal_pad"); if (hpadstr) h_pad = atoi(hpadstr); - vpadstr = edje_object_data_get - (ELM_WIDGET_DATA(sd)->resize_obj, "vertical_pad"); + vpadstr = edje_object_data_get(wd->base, "vertical_pad"); if (vpadstr) v_pad = atoi(vpadstr); - - elm_box_padding_set - (sd->palette_box, - (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()), - (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get())); - - EINA_LIST_FOREACH (sd->items, elist, item) + elm_box_padding_set(wd->box, (Evas_Coord)(h_pad * elm_widget_scale_get(obj) * _elm_config->scale), + (Evas_Coord)(v_pad * elm_widget_scale_get(obj) *_elm_config->scale)); + EINA_LIST_FOREACH(wd->items, elist, item) { - elm_layout_theme_set - (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)); - elm_widget_theme_object_set - (obj, item->color_obj, "colorselector", "item/color", - elm_widget_style_get(obj)); + elm_layout_theme_set(VIEW(item), "colorselector", "item", elm_widget_style_get(obj)); + _elm_theme_object_set(obj, item->color_obj, "colorselector", "item/color", elm_widget_style_get(obj)); } for (i = 0; i < 4; i++) { - evas_object_del(sd->cb_data[i]->colorbar); - sd->cb_data[i]->colorbar = NULL; - evas_object_del(sd->cb_data[i]->bar); - sd->cb_data[i]->bar = NULL; - evas_object_del(sd->cb_data[i]->lbt); - sd->cb_data[i]->lbt = NULL; - evas_object_del(sd->cb_data[i]->rbt); - sd->cb_data[i]->rbt = NULL; + evas_object_del(wd->cp[i]->colorbar); + wd->cp[i]->colorbar = NULL; + evas_object_del(wd->cp[i]->bar); + wd->cp[i]->bar = NULL; + evas_object_del(wd->cp[i]->lbt); + wd->cp[i]->lbt = NULL; + evas_object_del(wd->cp[i]->rbt); + wd->cp[i]->rbt = NULL; if (i != 0) { - evas_object_del(sd->cb_data[i]->bg_rect); - sd->cb_data[i]->bg_rect = NULL; + evas_object_del(wd->cp[i]->bg_rect); + wd->cp[i]->bg_rect = NULL; } - evas_object_del(sd->cb_data[i]->arrow); - sd->cb_data[i]->arrow = NULL; - evas_object_del(sd->cb_data[i]->touch_area); - sd->cb_data[i]->touch_area = NULL; + evas_object_del(wd->cp[i]->arrow); + wd->cp[i]->arrow = NULL; + evas_object_del(wd->cp[i]->touch_area); + wd->cp[i]->touch_area = NULL; } - _color_bars_add(obj); - elm_colorselector_color_set(obj, sd->r, sd->g, sd->b, sd->a); - - elm_layout_sizing_eval(obj); - - return EINA_TRUE; + _add_colorbar(obj); + elm_colorselector_color_set(obj, wd->r, wd->g, wd->b, wd->a); + _sizing_eval(obj); } static void -_sub_obj_size_hints_set(Evas_Object *sobj, - int timesw, - int timesh) +_colorselector_set_size_hints(Evas_Object *obj, int timesw, int timesh) { Evas_Coord minw = -1, minh = -1; elm_coords_finger_size_adjust(timesw, &minw, timesh, &minh); - edje_object_size_min_restricted_calc(sobj, &minw, &minh, minw, minh); - evas_object_size_hint_min_set(sobj, minw, minh); - evas_object_size_hint_max_set(sobj, -1, -1); + edje_object_size_min_restricted_calc(obj, &minw, &minh, + minw, minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); } static void @@ -755,181 +195,211 @@ _item_sizing_eval(Elm_Color_Item *item) if (!item) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc(VIEW(item), &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(VIEW(item), &minw, &minh, minw, + minh); evas_object_size_hint_min_set(VIEW(item), minw, minh); } -/* fix size hints of color palette items, so that the box gets it */ +static void _resize_cb(void *data, Evas *a __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); +} + static void -_palette_sizing_eval(Evas_Object *obj) +_sizing_eval_palette(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Eina_List *elist; Elm_Color_Item *item; + Evas_Coord bw = 0, bh = 0; + Evas_Coord w = 0, h = 0; + if (!wd) return; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - EINA_LIST_FOREACH (sd->items, elist, item) - _item_sizing_eval(item); + EINA_LIST_FOREACH(wd->items, elist, item) + { + _item_sizing_eval(item); + } + evas_object_size_hint_min_get(wd->box, &bw, &bh); + evas_object_size_hint_min_set(obj, bw, bh); + evas_object_size_hint_max_set(obj, -1, -1); + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (w < bw) w = bw; + if (h < bh) h = bh; + evas_object_resize(obj, w, h); } static void -_component_sizing_eval(Evas_Object *obj) +_sizing_eval_selector(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; + Evas_Coord w = 0, h = 0; int i; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - + if (!wd) return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); for (i = 0; i < 4; i++) { - if (sd->cb_data[i]->bg_rect) - _sub_obj_size_hints_set(sd->cb_data[i]->bg_rect, 1, 1); + if (wd->cp[i]->bg_rect) + _colorselector_set_size_hints(wd->cp[i]->bg_rect, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->bar, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->rbt, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->lbt, 1, 1); - _sub_obj_size_hints_set(sd->cb_data[i]->bar, 1, 1); - _sub_obj_size_hints_set(sd->cb_data[i]->rbt, 1, 1); - _sub_obj_size_hints_set(sd->cb_data[i]->lbt, 1, 1); - _sub_obj_size_hints_set(sd->cb_data[i]->colorbar, 4, 1); + _colorselector_set_size_hints(wd->cp[i]->colorbar, 4, 1); } - edje_object_size_min_restricted_calc - (sd->col_bars_area, &minw, &minh, minw, minh); - evas_object_size_hint_min_set(sd->col_bars_area, minw, minh); -} - -static void -_full_sizing_eval(Evas_Object *obj) -{ - _palette_sizing_eval(obj); - _component_sizing_eval(obj); + elm_coords_finger_size_adjust(4, &minw, 4, &minh); + edje_object_size_min_restricted_calc(wd->sel, &minw, &minh, minw, minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (w < minw) w = minw; + if (h < minh) h = minh; + evas_object_resize(obj, w, h); } static void -_elm_colorselector_smart_sizing_eval(Evas_Object *obj) +_sizing_eval_palette_selector(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; - - ELM_COLORSELECTOR_DATA_GET(obj, sd); - + Evas_Coord bw = 0, bh = 0; + Evas_Coord w = 0, h = 0; + int i; + if (!wd) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - - switch (sd->mode) + for (i = 0; i < 4; i++) { - case ELM_COLORSELECTOR_PALETTE: - _palette_sizing_eval(obj); - break; + if (wd->cp[i]->bg_rect) + _colorselector_set_size_hints(wd->cp[i]->bg_rect, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->bar, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->rbt, 1, 1); + _colorselector_set_size_hints(wd->cp[i]->lbt, 1, 1); - case ELM_COLORSELECTOR_COMPONENTS: - _component_sizing_eval(obj); - break; - - case ELM_COLORSELECTOR_BOTH: - _full_sizing_eval(obj); - break; - - default: - return; + _colorselector_set_size_hints(wd->cp[i]->colorbar, 4, 1); } - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); + elm_coords_finger_size_adjust(4, &minw, 4, &minh); + edje_object_size_min_restricted_calc(wd->sel, &minw, &minh, minw, minh); + evas_object_size_hint_min_get(wd->box, &bw, &bh); + evas_object_size_hint_min_set(obj, minw, minh+bh); evas_object_size_hint_max_set(obj, -1, -1); + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (w < minw) w = minw; + if (h < (minh+bh)) h = (minh+bh); + evas_object_resize(obj, w, h); } -static Eina_Bool -_on_color_long_press(void *data) +static void +_sizing_eval(Evas_Object *obj) { - Elm_Color_Item *item = (Elm_Color_Item *)data; - - ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd); - - sd->longpress_timer = NULL; - sd->longpressed = EINA_TRUE; - evas_object_smart_callback_call - (WIDGET(item), SIG_COLOR_ITEM_LONGPRESSED, item); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + switch (wd->mode) + { + case ELM_COLORSELECTOR_PALETTE: + _sizing_eval_palette(obj); + break; + case ELM_COLORSELECTOR_COMPONENTS: + _sizing_eval_selector(obj); + break; + case ELM_COLORSELECTOR_BOTH: + _sizing_eval_palette_selector(obj); + break; + default: + break; + } +} +static Eina_Bool +_long_press(void *data) +{ + Elm_Color_Item *item = (Elm_Color_Item *) data; + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return ECORE_CALLBACK_CANCEL; + wd->longpress_timer = NULL; + wd->longpressed = EINA_TRUE; + evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_LONGPRESSED, item); return ECORE_CALLBACK_CANCEL; } static void -_on_color_pressed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_item_highlight(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Color_Item *item = (Elm_Color_Item *)data; + Elm_Color_Item *item = (Elm_Color_Item *) data; Evas_Event_Mouse_Down *ev = event_info; - if (!item) return; - - ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd); - + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return; if (ev->button != 1) return; elm_object_signal_emit(VIEW(item), "elm,state,selected", "elm"); - sd->longpressed = EINA_FALSE; - - if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer); - sd->longpress_timer = ecore_timer_add - (_elm_config->longpress_timeout, _on_color_long_press, data); + wd->longpressed = EINA_FALSE; + if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer); + wd->longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data); } static void -_on_color_released(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_item_unhighlight(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Color_Item *item = (Elm_Color_Item *)data; + Elm_Color_Item *item = (Elm_Color_Item *) data; Evas_Event_Mouse_Down *ev = event_info; if (!item) return; - - ELM_COLORSELECTOR_DATA_GET(WIDGET(item), sd); - + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return; if (ev->button != 1) return; - if (sd->longpress_timer) + if (wd->longpress_timer) { - ecore_timer_del(sd->longpress_timer); - sd->longpress_timer = NULL; + ecore_timer_del(wd->longpress_timer); + wd->longpress_timer = NULL; } elm_object_signal_emit(VIEW(item), "elm,state,unselected", "elm"); - if (!sd->longpressed) + if (!wd->longpressed) + { + evas_object_smart_callback_call(WIDGET(item), SIG_COLOR_ITEM_SELECTED, item); + elm_colorselector_color_set(WIDGET(item), item->color->r, item->color->g, item->color->b, item->color->a); + } +} + +static void +_remove_items(Widget_Data *wd) +{ + Elm_Color_Item *item; + + if (!wd->items) return; + + EINA_LIST_FREE(wd->items, item) { - evas_object_smart_callback_call - (WIDGET(item), SIG_COLOR_ITEM_SELECTED, item); - elm_colorselector_color_set - (WIDGET(item), item->color->r, item->color->g, item->color->b, - item->color->a); + free(item->color); + elm_widget_item_free(item); } + + wd->items = NULL; } -static Elm_Color_Item * +static Elm_Color_Item* _item_new(Evas_Object *obj) { Elm_Color_Item *item; + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return NULL; item = elm_widget_item_new(obj, Elm_Color_Item); if (!item) return NULL; VIEW(item) = elm_layout_add(obj); - elm_layout_theme_set - (VIEW(item), "colorselector", "item", elm_widget_style_get(obj)); - evas_object_size_hint_weight_set - (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_layout_theme_set(VIEW(item), "colorselector", "item", elm_widget_style_get(obj)); + evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL); - item->color_obj = edje_object_add(evas_object_evas_get(obj)); - elm_widget_theme_object_set - (obj, item->color_obj, "colorselector", "item/color", - elm_widget_style_get(obj)); - evas_object_size_hint_weight_set - (item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_event_callback_add - (item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_color_pressed, item); - evas_object_event_callback_add - (item->color_obj, EVAS_CALLBACK_MOUSE_UP, _on_color_released, item); + _elm_theme_object_set(obj, item->color_obj, "colorselector", "item/color", elm_widget_style_get(obj)); + evas_object_size_hint_weight_set(item->color_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(item->color_obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_event_callback_add(item->color_obj, EVAS_CALLBACK_MOUSE_DOWN, _item_highlight, item); + evas_object_event_callback_add(item->color_obj, EVAS_CALLBACK_MOUSE_UP, _item_unhighlight, item); elm_object_part_content_set(VIEW(item), "color_obj", item->color_obj); - _item_sizing_eval(item); evas_object_show(VIEW(item)); @@ -939,72 +409,65 @@ _item_new(Evas_Object *obj) static void _colors_remove(Evas_Object *obj) { - ELM_COLORSELECTOR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); - _items_del(sd); - _elm_config_colors_free(sd->palette_name); + _remove_items(wd); + _elm_config_colors_free(wd->palette_name); } -static void -_colors_save(Evas_Object *obj) +static void _colors_save(Evas_Object *obj) { Eina_List *elist; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Color_Item *item; - - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - _elm_config_colors_free(sd->palette_name); - EINA_LIST_FOREACH (sd->items, elist, item) - _elm_config_color_set(sd->palette_name, item->color->r, item->color->g, - item->color->b, item->color->a); + _elm_config_colors_free(wd->palette_name); + EINA_LIST_FOREACH(wd->items, elist, item) + { + _elm_config_color_set(wd->palette_name, item->color->r, item->color->g, + item->color->b, item->color->a); + } } static void -_palette_colors_load(Evas_Object *obj) +_colors_load_apply(Evas_Object *obj) { + Elm_Color_RGBA *color; Eina_List *elist; - Elm_Color_Item *item; Eina_List *color_list; - Elm_Color_RGBA *color; - - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - color_list = _elm_config_color_list_get(sd->palette_name); + Elm_Color_Item *item; + Widget_Data *wd = elm_widget_data_get(obj); + color_list = _elm_config_color_list_get(wd->palette_name); if (!color_list) return; - - EINA_LIST_FOREACH (color_list, elist, color) + EINA_LIST_FOREACH(color_list, elist, color) { item = _item_new(obj); if (!item) return; - item->color = ELM_NEW(Elm_Color_RGBA); if (!item->color) return; item->color->r = color->r; item->color->g = color->g; item->color->b = color->b; item->color->a = color->a; - - elm_box_pack_end(sd->palette_box, VIEW(item)); - evas_object_color_set - (item->color_obj, item->color->r, item->color->g, item->color->b, - item->color->a); - - sd->items = eina_list_append(sd->items, item); + elm_box_pack_end(wd->box, VIEW(item)); + evas_object_color_set(item->color_obj, item->color->r, item->color->g, + item->color->b, item->color->a); + wd->items = eina_list_append(wd->items, item); + _sizing_eval_palette(obj); } - - sd->config_load = EINA_TRUE; + wd->config_load = EINA_TRUE; } static void -_rgb_to_hsl(Elm_Colorselector_Smart_Data *sd) +_rgb_to_hsl(void *data) { - double r2, g2, b2; - double v, m, vm; + Widget_Data *wd = data; double r, g, b; + double v, m, vm; + double r2, g2, b2; - r = sd->r; - g = sd->g; - b = sd->b; + r = wd->r; + g = wd->g; + b = wd->b; r /= 255.0; g /= 255.0; @@ -1016,279 +479,719 @@ _rgb_to_hsl(Elm_Colorselector_Smart_Data *sd) m = (r < g) ? r : g; m = (m < b) ? m : b; - sd->h = 0.0; - sd->s = 0.0; - sd->l = 0.0; + wd->h = 0.0; + wd->s = 0.0; + wd->l = 0.0; - sd->l = (m + v) / 2.0; + wd->l = (m + v) / 2.0; - if (sd->l <= 0.0) return; + if (wd->l <= 0.0) return; vm = v - m; - sd->s = vm; + wd->s = vm; - if (sd->s > 0.0) sd->s /= (sd->l <= 0.5) ? (v + m) : (2.0 - v - m); + if (wd->s > 0.0) wd->s /= (wd->l <= 0.5) ? (v + m) : (2.0 - v - m); else return; r2 = (v - r) / vm; g2 = (v - g) / vm; b2 = (v - b) / vm; - if (r == v) sd->h = (g == m ? 5.0 + b2 : 1.0 - g2); - else if (g == v) - sd->h = (b == m ? 1.0 + r2 : 3.0 - b2); - else sd->h = (r == m ? 3.0 + g2 : 5.0 - r2); + if (r == v) wd->h = (g == m ? 5.0 + b2 : 1.0 - g2); + else if (g == v) wd->h = (b == m ? 1.0 + r2 : 3.0 - b2); + else wd->h = (r == m ? 3.0 + g2 : 5.0 - r2); + + wd->h *= 60.0; +} + +static void +_hsl_to_rgb(void *data) +{ + Widget_Data *wd = data; + double r = 0, g = 0, b = 0; + double _h, _s, _l; + int i = 0; + double sv, vsf, f, p, q, t, v; + + _h = wd->h; + _s = wd->s; + _l = wd->l; + + if (_s == 0.0) r = g = b = _l; + else + { + if (_h == 360.0) _h = 0.0; + _h /= 60.0; + + v = (_l <= 0.5) ? (_l * (1.0 + _s)) : (_l + _s - (_l * _s)); + p = _l + _l - v; + + if (v) sv = (v - p) / v; + else sv = 0; + + i = (int)_h; + f = _h - i; + + vsf = v * sv * f; + + t = p + vsf; + q = v - vsf; + + switch (i) + { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + } + i = (int)(r * 255.0); + f = (r * 255.0) - i; + wd->r = (f <= 0.5) ? i : (i + 1); + + i = (int)(g * 255.0); + f = (g * 255.0) - i; + wd->g = (f <= 0.5) ? i : (i + 1); + + i = (int)(b * 255.0); + f = (b * 255.0) - i; + wd->b = (f <= 0.5) ? i : (i + 1); +} + +static void +_color_with_saturation(void *data) +{ + Widget_Data *wd = data; + + if (wd->er > 127) + wd->sr = 127 + (int)((double)(wd->er - 127) * wd->s); + else + wd->sr = 127 - (int)((double)(127 - wd->er) * wd->s); + + if (wd->eg > 127) + wd->sg = 127 + (int)((double)(wd->eg - 127) * wd->s); + else + wd->sg = 127 - (int)((double)(127 - wd->eg) * wd->s); - sd->h *= 60.0; + if (wd->eb > 127) + wd->sb = 127 + (int)((double)(wd->eb - 127) * wd->s); + else + wd->sb = 127 - (int)((double)(127 - wd->eb) * wd->s); } static void -_colors_set(Evas_Object *obj, - int r, - int g, - int b, - int a) +_color_with_lightness(void *data) { + Widget_Data *wd = data; + + if (wd->l > 0.5) + { + wd->lr = wd->er + (int)((double)(255 - wd->er) * (wd->l - 0.5) * 2.0); + wd->lg = wd->eg + (int)((double)(255 - wd->eg) * (wd->l - 0.5) * 2.0); + wd->lb = wd->eb + (int)((double)(255 - wd->eb) * (wd->l - 0.5) * 2.0); + } + else if (wd->l < 0.5) + { + wd->lr = (double)wd->er * wd->l * 2.0; + wd->lg = (double)wd->eg * wd->l * 2.0; + wd->lb = (double)wd->eb * wd->l * 2.0; + } + else + { + wd->lr = wd->er; + wd->lg = wd->eg; + wd->lb = wd->eb; + } +} + +static void +_draw_rects(void *data, double x) +{ + Colorselector_Data *cp = data; + Widget_Data *wd = elm_widget_data_get(cp->parent); + double one_six = 1.0 / 6.0; + + switch (cp->color_type) + { + case HUE: + wd->h = 360.0 * x; + + if (x < one_six) + { + wd->er = 255; + wd->eg = (255.0 * x * 6.0); + wd->eb = 0; + } + else if (x < 2 * one_six) + { + wd->er = 255 - (int)(255.0 * (x - one_six) * 6.0); + wd->eg = 255; + wd->eb = 0; + } + else if (x < 3 * one_six) + { + wd->er = 0; + wd->eg = 255; + wd->eb = (int)(255.0 * (x - (2.0 * one_six)) * 6.0); + } + else if (x < 4 * one_six) + { + wd->er = 0; + wd->eg = 255 - (int)(255.0 * (x - (3.0 * one_six)) * 6.0); + wd->eb = 255; + } + else if (x < 5 * one_six) + { + wd->er = 255.0 * (x - (4.0 * one_six)) * 6.0; + wd->eg = 0; + wd->eb = 255; + } + else + { + wd->er = 255; + wd->eg = 0; + wd->eb = 255 - (int)(255.0 * (x - (5.0 * one_six)) * 6.0); + } + + evas_object_color_set(wd->cp[0]->arrow, wd->er, wd->eg, wd->eb, 255); + evas_object_color_set(wd->cp[1]->bg_rect, wd->er, wd->eg, wd->eb, 255); + evas_object_color_set(wd->cp[2]->bg_rect, wd->er, wd->eg, wd->eb, 255); + evas_object_color_set(wd->cp[3]->bar, wd->er, wd->eg, wd->eb, 255); + + _color_with_saturation(wd); + evas_object_color_set(wd->cp[1]->arrow, wd->sr, wd->sg, wd->sb, 255); + + _color_with_lightness(wd); + evas_object_color_set(wd->cp[2]->arrow, wd->lr, wd->lg, wd->lb, 255); + + evas_object_color_set(wd->cp[3]->arrow, + (wd->er * wd->a) / 255, + (wd->eg * wd->a) / 255, + (wd->eb * wd->a) / 255, + wd->a); + break; + case SATURATION: + wd->s = 1.0 - x; + _color_with_saturation(wd); + evas_object_color_set(wd->cp[1]->arrow, wd->sr, wd->sg, wd->sb, 255); + break; + case LIGHTNESS: + wd->l = x; + _color_with_lightness(wd); + evas_object_color_set(wd->cp[2]->arrow, wd->lr, wd->lg, wd->lb, 255); + break; + case ALPHA: + wd->a = 255.0 * x; + evas_object_color_set(wd->cp[3]->arrow, + (wd->er * wd->a) / 255, + (wd->eg * wd->a) / 255, + (wd->eb * wd->a) / 255, + wd->a); + break; + default: + break; + } + _hsl_to_rgb(wd); +} + +static void +_arrow_cb(void *data, Evas_Object *obj, const char *emission __UNUSED__, + const char *source __UNUSED__) +{ + Colorselector_Data *cp = data; double x, y; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - sd->r = r; - sd->g = g; - sd->b = b; - sd->a = a; - - _rgb_to_hsl(sd); - - edje_object_part_drag_value_get - (sd->cb_data[0]->colorbar, "elm.arrow", &x, &y); - x = sd->h / 360.0; - edje_object_part_drag_value_set - (sd->cb_data[0]->colorbar, "elm.arrow", x, y); - _rectangles_redraw(sd->cb_data[0], x); - - edje_object_part_drag_value_get - (sd->cb_data[1]->colorbar, "elm.arrow", &x, &y); - x = 1.0 - sd->s; - edje_object_part_drag_value_set - (sd->cb_data[1]->colorbar, "elm.arrow", x, y); - _rectangles_redraw(sd->cb_data[1], x); - - edje_object_part_drag_value_get - (sd->cb_data[2]->colorbar, "elm.arrow", &x, &y); - x = sd->l; - edje_object_part_drag_value_set(sd->cb_data[2]->colorbar, "elm.arrow", x, y); - _rectangles_redraw(sd->cb_data[2], x); - - edje_object_part_drag_value_get - (sd->cb_data[3]->colorbar, "elm.arrow", &x, &y); - x = sd->a / 255.0; - edje_object_part_drag_value_set - (sd->cb_data[3]->colorbar, "elm.arrow", x, y); - - _rectangles_redraw(sd->cb_data[3], x); + edje_object_part_drag_value_get(obj, "elm.arrow", &x, &y); + _draw_rects(data, x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); } static void -_elm_colorselector_smart_add(Evas_Object *obj) +_colorbar_cb(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info) { - const char *hpadstr, *vpadstr; - unsigned int h_pad = DEFAULT_HOR_PAD; - unsigned int v_pad = DEFAULT_VER_PAD; + Colorselector_Data *cp = data; + Evas_Event_Mouse_Down *ev = event_info; + Evas_Coord x, y, w, h; + double arrow_x = 0, arrow_y; - EVAS_SMART_DATA_ALLOC(obj, Elm_Colorselector_Smart_Data); + evas_object_geometry_get(cp->bar, &x, &y, &w, &h); + edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", + &arrow_x, &arrow_y); + if (w > 0) arrow_x = (double)(ev->canvas.x - x) / (double)w; + if (arrow_x > 1) arrow_x = 1; + if (arrow_x < 0) arrow_x = 0; + edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", arrow_x, arrow_y); + _draw_rects(data, arrow_x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); + evas_event_feed_mouse_cancel(e, 0, NULL); + evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, 0, NULL); +} - ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->base.add(obj); +static void +_left_button_clicked_cb(void *data, Evas_Object * obj __UNUSED__, + void *event_info __UNUSED__) +{ + Colorselector_Data *cp = data; + double x, y; - elm_layout_theme_set - (obj, "colorselector", "palette", elm_object_style_get(obj)); + edje_object_signal_emit(cp->lbt, "elm,state,left,button,down", + "left_button"); + edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y); - priv->palette_box = elm_box_add(obj); - elm_box_layout_set - (priv->palette_box, evas_object_box_layout_flow_horizontal, NULL, NULL); - elm_box_horizontal_set(priv->palette_box, EINA_TRUE); - evas_object_size_hint_weight_set - (priv->palette_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (priv->palette_box, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_box_homogeneous_set(priv->palette_box, EINA_TRUE); + switch(cp->color_type) + { + case HUE : + x -= 1.0 / HUE_STEP; + break; + case SATURATION : + x -= 1.0 / SAT_STEP; + break; + case LIGHTNESS : + x -= 1.0 / LIG_STEP; + break; + case ALPHA : + x -= 1.0 / ALP_STEP; + break; + default : + break; + } - hpadstr = - edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj, "horizontal_pad"); - if (hpadstr) h_pad = atoi(hpadstr); - vpadstr = edje_object_data_get - (ELM_WIDGET_DATA(priv)->resize_obj, "vertical_pad"); - if (vpadstr) v_pad = atoi(vpadstr); + if (x < 0.0) x = 0.0; - elm_box_padding_set - (priv->palette_box, - (h_pad * elm_widget_scale_get(obj) * elm_config_scale_get()), - (v_pad * elm_widget_scale_get(obj) * elm_config_scale_get())); + edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y); + _draw_rects(data, x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); +} - elm_box_align_set(priv->palette_box, 0.5, 0.5); - elm_layout_content_set(obj, "palette", priv->palette_box); - priv->palette_name = eina_stringshare_add("default"); - _palette_colors_load(obj); +static void +_left_button_repeat_cb(void *data, Evas_Object * obj __UNUSED__, + void *event_info __UNUSED__) +{ + Colorselector_Data *cp = data; + double x, y; - /* load background edj */ - priv->col_bars_area = edje_object_add(evas_object_evas_get(obj)); - elm_widget_theme_object_set - (obj, priv->col_bars_area, "colorselector", "bg", - elm_widget_style_get(obj)); - elm_layout_content_set(obj, "selector", priv->col_bars_area); - - priv->mode = ELM_COLORSELECTOR_BOTH; - priv->er = 255; - priv->eg = 0; - priv->eb = 0; - priv->h = 0.0; - priv->s = 1.0; - priv->l = 0.0; - priv->a = 255; - - _hsl_to_rgb(priv); - _color_bars_add(obj); - - elm_layout_sizing_eval(obj); + edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y); + x -= 1.0 / BASE_STEP; + if (x < 0.0) x = 0.0; + edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y); + _draw_rects(data, x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); + +} + +static void +_right_button_clicked_cb(void *data, Evas_Object * obj __UNUSED__, + void *event_info __UNUSED__) +{ + Colorselector_Data *cp = data; + double x, y; + + edje_object_signal_emit(cp->rbt, "elm,state,right,button,down", + "right_button"); + edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y); + + switch(cp->color_type) + { + case HUE : + x += 1.0 / HUE_STEP; + break; + case SATURATION : + x += 1.0 / SAT_STEP; + break; + case LIGHTNESS : + x += 1.0 / LIG_STEP; + break; + case ALPHA : + x += 1.0 / ALP_STEP; + break; + default : + break; + } + + if (x > 1.0) x = 1.0; + + edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y); + _draw_rects(data, x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); } static void -_elm_colorselector_smart_del(Evas_Object *obj) +_right_button_repeat_cb(void *data, Evas_Object * obj __UNUSED__, + void *event_info __UNUSED__) { + Colorselector_Data *cp = data; + double x, y; + + edje_object_part_drag_value_get(cp->colorbar, "elm.arrow", &x, &y); + x += 1.0 / BASE_STEP; + if (x > 1.0) x = 1.0; + edje_object_part_drag_value_set(cp->colorbar, "elm.arrow", x, y); + _draw_rects(data, x); + evas_object_smart_callback_call(cp->parent, SIG_CHANGED, NULL); +} + +static void +_add_colorbar(Evas_Object *obj) +{ + char colorbar_name[128]; + char colorbar_s[128]; + Widget_Data *wd; + Evas *e; int i = 0; + char buf[1024]; - ELM_COLORSELECTOR_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; - if (sd->longpress_timer) ecore_timer_del(sd->longpress_timer); - if (sd->palette_name) eina_stringshare_del(sd->palette_name); + e = evas_object_evas_get(obj); - _items_del(sd); for (i = 0; i < 4; i++) - free(sd->cb_data[i]); + { + wd->cp[i] = ELM_NEW(Colorselector_Data); + wd->cp[i]->parent = obj; + switch(i) + { + case 0 : + wd->cp[i]->color_type = HUE; + break; + case 1 : + wd->cp[i]->color_type = SATURATION; + break; + case 2 : + wd->cp[i]->color_type = LIGHTNESS; + break; + case 3 : + wd->cp[i]->color_type = ALPHA; + break; + default : + break; + } + /* load colorbar area */ + wd->cp[i]->colorbar = edje_object_add(e); + _elm_theme_object_set(obj, wd->cp[i]->colorbar, "colorselector", "base", + elm_widget_style_get(obj)); + snprintf(colorbar_name, sizeof(colorbar_name), "colorbar_%d", i); + snprintf(colorbar_s, sizeof(colorbar_s), "elm.colorbar_%d", i); + edje_object_signal_callback_add(wd->cp[i]->colorbar, "drag", "*", + _arrow_cb, wd->cp[i]); + edje_object_part_swallow(wd->sel, colorbar_s, wd->cp[i]->colorbar); + elm_widget_sub_object_add(obj, wd->cp[i]->colorbar); + + /* load colorbar image */ + wd->cp[i]->bar = edje_object_add(e); + snprintf(buf, sizeof(buf), "%s/%s", colorbar_name, + elm_widget_style_get(obj)); + _elm_theme_object_set(obj, wd->cp[i]->bar, "colorselector", "image", + buf); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar", + wd->cp[i]->bar); + elm_widget_sub_object_add(obj, wd->cp[i]->bar); + + /* provide expanded touch area */ + wd->cp[i]->touch_area = evas_object_rectangle_add(e); + evas_object_color_set(wd->cp[i]->touch_area, 0, 0, 0, 0); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.arrow_bg", + wd->cp[i]->touch_area); + evas_object_event_callback_add(wd->cp[i]->touch_area, + EVAS_CALLBACK_MOUSE_DOWN, _colorbar_cb, + wd->cp[i]); + elm_widget_sub_object_add(obj, wd->cp[i]->touch_area); + + /* load background rectangle of the colorbar. used for + changing color of the opacity bar */ + if ((i == 1) || (i == 2)) + { + wd->cp[i]->bg_rect = evas_object_rectangle_add(e); + evas_object_color_set(wd->cp[i]->bg_rect, wd->er, wd->eg, wd->eb, + 255); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar_bg", + wd->cp[i]->bg_rect); + + elm_widget_sub_object_add(obj, wd->cp[i]->bg_rect); + } + if (i == 3) + { + wd->cp[i]->bg_rect = edje_object_add(e); + snprintf(buf, sizeof(buf), "%s/%s", colorbar_name, + elm_widget_style_get(obj)); + _elm_theme_object_set(obj, wd->cp[i]->bg_rect, "colorselector", + "bg_image", buf); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.bar_bg", + wd->cp[i]->bg_rect); + elm_widget_sub_object_add(obj, wd->cp[i]->bg_rect); + evas_object_color_set(wd->cp[i]->bar, wd->er, wd->eg, wd->eb, 255); + } + /* load arrow image, pointing the colorbar */ + wd->cp[i]->arrow = edje_object_add(e); + _elm_theme_object_set(obj, wd->cp[i]->arrow, "colorselector", "arrow", + elm_widget_style_get(obj)); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.arrow_icon", + wd->cp[i]->arrow); + elm_widget_sub_object_add(obj, wd->cp[i]->arrow); + if (i == 2) + evas_object_color_set(wd->cp[i]->arrow, 0, 0, 0, 255); + else + evas_object_color_set(wd->cp[i]->arrow, wd->er, wd->eg, wd->eb, 255); + + /* load left button */ + wd->cp[i]->lbt = elm_button_add(obj); + snprintf(buf, sizeof(buf), "colorselector/left/%s", + elm_widget_style_get(obj)); + elm_object_style_set(wd->cp[i]->lbt, buf); + elm_widget_sub_object_add(obj, wd->cp[i]->lbt); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.l_button", + wd->cp[i]->lbt); + evas_object_smart_callback_add(wd->cp[i]->lbt, "clicked", + _left_button_clicked_cb, wd->cp[i]); + elm_button_autorepeat_set(wd->cp[i]->lbt, EINA_TRUE); + elm_button_autorepeat_initial_timeout_set(wd->cp[i]->lbt, + _elm_config->longpress_timeout); + elm_button_autorepeat_gap_timeout_set(wd->cp[i]->lbt, + (1.0 / _elm_config->fps)); + evas_object_smart_callback_add(wd->cp[i]->lbt, "repeated", + _left_button_repeat_cb, wd->cp[i]); - ELM_WIDGET_CLASS(_elm_colorselector_parent_sc)->base.del(obj); + /* load right button */ + wd->cp[i]->rbt = elm_button_add(obj); + snprintf(buf, sizeof(buf), "colorselector/right/%s", + elm_widget_style_get(obj)); + elm_object_style_set(wd->cp[i]->rbt, buf); + elm_widget_sub_object_add(obj, wd->cp[i]->rbt); + edje_object_part_swallow(wd->cp[i]->colorbar, "elm.r_button", + wd->cp[i]->rbt); + evas_object_smart_callback_add(wd->cp[i]->rbt, "clicked", + _right_button_clicked_cb, wd->cp[i]); + elm_button_autorepeat_set(wd->cp[i]->rbt, EINA_TRUE); + elm_button_autorepeat_initial_timeout_set(wd->cp[i]->rbt, + _elm_config->longpress_timeout); + elm_button_autorepeat_gap_timeout_set(wd->cp[i]->rbt, + (1.0 / _elm_config->fps)); + evas_object_smart_callback_add(wd->cp[i]->rbt, "repeated", + _right_button_repeat_cb, wd->cp[i]); + } } static void -_elm_colorselector_smart_set_user(Elm_Layout_Smart_Class *sc) +_set_color(Evas_Object *obj, int r, int g, int b, int a) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_colorselector_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_colorselector_smart_del; + Widget_Data *wd = elm_widget_data_get(obj); + double x, y; + + wd->r = r; + wd->g = g; + wd->b = b; + wd->a = a; + + _rgb_to_hsl(wd); + + edje_object_part_drag_value_get(wd->cp[0]->colorbar, "elm.arrow", &x, &y); + x = wd->h / 360.0; + edje_object_part_drag_value_set(wd->cp[0]->colorbar, "elm.arrow", x, y); + _draw_rects(wd->cp[0], x); - ELM_WIDGET_CLASS(sc)->focus_next = NULL; - ELM_WIDGET_CLASS(sc)->theme = _elm_colorselector_smart_theme; + edje_object_part_drag_value_get(wd->cp[1]->colorbar, "elm.arrow", &x, &y); + x = 1.0 - wd->s; + edje_object_part_drag_value_set(wd->cp[1]->colorbar, "elm.arrow", x, y); + _draw_rects(wd->cp[1], x); - sc->sizing_eval = _elm_colorselector_smart_sizing_eval; + edje_object_part_drag_value_get(wd->cp[2]->colorbar, "elm.arrow", &x, &y); + x = wd->l; + edje_object_part_drag_value_set(wd->cp[2]->colorbar, "elm.arrow", x, y); + _draw_rects(wd->cp[2], x); + + edje_object_part_drag_value_get(wd->cp[3]->colorbar, "elm.arrow", &x, &y); + x = wd->a / 255.0; + edje_object_part_drag_value_set(wd->cp[3]->colorbar, "elm.arrow", x, y); + _draw_rects(wd->cp[3], x); } EAPI Evas_Object * elm_colorselector_add(Evas_Object *parent) { + Evas_Object *obj = NULL; + Widget_Data *wd = NULL; Evas *e; - Evas_Object *obj; + const char *hpadstr, *vpadstr; + unsigned int h_pad = DEFAULT_HOR_PAD; + unsigned int v_pad = DEFAULT_VER_PAD; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - e = evas_object_evas_get(parent); - if (!e) return NULL; + ELM_SET_WIDTYPE(widtype, "colorselector"); + elm_widget_type_set(obj, "colorselector"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + evas_object_smart_callbacks_descriptions_set(obj, _signals); - obj = evas_object_smart_add(e, _elm_colorselector_smart_class_new()); + /* load background edj */ + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "colorselector", "palette", "default"); + elm_widget_resize_object_set(obj, wd->base); + evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, + _resize_cb, obj); + + wd->box = elm_box_add(obj); + elm_box_layout_set(wd->box, evas_object_box_layout_flow_horizontal, + NULL, NULL); + elm_box_horizontal_set(wd->box, EINA_TRUE); + evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND, + 0); + evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, 0); + elm_box_homogeneous_set(wd->box, EINA_TRUE); + hpadstr = edje_object_data_get(wd->base, "horizontal_pad"); + if (hpadstr) h_pad = atoi(hpadstr); + vpadstr = edje_object_data_get(wd->base, "vertical_pad"); + if (vpadstr) v_pad = atoi(vpadstr); + elm_box_padding_set(wd->box, (Evas_Coord)(h_pad * elm_widget_scale_get(obj) * _elm_config->scale), + (Evas_Coord)(v_pad * elm_widget_scale_get(obj) *_elm_config->scale)); + elm_box_align_set(wd->box, 0.5, 0.5); + elm_widget_sub_object_add(obj, wd->box); + evas_object_show(wd->box); + edje_object_part_swallow(wd->base, "palette", wd->box); + wd->palette_name = eina_stringshare_add("default"); + _colors_load_apply(obj); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + /* load background edj */ + wd->sel = edje_object_add(e); + _elm_theme_object_set(obj, wd->sel, "colorselector", "bg", "default"); + edje_object_part_swallow(wd->base, "selector", wd->sel); + elm_widget_sub_object_add(obj, wd->sel); + + wd->mode = ELM_COLORSELECTOR_BOTH; + wd->er = 255; + wd->eg = 0; + wd->eb = 0; + wd->h = 0.0; + wd->s = 1.0; + wd->l = 0.0; + wd->a = 255; + + _hsl_to_rgb(wd); + _add_colorbar(obj); + _sizing_eval(obj); return obj; } EAPI void -elm_colorselector_color_set(Evas_Object *obj, - int r, - int g, - int b, - int a) +elm_colorselector_color_set(Evas_Object *obj, int r, int g, int b, int a) { - ELM_COLORSELECTOR_CHECK(obj); - - _colors_set(obj, r, g, b, a); + ELM_CHECK_WIDTYPE(obj, widtype); + _set_color(obj, r, g, b, a); } EAPI void -elm_colorselector_color_get(const Evas_Object *obj, - int *r, - int *g, - int *b, - int *a) +elm_colorselector_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) { - ELM_COLORSELECTOR_CHECK(obj); - ELM_COLORSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - if (r) *r = sd->r; - if (g) *g = sd->g; - if (b) *b = sd->b; - if (a) *a = sd->a; + if (r) *r = wd->r; + if (g) *g = wd->g; + if (b) *b = wd->b; + if (a) *a = wd->a; } EAPI void -elm_colorselector_mode_set(Evas_Object *obj, - Elm_Colorselector_Mode mode) +elm_colorselector_mode_set(Evas_Object *obj, Elm_Colorselector_Mode mode) { - ELM_COLORSELECTOR_CHECK(obj); - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - if (sd->mode == mode) return; - sd->mode = mode; - - evas_object_hide(elm_layout_content_unset(obj, "selector")); - evas_object_hide(elm_layout_content_unset(obj, "palette")); - - switch (sd->mode) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->mode == mode) return; + wd->mode = mode; + switch (wd->mode) { - case ELM_COLORSELECTOR_PALETTE: - elm_layout_content_set(obj, "palette", sd->palette_box); - elm_layout_signal_emit(obj, "elm,state,palette", "elm"); - break; - - case ELM_COLORSELECTOR_COMPONENTS: - elm_layout_content_set(obj, "selector", sd->col_bars_area); - elm_layout_signal_emit(obj, "elm,state,components", "elm"); - break; - - case ELM_COLORSELECTOR_BOTH: - elm_layout_content_set(obj, "palette", sd->palette_box); - elm_layout_content_set(obj, "selector", sd->col_bars_area); - elm_layout_signal_emit(obj, "elm,state,both", "elm"); - break; - - default: - return; + case ELM_COLORSELECTOR_PALETTE: + if (edje_object_part_swallow_get(wd->base, "selector")) + { + edje_object_part_unswallow(wd->base, wd->sel); + evas_object_hide(wd->sel); + } + if (!edje_object_part_swallow_get(wd->base, "palette")) + { + edje_object_part_swallow(wd->base, "palette", wd->box); + evas_object_show(wd->box); + } + edje_object_signal_emit(wd->base, "elm,state,palette", "elm"); + break; + case ELM_COLORSELECTOR_COMPONENTS: + if (edje_object_part_swallow_get(wd->base, "palette")) + { + edje_object_part_unswallow(wd->base, wd->box); + evas_object_hide(wd->box); + } + if (!edje_object_part_swallow_get(wd->base, "selector")) + { + edje_object_part_swallow(wd->base, "selector", wd->sel); + evas_object_show(wd->sel); + } + edje_object_signal_emit(wd->base, "elm,state,components", "elm"); + break; + case ELM_COLORSELECTOR_BOTH: + if (!edje_object_part_swallow_get(wd->base, "palette")) + { + edje_object_part_swallow(wd->base, "palette", wd->box); + evas_object_show(wd->box); + } + if (!edje_object_part_swallow_get(wd->base, "selector")) + { + edje_object_part_swallow(wd->base, "selector", wd->sel); + evas_object_show(wd->sel); + } + edje_object_signal_emit(wd->base, "elm,state,both", "elm"); + break; + default: + return; } + edje_object_message_signal_process(wd->base); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); + _sizing_eval(obj); } EAPI Elm_Colorselector_Mode elm_colorselector_mode_get(const Evas_Object *obj) { - ELM_COLORSELECTOR_CHECK(obj) ELM_COLORSELECTOR_BOTH; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - return sd->mode; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_COLORSELECTOR_BOTH; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_COLORSELECTOR_BOTH; + return wd->mode; } EAPI void -elm_colorselector_palette_item_color_get(const Elm_Object_Item *it, - int *r, - int *g, - int *b, - int *a) +elm_colorselector_palette_item_color_get(const Elm_Object_Item *it, int *r __UNUSED__, int *g __UNUSED__, int *b __UNUSED__, int*a __UNUSED__) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); Elm_Color_Item *item; - - ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it); - - item = (Elm_Color_Item *)it; + item = (Elm_Color_Item *) it; if (item) { if (r) *r = item->color->r; @@ -1299,101 +1202,78 @@ elm_colorselector_palette_item_color_get(const Elm_Object_Item *it, } EAPI void -elm_colorselector_palette_item_color_set(Elm_Object_Item *it, - int r, - int g, - int b, - int a) +elm_colorselector_palette_item_color_set(Elm_Object_Item *it, int r __UNUSED__, int g __UNUSED__, int b __UNUSED__, int a __UNUSED__) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); Elm_Color_Item *item; - - ELM_COLORSELECTOR_ITEM_CHECK_OR_RETURN(it); - - item = (Elm_Color_Item *)it; + item = (Elm_Color_Item *) it; item->color->r = r; item->color->g = g; item->color->b = b; item->color->a = a; - evas_object_color_set - (item->color_obj, item->color->r, item->color->g, item->color->b, - item->color->a); - + evas_object_color_set(item->color_obj, item->color->r, item->color->g, item->color->b, item->color->a); _colors_save(WIDGET(it)); } EAPI Elm_Object_Item * -elm_colorselector_palette_color_add(Evas_Object *obj, - int r, - int g, - int b, - int a) +elm_colorselector_palette_color_add(Evas_Object *obj, int r, int g, int b, int a) { Elm_Color_Item *item; - - ELM_COLORSELECTOR_CHECK(obj) NULL; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - if (sd->config_load) + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (wd->config_load) { _colors_remove(obj); - sd->config_load = EINA_FALSE; + wd->config_load = EINA_FALSE; } item = _item_new(obj); if (!item) return NULL; - item->color = ELM_NEW(Elm_Color_RGBA); if (!item->color) return NULL; - item->color->r = r; item->color->g = g; item->color->b = b; item->color->a = a; - _elm_config_color_set - (sd->palette_name, item->color->r, item->color->g, item->color->b, - item->color->a); - - elm_box_pack_end(sd->palette_box, VIEW(item)); - evas_object_color_set - (item->color_obj, item->color->r, item->color->g, item->color->b, - item->color->a); - - sd->items = eina_list_append(sd->items, item); - - elm_layout_sizing_eval(obj); - - return (Elm_Object_Item *)item; + _elm_config_color_set(wd->palette_name, item->color->r, item->color->g, + item->color->b, item->color->a); + elm_box_pack_end(wd->box, VIEW(item)); + evas_object_color_set(item->color_obj, item->color->r, item->color->g, + item->color->b, item->color->a); + wd->items = eina_list_append(wd->items, item); + _sizing_eval(obj); + return (Elm_Object_Item *) item; } EAPI void elm_colorselector_palette_clear(Evas_Object *obj) { - ELM_COLORSELECTOR_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; _colors_remove(obj); } EAPI void -elm_colorselector_palette_name_set(Evas_Object *obj, - const char *palette_name) +elm_colorselector_palette_name_set(Evas_Object *obj, const char *palette_name) { - ELM_COLORSELECTOR_CHECK(obj); - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - if (!strcmp(sd->palette_name, palette_name)) return; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (!strcmp(wd->palette_name, palette_name)) return; if (palette_name) { _colors_remove(obj); - eina_stringshare_replace(&sd->palette_name, palette_name); - _palette_colors_load(obj); + eina_stringshare_replace(&wd->palette_name, palette_name); + _colors_load_apply(obj); } } -EAPI const char * +EAPI const char* elm_colorselector_palette_name_get(const Evas_Object *obj) { - ELM_COLORSELECTOR_CHECK(obj) NULL; - ELM_COLORSELECTOR_DATA_GET(obj, sd); - - return sd->palette_name; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->palette_name; } diff --git a/src/lib/elm_colorselector.h b/src/lib/elm_colorselector.h index b45150cac..22dd78b12 100644 --- a/src/lib/elm_colorselector.h +++ b/src/lib/elm_colorselector.h @@ -5,26 +5,19 @@ * @image html img/widget/colorselector/preview-00.png * @image latex img/widget/colorselector/preview-00.eps * - * A ColorSelector is a color selection widget. It allows application - * to set a series of colors.It also allows to load/save colors - * from/to config with a unique identifier, by default, the colors are - * loaded/saved from/to config using "default" identifier. The colors - * can be picked by user from the color set by clicking on individual - * color item on the palette or by selecting it from selector. - * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for check objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "changed" - When the color value changes on selector - * event_info is NULL. - * - @c "color,item,selected" - When user clicks on color item. The - * event_info parameter of the callback will be the selected color - * item. - * - @c "color,item,longpressed" - When user long presses on color - * item. The event info parameter of the callback contains selected - * color item. + * A ColorSelector is a color selection widget. It allows application to set a + * series of colors.It also allows to load/save colors from/to config with a + * unique identifier, by default, the colors are loaded/saved from/to config + * using "default" identifier. + * The colors can be picked by user from the color set by clicking on individual color + * item on the palette or by selecting it from selector. + * + * Signals that you can add callbacks for are: + * - "changed" - When the color value changes on selector(event_info is NULL). + * - "color,item,selected" - When user clicks on color item. The event_info parameter + * of the callback will be the selected color item. + * - "color,item,longpressed" - When user long presses on color item. The event info + * parameter of the callback contains selected color item. * * See @ref tutorial_colorselector. * @{ diff --git a/src/lib/elm_conform.c b/src/lib/elm_conform.c index 2daeba777..355341e42 100644 --- a/src/lib/elm_conform.c +++ b/src/lib/elm_conform.c @@ -1,39 +1,36 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" #ifndef MIN -# define MIN(a, b) ((a) < (b)) ? (a) : (b) +# define MIN(a,b) ((a) < (b)) ? (a) : (b) #endif #ifndef MAX -# define MAX(a, b) ((a) < (b)) ? (b) : (a) +# define MAX(a,b) ((a) < (b)) ? (b) : (a) #endif -static const char CONFORM_SMART_NAME[] = "elm_conform"; - -typedef struct _Elm_Conform_Smart_Data Elm_Conform_Smart_Data; -struct _Elm_Conform_Smart_Data +typedef struct _Widget_Data Widget_Data; +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *indicator; - Evas_Object *softkey; - Evas_Object *virtualkeypad; - Evas_Object *clipboard; - Evas_Object *scroller; + Evas_Object *base; + Evas_Object *indicator; + Evas_Object *softkey; + Evas_Object *virtualkeypad; + Evas_Object *clipboard; + Evas_Object *content; + Evas_Object *scroller; #ifdef HAVE_ELEMENTARY_X - Ecore_Event_Handler *prop_hdl; + Ecore_Event_Handler *prop_hdl; Ecore_X_Virtual_Keyboard_State vkb_state; #endif struct { Ecore_Animator *animator; // animaton timer - double start; // time started - Evas_Coord auto_x, auto_y; // desired delta - Evas_Coord x, y; // current delta + double start; // time started + Evas_Coord auto_x, auto_y; // desired delta + Evas_Coord x, y; // current delta } delta; - Ecore_Job *show_region_job; + Ecore_Job *show_region_job; }; /* Enum to identify conformant swallow parts */ @@ -48,58 +45,162 @@ enum _Conformant_Part_Type #ifdef HAVE_ELEMENTARY_X #define SUB_TYPE_COUNT 2 -/* FIXME: change the smart names once those two are ported to new classes */ static char *sub_type[SUB_TYPE_COUNT] = { "scroller", "genlist" }; #endif -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +/* local function prototypes */ +static const char *widtype = NULL; +static void _del_pre_hook(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _content_set_hook(Evas_Object *obj, + const char *part, + Evas_Object *content); +static Evas_Object *_content_get_hook(const Evas_Object *obj, + const char *part); +static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part); +static void _swallow_conformant_parts(Evas_Object *obj); +static void _conformant_part_size_set(Evas_Object *obj, + Evas_Object *sobj, + Evas_Coord sx, + Evas_Coord sy, + Evas_Coord sw, + Evas_Coord sh); +static void _conformant_part_sizing_eval(Evas_Object *obj, + Conformant_Part_Type part_type); +static void _conformant_move_resize_event_cb(void *data, + Evas *e, + Evas_Object *obj, + void *event_info); +static void _sizing_eval(Evas_Object *obj); +static void _show_region_job(void *data); +static void _changed_size_hints(void *data, Evas *e, + Evas_Object *obj, + void *event_info); + +/* local functions */ +static void +_del_pre_hook(Evas_Object *obj) { - {"icon", "elm.swallow.content"}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + +#ifdef HAVE_ELEMENTARY_X + if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl); +#endif +} -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (CONFORM_SMART_NAME, _elm_conform, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); - -#define ELM_CONFORM_DATA_GET(o, sd) \ - Elm_Conform_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_CONFORM_DATA_GET_OR_RETURN(o, ptr) \ - ELM_CONFORM_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_CONFORM_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_CONFORM_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_CONFORM_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), CONFORM_SMART_NAME, __func__)) \ - return +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (wd->show_region_job) ecore_job_del(wd->show_region_job); + free(wd); +} + +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + edje_object_mirrored_set(wd->base, rtl); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->base, "conformant", "base", + elm_widget_style_get(obj)); + _swallow_conformant_parts(obj); + + if (wd->content) + edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content); + _sizing_eval(obj); +} + +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + if (part && strcmp(part, "default")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->base, "elm.swallow.content", content); + } + _sizing_eval(obj); +} + +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + + if (part && strcmp(part, "default")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->content; +} + +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + Evas_Object *content; + if (part && strcmp(part, "default")) return NULL; + wd = elm_widget_data_get(obj); + if ((!wd) || (!wd->content)) return NULL; + + content = wd->content; + elm_widget_sub_object_del(obj, wd->content); + evas_object_event_callback_del_full(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->base, content); + wd->content = NULL; + return content; +} + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord mw = -1, mh = -1; + if (!wd) return; + + edje_object_size_min_calc(wd->base, &mw, &mh); + evas_object_size_hint_min_set(obj, mw, mh); + evas_object_size_hint_max_set(obj, -1, -1); +} /* Example of env vars: * ILLUME_KBD="0, 0, 800, 301" - * ILLUME_IND="0, 0, 800, 32" - * ILLUME_STK="0, 568, 800, 32" + * ILLUME_IND=0,0,800,32 + * ILLUME_STK="0,568,800,32 */ static Eina_Bool -_conformant_part_geometry_get_from_env(const char *part, - int *sx, - int *sy, - int *sw, - int *sh) +_conformant_part_geometry_env_get(const char *part, int *sx, int *sy, int *sw, int *sh) { const char delimiters[] = " ,;"; char *env_val, *token; @@ -135,12 +236,8 @@ _conformant_part_geometry_get_from_env(const char *part, } static void -_conformant_part_size_hints_set(Evas_Object *obj, - Evas_Object *sobj, - Evas_Coord sx, - Evas_Coord sy, - Evas_Coord sw, - Evas_Coord sh) +_conformant_part_size_set(Evas_Object *obj, Evas_Object *sobj, Evas_Coord sx, + Evas_Coord sy, Evas_Coord sw, Evas_Coord sh) { Evas_Coord cx, cy, cw, ch; Evas_Coord part_height = 0, part_width = 0; @@ -149,7 +246,7 @@ _conformant_part_size_hints_set(Evas_Object *obj, /* Part overlapping with conformant */ if ((cx < (sx + sw)) && ((cx + cw) > sx) - && (cy < (sy + sh)) && ((cy + ch) > sy)) + && (cy < (sy + sh)) && ((cy + ch) > sy)) { part_height = MIN((cy + ch), (sy + sh)) - MAX(cy, sy); part_width = MIN((cx + cw), (sx + sw)) - MAX(cx, sx); @@ -160,248 +257,270 @@ _conformant_part_size_hints_set(Evas_Object *obj, } static void -_conformant_part_sizing_eval(Evas_Object *obj, - Conformant_Part_Type part_type) +_conformant_part_sizing_eval(Evas_Object *obj, Conformant_Part_Type part_type) { #ifdef HAVE_ELEMENTARY_X Ecore_X_Window zone = 0; Evas_Object *top; #endif - int sx = -1, sy = -1, sw = -1, sh = -1; Ecore_X_Window xwin; - - ELM_CONFORM_DATA_GET(obj, sd); + int sx = -1, sy = -1, sw = -1, sh = -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; #ifdef HAVE_ELEMENTARY_X top = elm_widget_top_get(obj); xwin = elm_win_xwindow_get(top); - if (xwin) zone = ecore_x_e_illume_zone_get(xwin); #endif if (part_type & ELM_CONFORM_INDICATOR_PART) { - if ((!_conformant_part_geometry_get_from_env - ("ILLUME_IND", &sx, &sy, &sw, &sh)) && (xwin)) + if ((!_conformant_part_geometry_env_get("ILLUME_IND", + &sx, &sy, &sw, &sh)) && (xwin)) { #ifdef HAVE_ELEMENTARY_X - //No information of the indicator geometry, reset the geometry. - if (!ecore_x_e_illume_indicator_geometry_get - (zone, &sx, &sy, &sw, &sh)) + //No information of the indicator geometry, reset the geometry. + if (!ecore_x_e_illume_indicator_geometry_get(zone, &sx, &sy, &sw, &sh)) sx = sy = sw = sh = 0; #else ; #endif } - _conformant_part_size_hints_set(obj, sd->indicator, sx, sy, sw, sh); + _conformant_part_size_set(obj, wd->indicator, sx, sy, sw, sh); } - if (part_type & ELM_CONFORM_VIRTUAL_KEYPAD_PART) { - if ((!_conformant_part_geometry_get_from_env - ("ILLUME_KBD", &sx, &sy, &sw, &sh)) && (xwin)) + if ((!_conformant_part_geometry_env_get("ILLUME_KBD", + &sx, &sy, &sw, &sh)) && (xwin)) { #ifdef HAVE_ELEMENTARY_X - //No information of the keyboard geometry, reset the geometry. - if (!ecore_x_e_illume_keyboard_geometry_get - (zone, &sx, &sy, &sw, &sh)) - sx = sy = sw = sh = 0; + //No information of the keyboard geometry, reset the geometry. + if (!ecore_x_e_illume_keyboard_geometry_get(zone, &sx, &sy, &sw, &sh)) + sx = sy = sw = sh = 0; #else ; #endif } - _conformant_part_size_hints_set - (obj, sd->virtualkeypad, sx, sy, sw, sh); + _conformant_part_size_set(obj, wd->virtualkeypad, sx, sy, sw, sh); } - if (part_type & ELM_CONFORM_SOFTKEY_PART) { - if ((!_conformant_part_geometry_get_from_env - ("ILLUME_STK", &sx, &sy, &sw, &sh)) && (xwin)) + if ((!_conformant_part_geometry_env_get("ILLUME_STK", + &sx, &sy, &sw, &sh)) && (xwin)) { #ifdef HAVE_ELEMENTARY_X - //No information of the softkey geometry, reset the geometry. - if (!ecore_x_e_illume_softkey_geometry_get - (zone, &sx, &sy, &sw, &sh)) - sx = sy = sw = sh = 0; + //No information of the softkey geometry, reset the geometry. + if (!ecore_x_e_illume_softkey_geometry_get(zone, &sx, &sy, &sw, &sh)) + sx = sy = sw = sh = 0; #else ; #endif } - _conformant_part_size_hints_set(obj, sd->softkey, sx, sy, sw, sh); + _conformant_part_size_set(obj, wd->softkey, sx, sy, sw, sh); } if (part_type & ELM_CONFORM_CLIPBOARD_PART) { - if ((!_conformant_part_geometry_get_from_env - ("ILLUME_CB", &sx, &sy, &sw, &sh)) && (xwin)) + if ((!_conformant_part_geometry_env_get("ILLUME_CB", + &sx, &sy, &sw, &sh)) && (xwin)) { #ifdef HAVE_ELEMENTARY_X - //No information of the clipboard geometry, reset the geometry. - if (!ecore_x_e_illume_clipboard_geometry_get - (zone, &sx, &sy, &sw, &sh)) - sx = sy = sw = sh = 0; + //No information of the clipboard geometry, reset the geometry. + if (!ecore_x_e_illume_clipboard_geometry_get(zone, &sx, &sy, &sw, &sh)) + sx = sy = sw = sh = 0; #else ; #endif } - _conformant_part_size_hints_set(obj, sd->clipboard, sx, sy, sw, sh); + _conformant_part_size_set(obj, wd->clipboard, sx, sy, sw, sh); } } static void -_conformant_parts_swallow(Evas_Object *obj) +_swallow_conformant_parts(Evas_Object *obj) { - Evas *e; - - ELM_CONFORM_DATA_GET(obj, sd); - - e = evas_object_evas_get(obj); + Widget_Data *wd = elm_widget_data_get(obj); + Evas *e = evas_object_evas_get(obj); + if (!wd || !e) return; - sd->scroller = NULL; + wd->scroller = NULL; //Indicator - if (!sd->indicator) + if (!wd->indicator) { - sd->indicator = evas_object_rectangle_add(e); - evas_object_size_hint_min_set(sd->indicator, -1, 0); - evas_object_size_hint_max_set(sd->indicator, -1, 0); + wd->indicator = evas_object_rectangle_add(e); + elm_widget_sub_object_add(obj, wd->indicator); + evas_object_size_hint_min_set(wd->indicator, -1, 0); + evas_object_size_hint_max_set(wd->indicator, -1, 0); } else _conformant_part_sizing_eval(obj, ELM_CONFORM_INDICATOR_PART); - - evas_object_color_set(sd->indicator, 0, 0, 0, 0); - elm_layout_content_set(obj, "elm.swallow.indicator", sd->indicator); + evas_object_color_set(wd->indicator, 0, 0, 0, 0); + edje_object_part_swallow(wd->base, "elm.swallow.indicator", wd->indicator); //Virtual Keyboard - if (!sd->virtualkeypad) + if (!wd->virtualkeypad) { - sd->virtualkeypad = evas_object_rectangle_add(e); - elm_widget_sub_object_add(obj, sd->virtualkeypad); - evas_object_size_hint_max_set(sd->virtualkeypad, -1, 0); + wd->virtualkeypad = evas_object_rectangle_add(e); + elm_widget_sub_object_add(obj, wd->virtualkeypad); + evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0); + evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0); } else _conformant_part_sizing_eval(obj, ELM_CONFORM_VIRTUAL_KEYPAD_PART); - - evas_object_color_set(sd->virtualkeypad, 0, 0, 0, 0); - elm_layout_content_set(obj, "elm.swallow.virtualkeypad", sd->virtualkeypad); - + evas_object_color_set(wd->virtualkeypad, 0, 0, 0, 0); + edje_object_part_swallow(wd->base, "elm.swallow.virtualkeypad", + wd->virtualkeypad); //Clipboard - if (!sd->clipboard) + if (!wd->clipboard) { - sd->clipboard = evas_object_rectangle_add(e); - evas_object_size_hint_min_set(sd->clipboard, -1, 0); - evas_object_size_hint_max_set(sd->clipboard, -1, 0); + wd->clipboard = evas_object_rectangle_add(e); + elm_widget_sub_object_add(obj, wd->clipboard); + evas_object_size_hint_min_set(wd->clipboard, -1, 0); + evas_object_size_hint_max_set(wd->clipboard, -1, 0); } else _conformant_part_sizing_eval(obj, ELM_CONFORM_CLIPBOARD_PART); - - evas_object_color_set(sd->clipboard, 0, 0, 0, 0); - elm_layout_content_set(obj, "elm.swallow.clipboard", sd->clipboard); + evas_object_color_set(wd->clipboard, 0, 0, 0, 0); + edje_object_part_swallow(wd->base, "elm.swallow.clipboard", + wd->clipboard); //Softkey - if (!sd->softkey) + if (!wd->softkey) { - sd->softkey = evas_object_rectangle_add(e); - evas_object_size_hint_min_set(sd->softkey, -1, 0); - evas_object_size_hint_max_set(sd->softkey, -1, 0); + wd->softkey = evas_object_rectangle_add(e); + elm_widget_sub_object_add(obj, wd->softkey); + evas_object_size_hint_min_set(wd->softkey, -1, 0); + evas_object_size_hint_max_set(wd->softkey, -1, 0); } else _conformant_part_sizing_eval(obj, ELM_CONFORM_SOFTKEY_PART); - - evas_object_color_set(sd->softkey, 0, 0, 0, 0); - elm_layout_content_set(obj, "elm.swallow.softkey", sd->softkey); + evas_object_color_set(wd->softkey, 0, 0, 0, 0); + edje_object_part_swallow(wd->base, "elm.swallow.softkey", wd->softkey); } -static Eina_Bool -_elm_conform_smart_theme(Evas_Object *obj) +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { - if (!ELM_WIDGET_CLASS(_elm_conform_parent_sc)->theme(obj)) - return EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - _conformant_parts_swallow(obj); + _sizing_eval(data); +} - elm_layout_sizing_eval(obj); +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; - return EINA_TRUE; + if (sub == wd->content) + { + evas_object_event_callback_del_full(sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->content = NULL; + _sizing_eval(obj); + } } -// unused now - but meant to be for making sure the focused widget is always -// visible when the vkbd comes and goes by moving the conformant obj (and thus -// its children) to show the focused widget (and if focus changes follow) -/* - static Evas_Object * - _focus_object_get(const Evas_Object *obj) - { +/* unused now - but meant to be for making sure the focused widget is always + * visible when the vkbd comes and goes by moving the conformant obj (and thus + * its children) to show the focused widget (and if focus changes follow) + +static Evas_Object * +_focus_object_get(const Evas_Object *obj) +{ Evas_Object *win, *foc; win = elm_widget_top_get(obj); if (!win) return NULL; foc = elm_widget_top_get(win); - } +} - static void - _focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) - { +static void +_focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) +{ evas_object_geometry_get(obj, x, y, w, h); - } +} - static void - _focus_change_del(void *data, Evas_Object *obj, void *event_info) - { +static void +_focus_change_del(void *data, Evas_Object *obj, void *event_info) +{ // called from toplevel when the focused window shanges - } +} - static void - _autoscroll_move(Evas_Object *obj) - { +static void +_autoscroll_move(Evas_Object *obj) +{ // move conformant edje by delta to show focused widget - } +} - static void - _autoscroll_mode_enable(Evas_Object *obj) - { - // called when autoscroll mode should be on - content area smaller than - // its min size - // 1. get focused object - // 2. if not in visible conformant area calculate delta needed to - // get it in - // 3. store delta and call _autoscroll_move() which either asanimates - // or jumps right there - } - - static void - _autoscroll_mode_disable(Evas_Object *obj) - { - // called when autoscroll mode should be off - set delta to 0 and - // call _autoscroll_move() - } +static void +_autoscroll_mode_enable(Evas_Object *obj) +{ +// called when autoscroll mode should be on - content area smaller than +// its min size +// 1. get focused object +// 2. if not in visible conformant area calculate delta needed to +// get it in +// 3. store delta and call _autoscroll_move() which either asanimates +// or jumps right there +} + +static void +_autoscroll_mode_disable(Evas_Object *obj) +{ +// called when autoscroll mode should be off - set delta to 0 and +// call _autoscroll_move() +} */ static void -_move_resize_cb(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_conformant_move_resize_event_cb(void *data __UNUSED__, Evas *e __UNUSED__, + Evas_Object *obj, void *event_info __UNUSED__) { Conformant_Part_Type part_type; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - part_type = (ELM_CONFORM_INDICATOR_PART | - ELM_CONFORM_SOFTKEY_PART | - ELM_CONFORM_VIRTUAL_KEYPAD_PART | - ELM_CONFORM_CLIPBOARD_PART); - + part_type = (ELM_CONFORM_INDICATOR_PART | + ELM_CONFORM_SOFTKEY_PART | + ELM_CONFORM_VIRTUAL_KEYPAD_PART | + ELM_CONFORM_CLIPBOARD_PART); _conformant_part_sizing_eval(obj, part_type); } +// showing the focused/important region. +#ifdef HAVE_ELEMENTARY_X +static void +_content_resize_event_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj + __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *conformant = (Evas_Object *)data; + Widget_Data *wd = elm_widget_data_get(conformant); + if (!wd) return; + + if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) return; + + if (wd->show_region_job) ecore_job_del(wd->show_region_job); + wd->show_region_job = ecore_job_add(_show_region_job, conformant); +} +#endif + static void _show_region_job(void *data) { Evas_Object *focus_obj; + Evas_Object *conformant = (Evas_Object *)data; + Widget_Data *wd = elm_widget_data_get(conformant); + if (!wd) return; - ELM_CONFORM_DATA_GET(data, sd); - - focus_obj = elm_widget_focused_object_get(data); + focus_obj = elm_widget_focused_object_get(conformant); if (focus_obj) { Evas_Coord x, y, w, h; @@ -414,46 +533,27 @@ _show_region_job(void *data) elm_widget_show_region_set(focus_obj, x, y, w, h, EINA_TRUE); } - sd->show_region_job = NULL; + wd->show_region_job = NULL; } -// showing the focused/important region. -#ifdef HAVE_ELEMENTARY_X -static void -_on_content_resize(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - ELM_CONFORM_DATA_GET(data, sd); - - if (sd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) return; - - if (sd->show_region_job) ecore_job_del(sd->show_region_job); - sd->show_region_job = ecore_job_add(_show_region_job, data); -} - -#endif - #ifdef HAVE_ELEMENTARY_X static void -_autoscroll_objects_update(void *data) +_update_autoscroll_objs(void *data) { - int i; const char *type; + int i; Evas_Object *sub, *top_scroller = NULL; + Evas_Object *conformant = (Evas_Object *)data; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - ELM_CONFORM_DATA_GET(data, sd); - - sub = elm_widget_focused_object_get(data); - //Look up for top most scroller in the focus object hierarchy - //inside Conformant. + sub = elm_widget_focused_object_get(conformant); + //Look up for Top most scroller in the Focus Object hierarchy inside Conformant. while (sub) { type = elm_widget_type_get(sub); - if (!strcmp(type, CONFORM_SMART_NAME)) break; - + if (!strcmp(type, "conformant")) break; for (i = 0; i < SUB_TYPE_COUNT; i++) if (!strcmp(type, sub_type[i])) { @@ -464,37 +564,35 @@ _autoscroll_objects_update(void *data) } //If the scroller got changed by app, replace it. - if (top_scroller != sd->scroller) + if (top_scroller != wd->scroller) { - if (sd->scroller) - evas_object_event_callback_del - (sd->scroller, EVAS_CALLBACK_RESIZE, _on_content_resize); - sd->scroller = top_scroller; - - if (sd->scroller) - evas_object_event_callback_add - (sd->scroller, EVAS_CALLBACK_RESIZE, _on_content_resize, data); + if (wd->scroller) evas_object_event_callback_del(wd->scroller, + EVAS_CALLBACK_RESIZE, + _content_resize_event_cb); + wd->scroller = top_scroller; + if (wd->scroller) evas_object_event_callback_add(wd->scroller, + EVAS_CALLBACK_RESIZE, + _content_resize_event_cb, + data); } } static Eina_Bool -_on_prop_change(void *data, - int type __UNUSED__, - void *event) +_prop_change(void *data, int type __UNUSED__, void *event) { - Ecore_X_Event_Window_Property *ev = event; - - ELM_CONFORM_DATA_GET(data, sd); + Ecore_X_Event_Window_Property *ev; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_PASS_ON; + ev = event; if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE) { Conformant_Part_Type part_type; - part_type = (ELM_CONFORM_INDICATOR_PART | - ELM_CONFORM_SOFTKEY_PART | - ELM_CONFORM_VIRTUAL_KEYPAD_PART | - ELM_CONFORM_CLIPBOARD_PART); - + part_type = (ELM_CONFORM_INDICATOR_PART | + ELM_CONFORM_SOFTKEY_PART | + ELM_CONFORM_VIRTUAL_KEYPAD_PART | + ELM_CONFORM_CLIPBOARD_PART); _conformant_part_sizing_eval(data, part_type); } else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY) @@ -509,15 +607,16 @@ _on_prop_change(void *data, { Ecore_X_Window zone; - DBG("Keyboard Geometry Changed\n"); + printf("Keyboard Geometry Changed\n"); zone = ecore_x_e_illume_zone_get(ev->win); - sd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone); - if (sd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) + wd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone); + if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) { - evas_object_size_hint_min_set(sd->virtualkeypad, -1, 0); - evas_object_size_hint_max_set(sd->virtualkeypad, -1, 0); + evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0); + evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0); } - else _autoscroll_objects_update(data); + else + _update_autoscroll_objs(data); } else if (ev->atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE) { @@ -529,73 +628,43 @@ _on_prop_change(void *data, if (state != ECORE_X_ILLUME_CLIPBOARD_STATE_ON) { - evas_object_size_hint_min_set(sd->clipboard, -1, 0); - evas_object_size_hint_max_set(sd->clipboard, -1, 0); + evas_object_size_hint_min_set(wd->clipboard, -1, 0); + evas_object_size_hint_max_set(wd->clipboard, -1, 0); } - else _autoscroll_objects_update(data); + else + _update_autoscroll_objs(data); } return ECORE_CALLBACK_PASS_ON; } - -#endif - -static void -_elm_conform_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Conform_Smart_Data); - - ELM_WIDGET_CLASS(_elm_conform_parent_sc)->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); - - elm_layout_theme_set(obj, "conformant", "base", elm_widget_style_get(obj)); - - _conformant_parts_swallow(obj); -} - -static void -_elm_conform_smart_del(Evas_Object *obj) -{ - ELM_CONFORM_DATA_GET(obj, sd); - -#ifdef HAVE_ELEMENTARY_X - if (sd->prop_hdl) ecore_event_handler_del(sd->prop_hdl); #endif - if (sd->show_region_job) ecore_job_del(sd->show_region_job); - - ELM_WIDGET_CLASS(_elm_conform_parent_sc)->base.del(obj); -} - -static void -_elm_conform_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_conform_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_conform_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_conform_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->content_aliases = _content_aliases; -} - EAPI Evas_Object * elm_conformant_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - e = evas_object_evas_get(parent); - if (!e) return NULL; + ELM_SET_WIDTYPE(widtype, "conformant"); + elm_widget_type_set(obj, "conformant"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); - obj = evas_object_smart_add(e, _elm_conform_smart_class_new()); + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "conformant", "base", "default"); + elm_widget_resize_object_set(obj, wd->base); - /* NB: we got to sub-object-add before we probe for the top widget */ - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + _swallow_conformant_parts(obj); #ifdef HAVE_ELEMENTARY_X Evas_Object *top = elm_widget_top_get(obj); @@ -603,21 +672,21 @@ elm_conformant_add(Evas_Object *parent) if ((xwin) && (!elm_win_inlined_image_object_get(top))) { - ELM_CONFORM_DATA_GET(obj, sd); - - sd->prop_hdl = ecore_event_handler_add - (ECORE_X_EVENT_WINDOW_PROPERTY, _on_prop_change, obj); - sd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF; + wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _prop_change, obj); + wd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF; } // FIXME: get kbd region prop #endif - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESIZE, _move_resize_cb, obj); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_MOVE, _move_resize_cb, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, + _conformant_move_resize_event_cb, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, + _conformant_move_resize_event_cb, obj); - elm_layout_sizing_eval(obj); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } diff --git a/src/lib/elm_conform.h b/src/lib/elm_conform.h index a1a9792f8..3daf72a3e 100644 --- a/src/lib/elm_conform.h +++ b/src/lib/elm_conform.h @@ -16,11 +16,6 @@ * space required for such stuff, and when they popup, as a keyboard * shows when an entry is selected, conformant content won't change. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for conformant objects. - * - * This widget emits the same signals sent from @ref Layout: - * * Available styles for it: * - @c "default" * diff --git a/src/lib/elm_container.c b/src/lib/elm_container.c deleted file mode 100644 index d8e91df04..000000000 --- a/src/lib/elm_container.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <Elementary.h> -#include "elm_priv.h" -#include "elm_widget_container.h" - -static const char CONTAINER_SMART_NAME[] = "elm_container"; - -/* Elementary smart class for all widgets containing others */ -EVAS_SMART_SUBCLASS_NEW - (CONTAINER_SMART_NAME, _elm_container, Elm_Container_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL); - -/* no *direct* instantiation of this class, so far */ -__UNUSED__ static Evas_Smart *_elm_container_smart_class_new(void); - -static Eina_Bool -_unimplemented_smart_content_set(Evas_Object *obj, - const char *name __UNUSED__, - Evas_Object *content __UNUSED__) -{ - WRN("The %s widget does not implement the \"content_set()\" function.", - elm_widget_type_get(obj)); - - return EINA_FALSE; -} - -static Evas_Object * -_unimplemented_smart_content_get(const Evas_Object *obj, - const char *name __UNUSED__) -{ - WRN("The %s widget does not implement the \"content_get()\" function.", - elm_widget_type_get(obj)); - - return NULL; -} - -static Evas_Object * -_unimplemented_smart_content_unset(Evas_Object *obj, - const char *name __UNUSED__) -{ - WRN("The %s widunset does not implement the \"content_unset()\" function.", - elm_widget_type_get(obj)); - - return NULL; -} - -EAPI const Elm_Container_Smart_Class * -elm_container_smart_class_get(void) -{ - static Elm_Container_Smart_Class _sc = - ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(CONTAINER_SMART_NAME); - static const Elm_Container_Smart_Class *class = NULL; - - if (class) - return class; - - _elm_container_smart_set(&_sc); - class = &_sc; - - return class; -} - -static void -_elm_container_smart_set_user(Elm_Container_Smart_Class *sc) -{ - sc->content_set = _unimplemented_smart_content_set; - sc->content_get = _unimplemented_smart_content_get; - sc->content_unset = _unimplemented_smart_content_unset; -} diff --git a/src/lib/elm_datetime.c b/src/lib/elm_datetime.c index 52ad9e17b..8736e8dec 100644 --- a/src/lib/elm_datetime.c +++ b/src/lib/elm_datetime.c @@ -1,6 +1,5 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" #ifdef HAVE_LOCALE_H # include <locale.h> @@ -10,462 +9,217 @@ # include <langinfo.h> #endif -static const char DATETIME_SMART_NAME[] = "elm_datetime"; - -typedef struct _Elm_Datetime_Smart_Data Elm_Datetime_Smart_Data; -typedef struct _Datetime_Field Datetime_Field; -typedef struct _Datetime_Mod_Api Datetime_Mod_Api; -typedef struct _Format_Map Format_Map; - -#define DATETIME_TYPE_COUNT 6 -#define MAX_FORMAT_LEN 64 -#define MAX_SEPARATOR_LEN 6 -#define MAX_FIELD_FORMAT_LEN 3 -#define MIN_DAYS_IN_MONTH 28 -#define BUFFER_SIZE 1024 - -/* interface between EDC & C code (field & signal names). values 0 to - * DATETIME_TYPE_COUNT are in the valid range, and must get in the - * place of "%d". - */ -#define EDC_DATETIME_FOCUSIN_SIG_STR "elm,action,focus" -#define EDC_DATETIME_FOCUSOUT_SIG_STR "elm,action,unfocus" -#define EDC_PART_FIELD_STR "field%d" -#define EDC_PART_SEPARATOR_STR "separator%d" -#define EDC_PART_FIELD_ENABLE_SIG_STR "field%d,enable" -#define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable" - -/* struct tm does not define the fields in the order year, month, - * date, hour, minute. values are reassigned to an array for easy - * handling. - */ -#define DATETIME_TM_ARRAY(intptr, tmptr) \ - int *intptr[] = { \ - &(tmptr)->tm_year, \ - &(tmptr)->tm_mon, \ - &(tmptr)->tm_mday, \ - &(tmptr)->tm_hour, \ - &(tmptr)->tm_min} +typedef struct _Widget_Data Widget_Data; +typedef struct _Datetime_Field Datetime_Field; +typedef struct _Datetime_Mod_Api Datetime_Mod_Api; +typedef struct _Format_Map Format_Map; + +#define DATETIME_TYPE_COUNT 6 +#define MAX_FORMAT_LEN 64 +#define MAX_SEPARATOR_LEN 6 +#define MAX_FIELD_FORMAT_LEN 3 +#define MIN_DAYS_IN_MONTH 28 +#define BUFFER_SIZE 1024 + +// interface between EDC & C code. Field names & signal names. +// values 0 to DATETIME_TYPE_COUNT are valid range, can be substituted for %d. +#define EDC_DATETIME_ENABLE_SIG_STR "elm,state,enabled" +#define EDC_DATETIME_DISABLE_SIG_STR "elm,state,disabled" +#define EDC_DATETIME_FOCUSIN_SIG_STR "elm,action,focus" +#define EDC_DATETIME_FOCUSOUT_SIG_STR "elm,action,unfocus" +#define EDC_PART_FIELD_STR "field%d" +#define EDC_PART_SEPARATOR_STR "separator%d" +#define EDC_PART_FIELD_ENABLE_SIG_STR "field%d,enable" +#define EDC_PART_FIELD_DISABLE_SIG_STR "field%d,disable" + +// struct tm does not define the fields in the order from year, month, date, hour, minute. +// values are reassigned to an array for easy handling. +#define DATETIME_TM_ARRAY(intptr, tmptr) int *intptr[] = {&(tmptr)->tm_year, \ + &(tmptr)->tm_mon, &(tmptr)->tm_mday, &(tmptr)->tm_hour, &(tmptr)->tm_min} struct _Datetime_Field { - Evas_Object *item_obj; - char fmt[MAX_FIELD_FORMAT_LEN]; + Evas_Object *item_obj; + char fmt[MAX_FIELD_FORMAT_LEN]; Elm_Datetime_Field_Type type; - const char *separator; - int location; /* location of the field as per - * current format */ - int min, max; - Eina_Bool fmt_exist : 1; /* whether field format is - * present or not */ - Eina_Bool visible : 1; /* whether field can be - * visible or not */ + const char *separator; + int location; // location of the field as per the current format + int min, max; + Eina_Bool fmt_exist:1; // whether field format is present or not + Eina_Bool visible:1; // whether field can be visible or not }; struct _Datetime_Mod_Api { - Elm_Datetime_Module_Data *(*obj_hook)(Evas_Object * obj); - void (*obj_unhook)(Elm_Datetime_Module_Data *mdata); - Evas_Object *(*field_create)(Elm_Datetime_Module_Data * mdata, - Elm_Datetime_Field_Type ftype); - void (*field_value_display)(Elm_Datetime_Module_Data - *mdata, - Evas_Object *obj); + Elm_Datetime_Module_Data *(*obj_hook) (Evas_Object *obj); + void (*obj_unhook) (Elm_Datetime_Module_Data *module_data); + Evas_Object *(*field_create) (Elm_Datetime_Module_Data *module_data, + Elm_Datetime_Field_Type field_type); + void (*field_value_display) (Elm_Datetime_Module_Data *module_data, + Evas_Object *obj); }; -struct _Elm_Datetime_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - /* fixed set of fields. */ - Datetime_Field field_list[DATETIME_TYPE_COUNT]; - struct tm curr_time, min_limit, max_limit; + Evas_Object *base; + Datetime_Field field_list[DATETIME_TYPE_COUNT]; // fixed set of fields. + struct tm curr_time, min_limit, max_limit; Elm_Datetime_Module_Data *mod_data; - char format[MAX_FORMAT_LEN]; - Eina_Bool user_format : 1; /* whether user set - * format or default - * format. */ + char format[MAX_FORMAT_LEN]; + Eina_Bool user_format:1; // whether user set format or default format. }; struct _Format_Map { char *fmt_char; - int def_min; - int def_max; + int def_min; + int def_max; char *ignore_sep; }; // default limits for individual fields static Format_Map mapping[DATETIME_TYPE_COUNT] = { - [ELM_DATETIME_YEAR] = { "Yy", -1, -1, "" }, - [ELM_DATETIME_MONTH] = { "mbBh", 0, 11, "" }, - [ELM_DATETIME_DATE] = { "de", 1, 31, "" }, - [ELM_DATETIME_HOUR] = { "IHkl", 0, 23, "" }, - [ELM_DATETIME_MINUTE] = { "M", 0, 59, ":" }, - [ELM_DATETIME_AMPM] = { "pP", 0, 1, "" } + [ELM_DATETIME_YEAR] = { "Yy", -1, -1, "" }, + [ELM_DATETIME_MONTH] = { "mbBh", 0, 11, "" }, + [ELM_DATETIME_DATE] = { "de", 1, 31, "" }, + [ELM_DATETIME_HOUR] = { "IHkl", 0, 23, "" }, + [ELM_DATETIME_MINUTE] = { "M", 0, 59, ":" }, + [ELM_DATETIME_AMPM] = { "pP", 0, 1, "" } }; static const char *multifield_formats = "cxXrRTDF"; static const char *ignore_separators = "()"; -static Datetime_Mod_Api *dt_mod = NULL; -#define ELM_DATETIME_DATA_GET(o, sd) \ - Elm_Datetime_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_DATETIME_DATA_GET_OR_RETURN(o, ptr) \ - ELM_DATETIME_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_DATETIME_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_DATETIME_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_DATETIME_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), DATETIME_SMART_NAME, __func__)) \ - return +static Datetime_Mod_Api *dt_mod = NULL; +static const char *widtype = NULL; + +static void _del_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _translate_hook(Evas_Object *obj); +static void _on_focus_hook(void *data __UNUSED__, Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _sizing_eval(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _validate_datetime_limits(struct tm *time1, struct tm *time2, Eina_Bool swap); +static void _apply_field_limits(Evas_Object *obj); +static void _apply_range_restrictions(Evas_Object *obj, struct tm *time); +static const char *_field_format_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type); +static void _field_limit_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type, + int *range_min, int *range_max); +static void _reload_format(Evas_Object *obj); +static void _field_list_display(Evas_Object *obj); +static void _field_list_arrange(Evas_Object *obj); +static void _field_list_init(Evas_Object *obj); static const char SIG_CHANGED[] = "changed"; static const char SIG_LANGUAGE_CHANGED[] = "language,changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHANGED, ""}, - {SIG_LANGUAGE_CHANGED, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHANGED, ""}, + {SIG_LANGUAGE_CHANGED, ""}, + {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (DATETIME_SMART_NAME, _elm_datetime, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static Datetime_Mod_Api * _dt_mod_init() { Elm_Module *mod = NULL; - if (!(mod = _elm_module_find_as("datetime/api"))) return NULL; mod->api = malloc(sizeof(Datetime_Mod_Api)); if (!mod->api) return NULL; - ((Datetime_Mod_Api *)(mod->api))->obj_hook = - _elm_module_symbol_get(mod, "obj_hook"); - ((Datetime_Mod_Api *)(mod->api))->obj_unhook = - _elm_module_symbol_get(mod, "obj_unhook"); - ((Datetime_Mod_Api *)(mod->api))->field_create = - _elm_module_symbol_get(mod, "field_create"); - ((Datetime_Mod_Api *)(mod->api))->field_value_display = - _elm_module_symbol_get(mod, "field_value_display"); + ((Datetime_Mod_Api *)(mod->api))->obj_hook = _elm_module_symbol_get(mod, "obj_hook"); + ((Datetime_Mod_Api *)(mod->api))->obj_unhook = _elm_module_symbol_get(mod, "obj_unhook"); + ((Datetime_Mod_Api *)(mod->api))->field_create = _elm_module_symbol_get(mod, "field_create"); + ((Datetime_Mod_Api *)(mod->api))->field_value_display = _elm_module_symbol_get(mod, "field_value_display"); return mod->api; } static void -_field_list_display(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - Datetime_Field *field; - unsigned int idx = 0; + Widget_Data *wd; + Datetime_Field *tmp; + unsigned int idx; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; - if (field->fmt_exist && field->visible) - { - if ((dt_mod) && (dt_mod->field_value_display)) - dt_mod->field_value_display(sd->mod_data, field->item_obj); - } + tmp = wd->field_list + idx; + evas_object_del(tmp->item_obj); + eina_stringshare_del(tmp->separator); } -} - -// FIXME: provide nl_langinfo on Windows if possible -// returns expanded format string for corresponding multi-field format character -static char * -_expanded_fmt_str_get(char ch) -{ - char *exp_fmt = ""; - switch (ch) - { - case 'c': -#ifdef HAVE_LANGINFO_H - exp_fmt = nl_langinfo(D_T_FMT); -#else - exp_fmt = ""; -#endif - break; - case 'x': -#ifdef HAVE_LANGINFO_H - exp_fmt = nl_langinfo(D_FMT); -#else - exp_fmt = ""; -#endif - break; - - case 'X': -#ifdef HAVE_LANGINFO_H - exp_fmt = nl_langinfo(T_FMT); -#else - exp_fmt = ""; -#endif - break; - - case 'r': -#ifdef HAVE_LANGINFO_H - exp_fmt = nl_langinfo(T_FMT_AMPM); -#else - exp_fmt = ""; -#endif - break; - - case 'R': - exp_fmt = "%H:%M"; - break; - - case 'T': - exp_fmt = "%H:%M:%S"; - break; - - case 'D': - exp_fmt = "%m/%d/%y"; - break; - - case 'F': - exp_fmt = "%Y-%m-%d"; - break; - - default: - exp_fmt = ""; - break; - } + if ((dt_mod) && (dt_mod->obj_unhook)) + dt_mod->obj_unhook(wd->mod_data); // module - unhook - return exp_fmt; + free(wd); } static void -_expand_format(char *dt_fmt) +_disable_hook(Evas_Object *obj) { - char *ptr, *expanded_fmt, ch; - unsigned int idx = 0, len = 0; - char buf[MAX_FORMAT_LEN] = {0, }; - Eina_Bool fmt_char = EINA_FALSE; + Widget_Data *wd; - ptr = dt_fmt; - while ((ch = *ptr)) - { - if ((fmt_char) && (strchr(multifield_formats, ch))) - { - /* replace the multi-field format characters with - * corresponding expanded format */ - expanded_fmt = _expanded_fmt_str_get(ch); - len = strlen(expanded_fmt); - buf[--idx] = 0; - strncat(buf, expanded_fmt, len); - idx += len; - } - else buf[idx++] = ch; - - if (ch == '%') fmt_char = EINA_TRUE; - else fmt_char = EINA_FALSE; - - ptr++; - } - - buf[idx] = 0; - strncpy(dt_fmt, buf, MAX_FORMAT_LEN); + wd = elm_widget_data_get(obj); + if (!wd || !wd->base) return; + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->base, EDC_DATETIME_DISABLE_SIG_STR, "elm"); + else + edje_object_signal_emit(wd->base, EDC_DATETIME_ENABLE_SIG_STR, "elm"); } static void -_field_list_arrange(Evas_Object *obj) -{ - Datetime_Field *field; - char buf[BUFFER_SIZE]; - int idx; - - ELM_DATETIME_DATA_GET(obj, sd); - - for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) - { - field = sd->field_list + idx; - snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location); - - if (field->visible && field->fmt_exist) - elm_layout_content_set(obj, buf, field->item_obj); - else - evas_object_hide(elm_layout_content_unset(obj, buf)); - } - - elm_layout_sizing_eval(obj); - _field_list_display(obj); -} - -static unsigned int -_parse_format(Evas_Object *obj, - char *fmt_ptr) +_translate_hook(Evas_Object *obj) { - Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE, - sep_lookup = EINA_FALSE; - unsigned int len = 0, idx = 0, location = 0; - char separator[MAX_SEPARATOR_LEN]; - Datetime_Field *field = NULL; - char cur; - - ELM_DATETIME_DATA_GET(obj, sd); + Widget_Data *wd; + wd = elm_widget_data_get(obj); + if (!wd) return; - while ((cur = *fmt_ptr)) - { - if (fmt_parsing) - { - fmt_parsing = EINA_FALSE; - for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) - { - if (strchr(mapping[idx].fmt_char, cur)) - { - field = sd->field_list + idx; - /* ignore the fields already have or disabled - * valid formats, means already parsed & - * repeated, ignore. */ - if (!field->visible || field->location != -1) break; - field->fmt[1] = cur; - field->fmt_exist = EINA_TRUE; - field->location = location++; - sep_lookup = EINA_TRUE; - len = 0; - break; - } - } - } - if (cur == '%') - { - fmt_parsing = EINA_TRUE; - sep_parsing = EINA_FALSE; - // set the separator to previous field - separator[len] = 0; - if (field) eina_stringshare_replace(&field->separator, separator); - } - // ignore the set of chars (global, field specific) as field separators - if (sep_parsing && - (len < MAX_SEPARATOR_LEN - 1) && - (field->type != ELM_DATETIME_AMPM) && - (!strchr(ignore_separators, cur)) && - (!strchr(mapping[idx].ignore_sep, cur))) - separator[len++] = cur; - if (sep_lookup) sep_parsing = EINA_TRUE; - sep_lookup = EINA_FALSE; - fmt_ptr++; - } - // return the number of valid fields parsed. - return location; + if (!wd->user_format) _reload_format(obj); + else _field_list_display(obj); + evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL); } static void -_reload_format(Evas_Object *obj) +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - unsigned int idx, field_count; - Datetime_Field *field; - char buf[BUFFER_SIZE]; - char *dt_fmt; - - ELM_DATETIME_DATA_GET(obj, sd); + Widget_Data *wd; - // FIXME: provide nl_langinfo on Windows if possible - // fetch the default format from Libc. - if (!sd->user_format) -#ifdef HAVE_LANGINFO_H - strncpy(sd->format, nl_langinfo(D_T_FMT), MAX_FORMAT_LEN); -#else - strncpy(sd->format, "", MAX_FORMAT_LEN); -#endif + wd = elm_widget_data_get(obj); + if (!wd) return; - dt_fmt = (char *)malloc(MAX_FORMAT_LEN); - if (!dt_fmt) return; - - strncpy(dt_fmt, sd->format, MAX_FORMAT_LEN); - - _expand_format(dt_fmt); - - // reset all the fields to disable state - for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) - { - field = sd->field_list + idx; - field->fmt_exist = EINA_FALSE; - field->location = -1; - } - - field_count = _parse_format(obj, dt_fmt); - free(dt_fmt); - - // assign locations to disabled fields for uniform usage - for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) - { - field = sd->field_list + idx; - if (field->location == -1) field->location = field_count++; - - if (field->fmt_exist && field->visible) - { - snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, - field->location); - elm_layout_signal_emit(obj, buf, "elm"); - } - else - { - snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR, - field->location); - elm_layout_signal_emit(obj, buf, "elm"); - } - snprintf - (buf, sizeof(buf), EDC_PART_SEPARATOR_STR, (field->location + 1)); - elm_layout_text_set(obj, buf, field->separator); - } - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - _field_list_arrange(obj); -} - -static Eina_Bool -_elm_datetime_smart_translate(Evas_Object *obj) -{ - ELM_DATETIME_DATA_GET(obj, sd); - - if (!sd->user_format) _reload_format(obj); - else _field_list_display(obj); - - evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL); - - return EINA_TRUE; + if (elm_widget_focus_get(obj)) + edje_object_signal_emit(wd->base, EDC_DATETIME_FOCUSIN_SIG_STR, "elm"); + else + edje_object_signal_emit(wd->base, EDC_DATETIME_FOCUSOUT_SIG_STR, "elm"); } static Eina_List * _datetime_items_get(const Evas_Object *obj) { + Widget_Data *wd; Eina_List *items = NULL; Datetime_Field *field; int loc, count = 0; unsigned int idx; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; + field = wd->field_list + idx; if (field->fmt_exist && field->visible) count++; } for (loc = 0; loc < count; loc++) { for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; + field = wd->field_list + idx; if (field->location == loc) items = eina_list_append(items, field->item_obj); } @@ -475,14 +229,16 @@ _datetime_items_get(const Evas_Object *obj) } static Eina_Bool -_elm_datetime_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_datetime_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - Eina_Bool ret; + Widget_Data *wd; const Eina_List *items; - Eina_List *(*list_free)(Eina_List *list); - void *(*list_data_get)(const Eina_List *list); + void *(*list_data_get) (const Eina_List *list); + Eina_List *(*list_free) (Eina_List *list); + Eina_Bool ret; + + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; if ((items = elm_widget_focus_custom_chain_get(obj))) { @@ -504,73 +260,86 @@ _elm_datetime_smart_focus_next(const Evas_Object *obj, } static void -_elm_datetime_smart_sizing_eval(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return; + + edje_object_mirrored_set(wd->base, rtl); +} + +static void +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd; Datetime_Field *field; Evas_Coord minw = -1, minh = -1; unsigned int idx, field_count = 0; - ELM_DATETIME_DATA_GET(obj, sd); - + wd = elm_widget_data_get(obj); + if (!wd || !wd->base) return; for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; - if ((field->visible) && (field->fmt_exist)) field_count++; + field = wd->field_list + idx; + if ((field->visible) && (field->fmt_exist)) field_count ++; } if (field_count) elm_coords_finger_size_adjust(field_count, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); } -static Eina_Bool -_elm_datetime_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { + Widget_Data *wd; Datetime_Field *field; char buf[BUFFER_SIZE]; unsigned int idx; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd || !wd->base) return; + + _elm_theme_object_set(obj, wd->base, "datetime", "base", + elm_widget_style_get(obj)); + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); - if (!ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->theme(obj)) - return EINA_FALSE; + edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale); + + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->base, EDC_DATETIME_DISABLE_SIG_STR,"elm"); + else + edje_object_signal_emit(wd->base, EDC_DATETIME_ENABLE_SIG_STR, "elm"); - if ((!dt_mod) || (!dt_mod->field_value_display)) return EINA_TRUE; + if ((!dt_mod) || (!dt_mod->field_value_display)) return; for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; + field = wd->field_list + idx; if (field->fmt_exist && field->visible) { - snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, - field->location); - elm_layout_signal_emit(obj, buf, "elm"); - - snprintf - (buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location); - elm_layout_text_set(obj, buf, field->separator); - - dt_mod->field_value_display(sd->mod_data, field->item_obj); + snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, field->location); + edje_object_signal_emit(wd->base, buf, "elm"); + snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, field->location); + edje_object_part_text_escaped_set(wd->base, buf, field->separator); + dt_mod->field_value_display(wd->mod_data, field->item_obj); } else { - snprintf(buf, sizeof(buf), EDC_PART_FIELD_DISABLE_SIG_STR, - field->location); - elm_layout_signal_emit(obj, buf, "elm"); + snprintf(buf, sizeof(buf),EDC_PART_FIELD_DISABLE_SIG_STR, field->location); + edje_object_signal_emit(wd->base, buf, "elm"); } } - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - elm_layout_sizing_eval(obj); - - return EINA_TRUE; + edje_object_message_signal_process(wd->base); + _sizing_eval(obj); } static int -_max_days_get(int year, - int month) +_max_days_get(int year, int month) { struct tm time1; time_t t; @@ -580,24 +349,20 @@ _max_days_get(int year, localtime_r(&t, &time1); time1.tm_year = year; time1.tm_mon = month; - for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max; - day++) + for (day = MIN_DAYS_IN_MONTH; day <= mapping[ELM_DATETIME_DATE].def_max; day++) { time1.tm_mday = day; mktime(&time1); if (time1.tm_mday == 1) break; } - day--; - + day --; return day; } static Eina_Bool -_date_cmp(struct tm *time1, - struct tm *time2) +_date_cmp(struct tm *time1, struct tm *time2) { unsigned int idx; - DATETIME_TM_ARRAY(timearr1, time1); DATETIME_TM_ARRAY(timearr2, time2); @@ -606,19 +371,15 @@ _date_cmp(struct tm *time1, if (*timearr1[idx] != *timearr2[idx]) return EINA_FALSE; } - return EINA_TRUE; } // validates curr_time/min_limt/max_limit according to the newly set value static void -_validate_datetime_limits(struct tm *time1, - struct tm *time2, - Eina_Bool swap) +_validate_datetime_limits(struct tm *time1, struct tm *time2, Eina_Bool swap) { struct tm *t1, *t2; unsigned int idx; - if (!time1 || !time2) return; t1 = (swap) ? time2 : time1; @@ -628,46 +389,49 @@ _validate_datetime_limits(struct tm *time1, DATETIME_TM_ARRAY(timearr2, time2); for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++) { - if (*timearr1[idx] < *timearr2[idx]) - { - memcpy(t1, t2, sizeof(struct tm)); - break; - } - else if (*timearr1[idx] > *timearr2[idx]) - break; + if (*timearr1[idx] < *timearr2[idx]) + { + memcpy(t1, t2, sizeof(struct tm)); + break; + } + else if (*timearr1[idx] > *timearr2[idx]) + break; } } static void _apply_field_limits(Evas_Object *obj) { + Widget_Data *wd; Datetime_Field *field; - unsigned int idx = 0; int val; + unsigned int idx = 0; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; - DATETIME_TM_ARRAY(timearr, &sd->curr_time); + DATETIME_TM_ARRAY(timearr, &wd->curr_time); for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++) { - field = sd->field_list + idx; + field = wd->field_list + idx; val = *timearr[idx]; if (val < field->min) *timearr[idx] = field->min; else if (val > field->max) *timearr[idx] = field->max; } - _field_list_display(obj); } static void -_apply_range_restrictions(struct tm *tim) +_apply_range_restrictions(Evas_Object *obj, struct tm *tim) { + Widget_Data *wd; unsigned int idx; int val, min, max; - if (!tim) return; + wd = elm_widget_data_get(obj); + if (!wd || !tim) return; DATETIME_TM_ARRAY(timearr, tim); for (idx = ELM_DATETIME_MONTH; idx < DATETIME_TYPE_COUNT - 1; idx++) @@ -685,40 +449,40 @@ _apply_range_restrictions(struct tm *tim) } static const char * -_field_format_get(Evas_Object *obj, - Elm_Datetime_Field_Type field_type) +_field_format_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type) { + Widget_Data *wd; Datetime_Field *field; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; - field = sd->field_list + field_type; + field = wd->field_list + field_type; if (!field) return NULL; return field->fmt; } static void -_field_limit_get(Evas_Object *obj, - Elm_Datetime_Field_Type field_type, - int *range_min, - int *range_max) +_field_limit_get(Evas_Object * obj, Elm_Datetime_Field_Type field_type, int *range_min, int *range_max) { - int min, max, max_days; + Widget_Data *wd; Datetime_Field *field; + int min, max, max_days; unsigned int idx; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; - field = sd->field_list + field_type; + field = wd->field_list + field_type; if (!field) return; min = field->min; max = field->max; - DATETIME_TM_ARRAY(curr_timearr, &sd->curr_time); - DATETIME_TM_ARRAY(min_timearr, &sd->min_limit); - DATETIME_TM_ARRAY(max_timearr, &sd->max_limit); + DATETIME_TM_ARRAY(curr_timearr, &wd->curr_time); + DATETIME_TM_ARRAY(min_timearr, &wd->min_limit); + DATETIME_TM_ARRAY(max_timearr, &wd->max_limit); for (idx = 0; idx < field->type; idx++) if (*curr_timearr[idx] > *min_timearr[idx]) break; @@ -726,7 +490,7 @@ _field_limit_get(Evas_Object *obj, min = *min_timearr[field_type]; if (field_type == ELM_DATETIME_DATE) { - max_days = _max_days_get(sd->curr_time.tm_year, sd->curr_time.tm_mon); + max_days = _max_days_get(wd->curr_time.tm_year, wd->curr_time.tm_mon); if (max > max_days) max = max_days; } for (idx = 0; idx < field->type; idx++) @@ -739,130 +503,348 @@ _field_limit_get(Evas_Object *obj, } static void -_field_list_init(Evas_Object *obj) +_field_list_display(Evas_Object *obj) { + Widget_Data *wd; Datetime_Field *field; - unsigned int idx; - time_t t; + unsigned int idx= 0; - ELM_DATETIME_DATA_GET(obj, sd); - - t = time(NULL); - localtime_r(&t, &sd->curr_time); + wd = elm_widget_data_get(obj); + if (!wd) return; - mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min; - mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max; for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - field = sd->field_list + idx; - field->type = ELM_DATETIME_YEAR + idx; - field->fmt[0] = '%'; - field->fmt_exist = EINA_FALSE; - field->visible = EINA_TRUE; - field->min = mapping[idx].def_min; - field->max = mapping[idx].def_max; - } - DATETIME_TM_ARRAY(min_timearr, &sd->min_limit); - DATETIME_TM_ARRAY(max_timearr, &sd->max_limit); - for (idx = 0; idx < DATETIME_TYPE_COUNT - 1; idx++) - { - *min_timearr[idx] = mapping[idx].def_min; - *max_timearr[idx] = mapping[idx].def_max; + field = wd->field_list + idx; + if (field->fmt_exist && field->visible) + { + if ((dt_mod) && (dt_mod->field_value_display)) + dt_mod->field_value_display(wd->mod_data, field->item_obj); + } } } static void -_elm_datetime_smart_add(Evas_Object *obj) +_field_list_arrange(Evas_Object *obj) { - int idx; + Widget_Data *wd; Datetime_Field *field; + char buf[BUFFER_SIZE]; + int idx; - EVAS_SMART_DATA_ALLOC(obj, Elm_Datetime_Smart_Data); - - ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.add(obj); - - elm_layout_theme_set(obj, "datetime", "base", elm_widget_style_get(obj)); + wd = elm_widget_data_get(obj); + if (!wd) return; - // module - initialise module for datetime - if (!dt_mod) dt_mod = _dt_mod_init(); - if ((dt_mod) && (dt_mod->obj_hook)) priv->mod_data = dt_mod->obj_hook(obj); + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + field = wd->field_list + idx; + edje_object_part_unswallow(wd->base, field->item_obj); + } + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + field = wd->field_list + idx; + if (field->visible && field->fmt_exist) + { + snprintf(buf, sizeof(buf), EDC_PART_FIELD_STR, field->location); + edje_object_part_swallow(wd->base, buf, field->item_obj); + } + else evas_object_hide(field->item_obj); + } + _sizing_eval(obj); + _field_list_display(obj); +} - // update module data - if (priv->mod_data) +// FIXME: provide nl_langinfo on Windows if possible +// returns expanded format string for corresponding multi-field format character +static char * +_expanded_fmt_str_get(char ch) +{ + char *exp_fmt = ""; + switch (ch) { - priv->mod_data->base = obj; - priv->mod_data->field_limit_get = _field_limit_get; - priv->mod_data->field_format_get = _field_format_get; + case 'c': +#ifdef HAVE_LANGINFO_H + exp_fmt = nl_langinfo(D_T_FMT); +#else + exp_fmt = ""; +#endif + break; + case 'x': +#ifdef HAVE_LANGINFO_H + exp_fmt = nl_langinfo(D_FMT); +#else + exp_fmt = ""; +#endif + break; + case 'X': +#ifdef HAVE_LANGINFO_H + exp_fmt = nl_langinfo(T_FMT); +#else + exp_fmt = ""; +#endif + break; + case 'r': +#ifdef HAVE_LANGINFO_H + exp_fmt = nl_langinfo(T_FMT_AMPM); +#else + exp_fmt = ""; +#endif + break; + case 'R': + exp_fmt = "%H:%M"; + break; + case 'T': + exp_fmt = "%H:%M:%S"; + break; + case 'D': + exp_fmt = "%m/%d/%y"; + break; + case 'F': + exp_fmt = "%Y-%m-%d"; + break; + default: + exp_fmt = ""; + break; } + return exp_fmt; +} - _field_list_init(obj); - _reload_format(obj); +static void +_expand_format(char * dt_fmt) +{ + char *ptr, *expanded_fmt, ch; + char buf[MAX_FORMAT_LEN] = {0,}; + unsigned int idx = 0, len = 0; + Eina_Bool fmt_char = EINA_FALSE; - if ((dt_mod) && (dt_mod->field_create)) + ptr = dt_fmt; + while ((ch = *ptr)) { - for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + if ((fmt_char) && (strchr(multifield_formats, ch))) { - field = priv->field_list + idx; - field->item_obj = dt_mod->field_create(priv->mod_data, idx); + // replace the multi-field format characters with corresponding expanded format + expanded_fmt = _expanded_fmt_str_get(ch); + len = strlen(expanded_fmt); + buf[--idx] = 0; + strncat(buf, expanded_fmt, len); + idx += len; } + else buf[idx++] = ch; + if (ch == '%') fmt_char = EINA_TRUE; + else fmt_char = EINA_FALSE; + ptr++; } + buf[idx] = 0; + strncpy(dt_fmt, buf, MAX_FORMAT_LEN); +} - _field_list_arrange(obj); +static unsigned int +_parse_format(Evas_Object *obj, char *fmt_ptr) +{ + Widget_Data *wd; + Datetime_Field *field = NULL; + unsigned int len = 0, idx = 0, location = 0; + char separator[MAX_SEPARATOR_LEN]; + char cur; + Eina_Bool fmt_parsing = EINA_FALSE, sep_parsing = EINA_FALSE, + sep_lookup = EINA_FALSE; - elm_widget_can_focus_set(obj, EINA_TRUE); + wd = elm_widget_data_get(obj); + + while ((cur = *fmt_ptr)) + { + if (fmt_parsing) + { + fmt_parsing = EINA_FALSE; + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + if (strchr(mapping[idx].fmt_char, cur)) + { + field = wd->field_list + idx; + // ignore the fields already have or disabled + // valid formats, means already parsed & repeated, ignore. + if (!field->visible || field->location != -1) break; + field->fmt[1] = cur; + field->fmt_exist = EINA_TRUE; + field->location = location++; + sep_lookup = EINA_TRUE; + len = 0; + break; + } + } + } + if (cur == '%') + { + fmt_parsing = EINA_TRUE; + sep_parsing = EINA_FALSE; + // set the separator to previous field + separator[len] = 0; + if (field) eina_stringshare_replace(&field->separator, separator); + } + + // ignore the set of chars (global, field specific) as field separators. + if (sep_parsing && (len < MAX_SEPARATOR_LEN - 1) && + (field->type != ELM_DATETIME_AMPM) && (!strchr(ignore_separators, cur)) && + (!strchr(mapping[idx].ignore_sep, cur))) + separator[len++] = cur; + if (sep_lookup) sep_parsing = EINA_TRUE; + sep_lookup = EINA_FALSE; + fmt_ptr++; + } + // return the number of valid fields parsed. + return location; } static void -_elm_datetime_smart_del(Evas_Object *obj) +_reload_format(Evas_Object *obj) { - Datetime_Field *tmp; - unsigned int idx; + Widget_Data *wd; + Datetime_Field *field; + char buf[BUFFER_SIZE]; + unsigned int idx, field_count; + char *dt_fmt; - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; + // FIXME: provide nl_langinfo on Windows if possible + // fetch the default format from Libc. + if (!wd->user_format) +#ifdef HAVE_LANGINFO_H + strncpy(wd->format, nl_langinfo(D_T_FMT), MAX_FORMAT_LEN); +#else + strncpy(wd->format, "", MAX_FORMAT_LEN); +#endif + + dt_fmt = (char *)malloc(MAX_FORMAT_LEN); + if (!dt_fmt) return; + strncpy(dt_fmt, wd->format, MAX_FORMAT_LEN); + + _expand_format(dt_fmt); + + // reset all the fields to disable state for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) { - tmp = sd->field_list + idx; - evas_object_del(tmp->item_obj); - eina_stringshare_del(tmp->separator); + field = wd->field_list + idx; + field->fmt_exist = EINA_FALSE; + field->location = -1; } - if ((dt_mod) && (dt_mod->obj_unhook)) - dt_mod->obj_unhook(sd->mod_data); // module - unhook + field_count = _parse_format(obj, dt_fmt); + free(dt_fmt); + + // assign locations to disabled fields for uniform usage + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + field = wd->field_list + idx; + if (field->location == -1) field->location = field_count++; - ELM_WIDGET_CLASS(_elm_datetime_parent_sc)->base.del(obj); + if (field->fmt_exist && field->visible) + { + snprintf(buf, sizeof(buf), EDC_PART_FIELD_ENABLE_SIG_STR, + field->location); + edje_object_signal_emit(wd->base, buf, "elm"); + } + else + { + snprintf(buf, sizeof(buf),EDC_PART_FIELD_DISABLE_SIG_STR, + field->location); + edje_object_signal_emit(wd->base, buf, "elm"); + } + snprintf(buf, sizeof(buf), EDC_PART_SEPARATOR_STR, (field->location + 1)); + edje_object_part_text_escaped_set(wd->base, buf, field->separator); + } + edje_object_message_signal_process(wd->base); + _field_list_arrange(obj); } static void -_elm_datetime_smart_set_user(Elm_Layout_Smart_Class *sc) +_field_list_init(Evas_Object *obj) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_datetime_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_datetime_smart_del; + Widget_Data *wd; + Datetime_Field *field; + unsigned int idx; + time_t t; - ELM_WIDGET_CLASS(sc)->translate = _elm_datetime_smart_translate; - ELM_WIDGET_CLASS(sc)->focus_next = _elm_datetime_smart_focus_next; - ELM_WIDGET_CLASS(sc)->theme = _elm_datetime_smart_theme; + wd = elm_widget_data_get(obj); + if (!wd) return; - sc->sizing_eval = _elm_datetime_smart_sizing_eval; + t = time(NULL); + localtime_r(&t, &wd->curr_time); + + mapping[ELM_DATETIME_YEAR].def_min = _elm_config->year_min; + mapping[ELM_DATETIME_YEAR].def_max = _elm_config->year_max; + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + field = wd->field_list + idx; + field->type = ELM_DATETIME_YEAR + idx; + field->fmt[0] = '%'; + field->fmt_exist = EINA_FALSE; + field->visible = EINA_TRUE; + field->min = mapping[idx].def_min; + field->max = mapping[idx].def_max; + } + DATETIME_TM_ARRAY(min_timearr, &wd->min_limit); + DATETIME_TM_ARRAY(max_timearr, &wd->max_limit); + for (idx = 0; idx < DATETIME_TYPE_COUNT-1; idx++) + { + *min_timearr[idx] = mapping[idx].def_min; + *max_timearr[idx] = mapping[idx].def_max; + } } EAPI Evas_Object * elm_datetime_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + Datetime_Field *field; + int idx; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "datetime"); + elm_widget_type_set(obj, widtype); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_translate_hook_set(obj, _translate_hook); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_focus_next_hook_set(obj, _elm_datetime_focus_next_hook); - e = evas_object_evas_get(parent); - if (!e) return NULL; + wd->base = edje_object_add(e); + elm_widget_resize_object_set(obj, wd->base); + _elm_theme_object_set(obj, wd->base, "datetime", "base", "default"); + evas_object_smart_callbacks_descriptions_set(obj, _signals); - obj = evas_object_smart_add(e, _elm_datetime_smart_class_new()); + // module - initialise module for datetime + if (!dt_mod) dt_mod = _dt_mod_init(); + if ((dt_mod) && (dt_mod->obj_hook)) + wd->mod_data = dt_mod->obj_hook(obj); + // update module data + if (wd->mod_data) + { + wd->mod_data->base = obj; + wd->mod_data->field_limit_get = _field_limit_get; + wd->mod_data->field_format_get = _field_format_get; + } - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + _field_list_init(obj); + _reload_format(obj); - elm_layout_sizing_eval(obj); + if ((dt_mod)&&(dt_mod->field_create)) + { + for (idx = 0; idx < DATETIME_TYPE_COUNT; idx++) + { + field = wd->field_list + idx; + field->item_obj = dt_mod->field_create(wd->mod_data, idx); + } + } + _field_list_arrange(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); return obj; } @@ -870,57 +852,62 @@ elm_datetime_add(Evas_Object *parent) EAPI const char * elm_datetime_format_get(const Evas_Object *obj) { - ELM_DATETIME_CHECK(obj) NULL; - ELM_DATETIME_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return NULL; - return sd->format; + return wd->format; } EAPI void -elm_datetime_format_set(Evas_Object *obj, - const char *fmt) +elm_datetime_format_set(Evas_Object *obj, const char *fmt) { - ELM_DATETIME_CHECK(obj); - ELM_DATETIME_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return; if (fmt) { - strncpy(sd->format, fmt, MAX_FORMAT_LEN); - sd->user_format = EINA_TRUE; + strncpy(wd->format, fmt, MAX_FORMAT_LEN); + wd->user_format = EINA_TRUE; } - else sd->user_format = EINA_FALSE; + else + wd->user_format = EINA_FALSE; _reload_format(obj); } EAPI Eina_Bool -elm_datetime_field_visible_get(const Evas_Object *obj, - Elm_Datetime_Field_Type fieldtype) +elm_datetime_field_visible_get(const Evas_Object *obj, Elm_Datetime_Field_Type + fieldtype) { + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd; Datetime_Field *field; - ELM_DATETIME_CHECK(obj) EINA_FALSE; - ELM_DATETIME_DATA_GET(obj, sd); - - if (fieldtype > ELM_DATETIME_AMPM) return EINA_FALSE; - field = sd->field_list + fieldtype; + wd = elm_widget_data_get(obj); + if (!wd || (fieldtype > ELM_DATETIME_AMPM)) return EINA_FALSE; + field = wd->field_list + fieldtype; return field->visible; } EAPI void -elm_datetime_field_visible_set(Evas_Object *obj, - Elm_Datetime_Field_Type fieldtype, - Eina_Bool visible) +elm_datetime_field_visible_set(Evas_Object *obj, Elm_Datetime_Field_Type fieldtype, + Eina_Bool visible) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; Datetime_Field *field; - ELM_DATETIME_CHECK(obj); - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd || (fieldtype > ELM_DATETIME_AMPM)) return; - if (fieldtype > ELM_DATETIME_AMPM) return; - - field = sd->field_list + fieldtype; + field = wd->field_list + fieldtype; if (field->visible == visible) return; field->visible = visible; @@ -928,155 +915,160 @@ elm_datetime_field_visible_set(Evas_Object *obj, } EAPI void -elm_datetime_field_limit_get(const Evas_Object *obj, - Elm_Datetime_Field_Type fieldtype, - int *min, - int *max) +elm_datetime_field_limit_get(const Evas_Object *obj, Elm_Datetime_Field_Type fieldtype, + int *min, int *max) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; Datetime_Field *field; - ELM_DATETIME_CHECK(obj); - ELM_DATETIME_DATA_GET(obj, sd); - - if (fieldtype >= ELM_DATETIME_AMPM) return; + wd = elm_widget_data_get(obj); + if (!wd || (fieldtype >= ELM_DATETIME_AMPM)) return; - field = sd->field_list + fieldtype; + field = wd->field_list + fieldtype; if (min) *min = field->min; if (max) *max = field->max; } EAPI void -elm_datetime_field_limit_set(Evas_Object *obj, - Elm_Datetime_Field_Type fieldtype, - int min, - int max) +elm_datetime_field_limit_set(Evas_Object *obj, Elm_Datetime_Field_Type fieldtype, + int min, int max) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; Datetime_Field *field; - ELM_DATETIME_CHECK(obj); - ELM_DATETIME_DATA_GET(obj, sd); - - if (fieldtype >= ELM_DATETIME_AMPM) return; + wd = elm_widget_data_get(obj); + if (!wd || (fieldtype >= ELM_DATETIME_AMPM)) return; if (min > max) return; - field = sd->field_list + fieldtype; + field = wd->field_list + fieldtype; if ((min > mapping[fieldtype].def_min && min < mapping[fieldtype].def_max) - || (field->type == ELM_DATETIME_YEAR)) + || (field->type == ELM_DATETIME_YEAR)) field->min = min; if ((max > mapping[fieldtype].def_min && max < mapping[fieldtype].def_max) - || (field->type == ELM_DATETIME_YEAR)) + || (field->type == ELM_DATETIME_YEAR)) field->max = max; _apply_field_limits(obj); } EAPI Eina_Bool -elm_datetime_value_get(const Evas_Object *obj, - struct tm *currtime) +elm_datetime_value_get(const Evas_Object *obj, struct tm *currtime) { - ELM_DATETIME_CHECK(obj) EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(currtime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - *currtime = sd->curr_time; + *currtime = wd->curr_time; return EINA_TRUE; } EAPI Eina_Bool -elm_datetime_value_set(Evas_Object *obj, - const struct tm *newtime) +elm_datetime_value_set(Evas_Object *obj, const struct tm *newtime) { + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE); + Widget_Data *wd; struct tm old_time; - ELM_DATETIME_CHECK(obj) EINA_FALSE; - EINA_SAFETY_ON_NULL_RETURN_VAL(newtime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - old_time = sd->curr_time; - sd->curr_time = *newtime; + old_time = wd->curr_time; + wd->curr_time = *newtime; // apply default field restrictions for curr_time - _apply_range_restrictions(&sd->curr_time); + _apply_range_restrictions(obj, &wd->curr_time); // validate the curr_time according to the min_limt and max_limt - _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE); - _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE); + _validate_datetime_limits(&wd->curr_time, &wd->min_limit, EINA_FALSE); + _validate_datetime_limits(&wd->max_limit, &wd->curr_time, EINA_TRUE); _apply_field_limits(obj); - if (!_date_cmp(&old_time, &sd->curr_time)) + if (!_date_cmp(&old_time, &wd->curr_time)) evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); return EINA_TRUE; } EAPI Eina_Bool -elm_datetime_value_min_get(const Evas_Object *obj, - struct tm *mintime) +elm_datetime_value_min_get(const Evas_Object *obj, struct tm *mintime) { - ELM_DATETIME_CHECK(obj) EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - *mintime = sd->min_limit; + *mintime = wd->min_limit; return EINA_TRUE; } EAPI Eina_Bool -elm_datetime_value_min_set(Evas_Object *obj, - const struct tm *mintime) +elm_datetime_value_min_set(Evas_Object *obj, const struct tm *mintime) { + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE); + Widget_Data *wd; struct tm old_time; - ELM_DATETIME_CHECK(obj) EINA_FALSE; - EINA_SAFETY_ON_NULL_RETURN_VAL(mintime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - sd->min_limit = *mintime; - old_time = sd->curr_time; + wd->min_limit = *mintime; + old_time = wd->curr_time; // apply default field restrictions for min_limit - _apply_range_restrictions(&sd->min_limit); + _apply_range_restrictions(obj, &wd->min_limit); // validate curr_time and max_limt according to the min_limit - _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_FALSE); - _validate_datetime_limits(&sd->curr_time, &sd->min_limit, EINA_FALSE); + _validate_datetime_limits(&wd->max_limit, &wd->min_limit, EINA_FALSE); + _validate_datetime_limits(&wd->curr_time, &wd->min_limit, EINA_FALSE); _apply_field_limits(obj); - if (!_date_cmp(&old_time, &sd->curr_time)) + if (!_date_cmp(&old_time, &wd->curr_time)) evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); return EINA_TRUE; } EAPI Eina_Bool -elm_datetime_value_max_get(const Evas_Object *obj, - struct tm *maxtime) +elm_datetime_value_max_get(const Evas_Object *obj, struct tm *maxtime) { - ELM_DATETIME_CHECK(obj) EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + Widget_Data *wd; - *maxtime = sd->max_limit; + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + + *maxtime = wd->max_limit; return EINA_TRUE; } EAPI Eina_Bool -elm_datetime_value_max_set(Evas_Object *obj, - const struct tm *maxtime) +elm_datetime_value_max_set(Evas_Object *obj, const struct tm *maxtime) { + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE); + Widget_Data *wd; struct tm old_time; - ELM_DATETIME_CHECK(obj) EINA_FALSE; - EINA_SAFETY_ON_NULL_RETURN_VAL(maxtime, EINA_FALSE); - ELM_DATETIME_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - sd->max_limit = *maxtime; - old_time = sd->curr_time; + wd->max_limit = *maxtime; + old_time = wd->curr_time; // apply default field restrictions for max_limit - _apply_range_restrictions(&sd->max_limit); + _apply_range_restrictions(obj, &wd->max_limit); // validate curr_time and min_limt according to the max_limit - _validate_datetime_limits(&sd->max_limit, &sd->min_limit, EINA_TRUE); - _validate_datetime_limits(&sd->max_limit, &sd->curr_time, EINA_TRUE); + _validate_datetime_limits(&wd->max_limit, &wd->min_limit, EINA_TRUE); + _validate_datetime_limits(&wd->max_limit, &wd->curr_time, EINA_TRUE); _apply_field_limits(obj); - if (!_date_cmp(&old_time, &sd->curr_time)) + if (!_date_cmp(&old_time, &wd->curr_time)) evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); return EINA_TRUE; diff --git a/src/lib/elm_datetime.h b/src/lib/elm_datetime.h index c16679d76..36785cb7c 100644 --- a/src/lib/elm_datetime.h +++ b/src/lib/elm_datetime.h @@ -172,16 +172,12 @@ * * <b>export ELM_MODULES="datetime_input_ctxpopup>datetime/api"</b> * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for datetime objects. * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @b "changed" - whenever Datetime field value is changed, this - * signal is sent. + * Datetime widgets emits the following signals: * - * @li @b "language,changed" - whenever system locale changes, this - * signal is sent. + * @li @b "changed" - whenever Datetime field value is changed, this signal is sent. + * + * @li @b "language,changed" - whenever system locale changes, this signal is sent. * * Here is an example on its usage: * @li @ref datetime_example diff --git a/src/lib/elm_dayselector.c b/src/lib/elm_dayselector.c deleted file mode 100644 index 3ee93f1e4..000000000 --- a/src/lib/elm_dayselector.c +++ /dev/null @@ -1,633 +0,0 @@ -#include <Elementary.h> -#include "elm_priv.h" -#include "elm_widget_layout.h" - -static const char DAYSELECTOR_SMART_NAME[] = "elm_dayselector"; - -typedef struct _Elm_Dayselector_Smart_Data Elm_Dayselector_Smart_Data; -typedef struct _Elm_Dayselector_Item Elm_Dayselector_Item; - -/* signals to edc */ -#define ITEM_TYPE_WEEKDAY_DEFAULT "elm,type,weekday,default" -#define ITEM_TYPE_WEEKDAY_STYLE1 "elm,type,weekday,style1" -#define ITEM_TYPE_WEEKEND_DEFAULT "elm,type,weekend,default" -#define ITEM_TYPE_WEEKEND_STYLE1 "elm,type,weekend,style1" -#define ITEM_POS_LEFT "elm,pos,check,left" -#define ITEM_POS_RIGHT "elm,pos,check,right" -#define ITEM_POS_MIDDLE "elm,pos,check,middle" - -struct _Elm_Dayselector_Smart_Data -{ - Elm_Layout_Smart_Data base; - - Eina_List *items; - Elm_Dayselector_Day week_start; - Elm_Dayselector_Day weekend_start; - unsigned int weekend_len; -}; - -struct _Elm_Dayselector_Item -{ - ELM_WIDGET_ITEM; - Elm_Dayselector_Day day; - const char *day_style; -}; - -static const char SIG_CHANGED[] = "dayselector,changed"; -static const char SIG_LANG_CHANGED[] = "language,changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHANGED, ""}, - {SIG_LANG_CHANGED, ""}, - {NULL, NULL} -}; - -#define ELM_DAYSELECTOR_DATA_GET(o, sd) \ - Elm_Dayselector_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_DAYSELECTOR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_DAYSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_DAYSELECTOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_DAYSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_DAYSELECTOR_CHECK(obj) \ - if (!obj || !elm_widget_type_check( \ - (obj), DAYSELECTOR_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (DAYSELECTOR_SMART_NAME, _elm_dayselector, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - -static void -_elm_dayselector_smart_sizing_eval(Evas_Object *obj) -{ - Evas_Coord min_w = -1, min_h = -1; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &min_w, &min_h, min_w, min_h); - elm_coords_finger_size_adjust(ELM_DAYSELECTOR_MAX, &min_w, 1, &min_h); - evas_object_size_hint_min_set(obj, min_w, min_h); -} - -static void -_dayselector_resize(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - elm_layout_sizing_eval(data); -} - -#if 0 -static Eina_Bool -_elm_dayselector_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir __UNUSED__, - Evas_Object **next __UNUSED__) -{ - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - /* TODO: Focus switch support to Elm_widget_Item is not supported yet.*/ - return EINA_FALSE; -} - -#endif - -static Eina_Bool -_elm_dayselector_smart_translate(Evas_Object *obj) -{ - time_t t; - Eina_List *l; - char buf[1024]; - struct tm time_daysel; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - t = time(NULL); - localtime_r(&t, &time_daysel); - EINA_LIST_FOREACH (sd->items, l, it) - { - time_daysel.tm_wday = it->day; - strftime(buf, sizeof(buf), "%a", &time_daysel); - elm_object_text_set(VIEW(it), buf); - } - - evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL); - - return EINA_TRUE; -} - -static void -_update_items(Evas_Object *obj) -{ - Eina_List *l; - Eina_Bool rtl; - unsigned int last_day; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - last_day = sd->week_start + ELM_DAYSELECTOR_MAX - 1; - if (last_day >= ELM_DAYSELECTOR_MAX) - last_day = last_day % ELM_DAYSELECTOR_MAX; - - rtl = elm_widget_mirrored_get(obj); - EINA_LIST_FOREACH (sd->items, l, it) - { - elm_object_signal_emit(VIEW(it), it->day_style, ""); - if (it->day == sd->week_start) - { - if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm"); - else elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm"); - } - else if (it->day == last_day) - { - if (rtl) elm_object_signal_emit(VIEW(it), ITEM_POS_LEFT, "elm"); - else elm_object_signal_emit(VIEW(it), ITEM_POS_RIGHT, "elm"); - } - else - elm_object_signal_emit(VIEW(it), ITEM_POS_MIDDLE, "elm"); - } -} - -static inline unsigned int -_item_location_get(Elm_Dayselector_Smart_Data *sd, - Elm_Dayselector_Item *it) -{ - return (ELM_DAYSELECTOR_MAX - sd->week_start + it->day) % - ELM_DAYSELECTOR_MAX; -} - -static Eina_Bool -_elm_dayselector_smart_theme(Evas_Object *obj) -{ - Eina_List *l; - char buf[1024]; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->theme(obj)) - return EINA_FALSE; - - EINA_LIST_FOREACH (sd->items, l, it) - { - snprintf - (buf, sizeof(buf), "dayselector/%s", elm_object_style_get(obj)); - elm_object_style_set(VIEW(it), buf); - - snprintf - (buf, sizeof(buf), "day%d,visible", _item_location_get(sd, it)); - elm_layout_signal_emit(obj, buf, "elm"); - } - - _update_items(obj); - elm_layout_sizing_eval(obj); - - return EINA_TRUE; -} - -static void -_item_del_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) -{ - Eina_List *l; - char buf[1024]; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_DATA_GET(data, sd); - - EINA_LIST_FOREACH (sd->items, l, it) - { - if (obj == VIEW(it)) - { - sd->items = eina_list_remove(sd->items, it); - eina_stringshare_del(it->day_style); - snprintf(buf, sizeof(buf), "day%d,default", - _item_location_get(sd, it)); - elm_layout_signal_emit(obj, buf, "elm"); - - VIEW(it) = NULL; - elm_widget_item_free(it); - - elm_layout_sizing_eval(obj); - break; - } - } -} - -static void -_item_signal_emit_cb(void *data, - Evas_Object *obj __UNUSED__, - const char *emission, - const char *source __UNUSED__) -{ - Elm_Dayselector_Item *it = data; - - eina_stringshare_replace(&it->day_style, emission); -} - -static void -_item_clicked_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Elm_Dayselector_Item *it = data; - - evas_object_smart_callback_call(WIDGET(it), SIG_CHANGED, (void *)it->day); -} - -static Elm_Dayselector_Item * -_item_find(const Evas_Object *obj, - Elm_Dayselector_Day day) -{ - Eina_List *l; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - EINA_LIST_FOREACH (sd->items, l, it) - if (day == it->day) return it; - - return NULL; -} - -static Eina_Bool -_elm_dayselector_smart_content_set(Evas_Object *obj, - const char *item, - Evas_Object *content) -{ - int day; - char buf[1024]; - Elm_Dayselector_Item *it = NULL; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - if (strcmp(elm_object_widget_type_get(content), "elm_check")) - return EINA_FALSE; - - if (!item) return EINA_FALSE; - - day = atoi(item + (strlen(item) - 1)); - if (day < 0 || day > ELM_DAYSELECTOR_MAX) return EINA_FALSE; - - it = _item_find(obj, day); - if (it) - { - snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it)); - - if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_set - (obj, buf, content)) - return EINA_FALSE; - - if (!content) return EINA_TRUE; /* item deletion already - * handled */ - - evas_object_del(VIEW(it)); - VIEW(it) = content; - } - else - { - it = elm_widget_item_new(obj, Elm_Dayselector_Item); - it->day = day; - - snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it)); - - if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_set - (obj, buf, content)) - { - elm_widget_item_free(it); - return EINA_FALSE; - } - - sd->items = eina_list_append(sd->items, it); - VIEW(it) = content; - } - - snprintf(buf, sizeof(buf), "day%d,visible", _item_location_get(sd, it)); - elm_layout_signal_emit(obj, buf, "elm"); - - evas_object_smart_callback_add(VIEW(it), "changed", _item_clicked_cb, it); - evas_object_event_callback_add - (VIEW(it), EVAS_CALLBACK_DEL, _item_del_cb, obj); - - elm_object_signal_callback_add - (VIEW(it), ITEM_TYPE_WEEKDAY_DEFAULT, "", _item_signal_emit_cb, it); - elm_object_signal_callback_add - (VIEW(it), ITEM_TYPE_WEEKDAY_STYLE1, "", _item_signal_emit_cb, it); - elm_object_signal_callback_add - (VIEW(it), ITEM_TYPE_WEEKEND_DEFAULT, "", _item_signal_emit_cb, it); - elm_object_signal_callback_add - (VIEW(it), ITEM_TYPE_WEEKEND_STYLE1, "", _item_signal_emit_cb, it); - - elm_layout_sizing_eval(obj); - _update_items(obj); - - return EINA_TRUE; -} - -static Evas_Object * -_elm_dayselector_smart_content_unset(Evas_Object *obj, - const char *item) -{ - int day; - char buf[1024]; - Evas_Object *content; - Elm_Dayselector_Item *it = NULL; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - day = atoi(item + (strlen(item) - 1)); - if (day < 0 || day > ELM_DAYSELECTOR_MAX) return EINA_FALSE; - - it = _item_find(obj, day); - if (!it) return NULL; - - content = VIEW(it); - - if (!ELM_CONTAINER_CLASS(_elm_dayselector_parent_sc)->content_unset - (obj, buf)) - return EINA_FALSE; - - sd->items = eina_list_remove(sd->items, it); - evas_object_smart_callback_del(content, "changed", _item_clicked_cb); - evas_object_event_callback_del(content, EVAS_CALLBACK_DEL, _item_del_cb); - - elm_object_signal_callback_del - (content, ITEM_TYPE_WEEKDAY_DEFAULT, "", _item_signal_emit_cb); - elm_object_signal_callback_del - (content, ITEM_TYPE_WEEKDAY_STYLE1, "", _item_signal_emit_cb); - elm_object_signal_callback_del - (content, ITEM_TYPE_WEEKEND_DEFAULT, "", _item_signal_emit_cb); - elm_object_signal_callback_del - (content, ITEM_TYPE_WEEKEND_STYLE1, "", _item_signal_emit_cb); - - snprintf(buf, sizeof(buf), "day%d,default", _item_location_get(sd, it)); - elm_layout_signal_emit(obj, buf, "elm"); - - VIEW(it) = NULL; - elm_widget_item_free(it); - - elm_layout_sizing_eval(obj); - - return content; -} - -static void -_items_style_set(Evas_Object *obj) -{ - Eina_List *l; - Elm_Dayselector_Item *it; - unsigned int weekend_last; - - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - weekend_last = sd->weekend_start + sd->weekend_len - 1; - if (weekend_last >= ELM_DAYSELECTOR_MAX) - weekend_last = weekend_last % ELM_DAYSELECTOR_MAX; - - EINA_LIST_FOREACH (sd->items, l, it) - { - if (weekend_last >= sd->weekend_start) - { - if ((it->day >= sd->weekend_start) && (it->day <= weekend_last)) - eina_stringshare_replace(&it->day_style, - ITEM_TYPE_WEEKEND_DEFAULT); - else - eina_stringshare_replace(&it->day_style, - ITEM_TYPE_WEEKDAY_DEFAULT); - } - else - { - if ((it->day >= sd->weekend_start) || (it->day <= weekend_last)) - eina_stringshare_replace(&it->day_style, - ITEM_TYPE_WEEKEND_DEFAULT); - else - eina_stringshare_replace(&it->day_style, - ITEM_TYPE_WEEKDAY_DEFAULT); - } - } -} - -static void -_items_create(Evas_Object *obj) -{ - time_t t; - char buf[1024]; - unsigned int idx; - struct tm time_daysel; - - t = time(NULL); - localtime_r(&t, &time_daysel); - - for (idx = 0; idx < ELM_DAYSELECTOR_MAX; idx++) - { - Evas_Object *chk; - - chk = elm_check_add(obj); - elm_object_style_set(chk, "dayselector/default"); - - time_daysel.tm_wday = idx; - strftime(buf, sizeof(buf), "%a", &time_daysel); - elm_object_text_set(chk, buf); - - snprintf(buf, sizeof(buf), "day%d", idx); - elm_layout_content_set(obj, buf, chk); - } - - _items_style_set(obj); - _update_items(obj); -} - -static void -_elm_dayselector_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Dayselector_Smart_Data); - - ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->base.add(obj); - - elm_layout_theme_set(obj, "dayselector", "base", "dayselector"); - - priv->week_start = _elm_config->week_start; - priv->weekend_start = _elm_config->weekend_start; - priv->weekend_len = _elm_config->weekend_len; - _items_create(obj); - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESIZE, _dayselector_resize, obj); - - elm_layout_sizing_eval(obj); -} - -static void -_elm_dayselector_smart_del(Evas_Object *obj) -{ - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - Elm_Dayselector_Item *it; - - EINA_LIST_FREE (sd->items, it) - { - sd->items = eina_list_remove(sd->items, it); - eina_stringshare_del(it->day_style); - elm_widget_item_free(it); - } - - /* handles freeing sd */ - ELM_WIDGET_CLASS(_elm_dayselector_parent_sc)->base.del(obj); -} - -static void -_elm_dayselector_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_dayselector_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_dayselector_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_dayselector_smart_theme; - ELM_WIDGET_CLASS(sc)->translate = _elm_dayselector_smart_translate; -#if 0 - ELM_WIDGET_CLASS(sc)->focus_next = _elm_dayselector_smart_focus_next; -#else - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ -#endif - - ELM_CONTAINER_CLASS(sc)->content_set = _elm_dayselector_smart_content_set; - ELM_CONTAINER_CLASS(sc)->content_unset = - _elm_dayselector_smart_content_unset; - - sc->sizing_eval = _elm_dayselector_smart_sizing_eval; -} - -EAPI Evas_Object * -elm_dayselector_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_dayselector_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - return obj; -} - -EAPI void -elm_dayselector_day_selected_set(Evas_Object *obj, - Elm_Dayselector_Day day, - Eina_Bool selected) -{ - ELM_DAYSELECTOR_CHECK(obj); - - elm_check_state_set(VIEW(_item_find(obj, day)), selected); -} - -EAPI Eina_Bool -elm_dayselector_day_selected_get(const Evas_Object *obj, - Elm_Dayselector_Day day) -{ - ELM_DAYSELECTOR_CHECK(obj) EINA_FALSE; - - return elm_check_state_get(VIEW(_item_find(obj, day))); -} - -EAPI void -elm_dayselector_week_start_set(Evas_Object *obj, - Elm_Dayselector_Day day) -{ - Eina_List *l; - char buf[1024]; - Elm_Dayselector_Item *it; - - ELM_DAYSELECTOR_CHECK(obj); - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - /* just shuffling items, so swalling them directly */ - sd->week_start = day; - EINA_LIST_FOREACH (sd->items, l, it) - { - snprintf(buf, sizeof(buf), "day%d", _item_location_get(sd, it)); - edje_object_part_swallow - (ELM_WIDGET_DATA(sd)->resize_obj, buf, VIEW(it)); - } - - _update_items(obj); -} - -EAPI Elm_Dayselector_Day -elm_dayselector_week_start_get(const Evas_Object *obj) -{ - ELM_DAYSELECTOR_CHECK(obj) ELM_DAYSELECTOR_MAX; - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - return sd->week_start; -} - -EAPI void -elm_dayselector_weekend_start_set(Evas_Object *obj, - Elm_Dayselector_Day day) -{ - ELM_DAYSELECTOR_CHECK(obj); - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - sd->weekend_start = day; - - _items_style_set(obj); - _update_items(obj); -} - -EAPI Elm_Dayselector_Day -elm_dayselector_weekend_start_get(const Evas_Object *obj) -{ - ELM_DAYSELECTOR_CHECK(obj) ELM_DAYSELECTOR_MAX; - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - return sd->weekend_start; -} - -EAPI void -elm_dayselector_weekend_length_set(Evas_Object *obj, - unsigned int length) -{ - ELM_DAYSELECTOR_CHECK(obj); - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - sd->weekend_len = length; - - _items_style_set(obj); - _update_items(obj); -} - -EAPI unsigned int -elm_dayselector_weekend_length_get(const Evas_Object *obj) -{ - ELM_DAYSELECTOR_CHECK(obj) 0; - ELM_DAYSELECTOR_DATA_GET(obj, sd); - - return sd->weekend_len; -} diff --git a/src/lib/elm_flipselector.c b/src/lib/elm_flipselector.c index e18926ccb..7939aba8e 100644 --- a/src/lib/elm_flipselector.c +++ b/src/lib/elm_flipselector.c @@ -1,6 +1,5 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" /* TODO: ideally, the default theme would use map{} blocks on the TEXT parts to implement their fading in/out propertly (as in the clock @@ -16,186 +15,96 @@ * bootstrapping (receiving the 1st message) and populate the downmost * TEXT parts with the same text as the upmost, where appropriate. */ -static const char FLIPSELECTOR_SMART_NAME[] = "elm_flipselector"; - #define FLIP_FIRST_INTERVAL (0.85) -#define FLIP_MIN_INTERVAL (0.1) -#define MSG_FLIP_DOWN (1) -#define MSG_FLIP_UP (2) -#define MAX_LEN_DEFAULT (50) +#define FLIP_MIN_INTERVAL (0.1) +#define MSG_FLIP_DOWN (1) +#define MSG_FLIP_UP (2) +#define MAX_LEN_DEFAULT (50) -#define DATA_GET eina_list_data_get +#define DATA_GET eina_list_data_get struct _Elm_Flipselector_Item { ELM_WIDGET_ITEM; - - const char *label; + const char *label; Evas_Smart_Cb func; - void *data; - int deleted : 1; + void *data; + int deleted : 1; }; -typedef struct _Elm_Flipselector_Smart_Data Elm_Flipselector_Smart_Data; -typedef struct _Elm_Flipselector_Item Elm_Flipselector_Item; +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Flipselector_Item Elm_Flipselector_Item; -struct _Elm_Flipselector_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Eina_List *items; - Eina_List *current; - Eina_List *sentinel; /* item containing the largest - * label string */ - Ecore_Timer *spin; - - unsigned int max_len; - double interval, first_interval; - - int walking; + Evas_Object *self; + Evas_Object *base; + Eina_List *items; + Eina_List *current; + Eina_List *sentinel; /* item containing the largest label string */ + int walking; + unsigned int max_len; + Ecore_Timer *spin; + double interval, first_interval; }; -#define ELM_FLIPSELECTOR_DATA_GET(o, sd) \ - Elm_Flipselector_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_FLIPSELECTOR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_FLIPSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_FLIPSELECTOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_FLIPSELECTOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_FLIPSELECTOR_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), FLIPSELECTOR_SMART_NAME, __func__)) \ - return - -#define ELM_FLIPSELECTOR_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_FLIPSELECTOR_CHECK(it->base.widget); - -#define ELM_FLIPSELECTOR_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_FLIPSELECTOR_CHECK(it->base.widget) __VA_ARGS__; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _update_view(Evas_Object *obj); +static void _callbacks_set(Evas_Object *obj); +static void _flip_up(Widget_Data *wd); +static void _flip_down(Widget_Data *wd); +static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it); static const char SIG_SELECTED[] = "selected"; static const char SIG_UNDERFLOWED[] = "underflowed"; static const char SIG_OVERFLOWED[] = "overflowed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_SELECTED, ""}, - {SIG_UNDERFLOWED, ""}, - {SIG_OVERFLOWED, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_SELECTED, ""}, + {SIG_UNDERFLOWED, ""}, + {SIG_OVERFLOWED, ""}, + {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (FLIPSELECTOR_SMART_NAME, _elm_flipselector, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - -static void -_elm_flipselector_smart_sizing_eval(Evas_Object *obj) -{ - char *tmp = NULL; - Evas_Coord minw = -1, minh = -1, w, h; - - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - elm_coords_finger_size_adjust(1, &minw, 2, &minh); - - if (sd->sentinel) - { - const char *label = elm_object_item_text_get(DATA_GET(sd->sentinel)); - - tmp = strdup(elm_layout_text_get(obj, "elm.top")); - elm_layout_text_set(obj, "elm.top", label); - } - - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); - elm_coords_finger_size_adjust(1, &minw, 2, &minh); - evas_object_size_hint_min_get(obj, &w, &h); - - if (sd->sentinel) - { - elm_layout_text_set(obj, "elm.top", tmp); - free(tmp); - } - - if (w > minw) minw = w; - if (h > minh) minh = h; - - evas_object_size_hint_min_set(obj, minw, minh); -} - -static void -_update_view(Evas_Object *obj) -{ - const char *label; - Elm_Flipselector_Item *item; - - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - label = NULL; - item = DATA_GET(sd->current); - if (item) label = item->label; - - elm_layout_text_set(obj, "elm.top", label ? label : ""); - elm_layout_text_set(obj, "elm.bottom", label ? label : ""); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); -} - static void _item_text_set_hook(Elm_Object_Item *it, const char *part, const char *label) { + Widget_Data *wd; Eina_List *l; Elm_Flipselector_Item *item; if (!label) return; - if (part && strcmp(part, "default")) return; + if (part && strcmp(part ,"default")) return; item = (Elm_Flipselector_Item *)it; - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); - - if (!sd->items) return; + wd = elm_widget_data_get(WIDGET(item)); + if ((!wd) || (!wd->items)) return; - l = eina_list_data_find_list(sd->items, item); + l = eina_list_data_find_list(wd->items, item); if (!l) return; eina_stringshare_del(item->label); - item->label = eina_stringshare_add_length(label, sd->max_len); + item->label = eina_stringshare_add_length(label, wd->max_len); - if (strlen(label) > strlen(elm_object_item_text_get(DATA_GET(sd->sentinel)))) - sd->sentinel = l; + if (strlen(label) > strlen(elm_object_item_text_get(DATA_GET(wd->sentinel)))) + wd->sentinel = l; - if (sd->current == l) + if (wd->current == l) { _update_view(WIDGET(item)); - elm_layout_sizing_eval(WIDGET(item)); + _sizing_eval(wd->self); } } static const char * -_item_text_get_hook(const Elm_Object_Item *it, - const char *part) +_item_text_get_hook(const Elm_Object_Item *it, const char *part) { - if (part && strcmp(part, "default")) return NULL; + if (part && strcmp(part ,"default")) return NULL; return ((Elm_Flipselector_Item *)it)->label; } @@ -206,561 +115,644 @@ _item_signal_emit_hook(Elm_Object_Item *it, const char *source) { Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it; - edje_object_signal_emit(VIEW(item), emission, source); } +static Elm_Flipselector_Item * +_item_new(Evas_Object *obj, const char *label, Evas_Smart_Cb func, const void *data) +{ + unsigned int len; + Elm_Flipselector_Item *it; + Widget_Data *wd = elm_widget_data_get(obj); + + it = elm_widget_item_new(obj, Elm_Flipselector_Item); + if (!it) return NULL; + + elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); + elm_widget_item_text_set_hook_set(it, _item_text_set_hook); + elm_widget_item_text_get_hook_set(it, _item_text_get_hook); + elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook); + + len = strlen(label); + if (len > wd->max_len) + len = wd->max_len; + + it->label = eina_stringshare_add_length(label, len); + it->func = func; + it->base.data = data; + + /* TODO: no view here, but if one desires general contents in the + * future... */ + return it; +} + static inline void -_flipselector_walk(Elm_Flipselector_Smart_Data *sd) +_item_free(Elm_Flipselector_Item *it) +{ + eina_stringshare_del(it->label); + elm_widget_item_free(it); +} + +static void +_del_hook(Evas_Object *obj) +{ + Elm_Flipselector_Item *item; + + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (wd->walking) ERR("flipselector deleted while walking.\n"); + + EINA_LIST_FREE(wd->items, item) + _item_free(item); + + if (wd->spin) ecore_timer_del(wd->spin); + free(wd); +} + +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->base, "elm,state,disabled", "elm"); + else + edje_object_signal_emit(wd->base, "elm,state,enabled", "elm"); +} + +static void +_theme_hook(Evas_Object *obj) { - if (sd->walking < 0) + Widget_Data *wd; + const char *max_len; + + wd = elm_widget_data_get(obj); + if (!wd) return; + + _elm_theme_object_set(obj, wd->base, "flipselector", "base", + elm_widget_style_get(obj)); + edje_object_scale_set(wd->base, + elm_widget_scale_get(obj) * _elm_config->scale); + + max_len = edje_object_data_get(wd->base, "max_len"); + if (!max_len) + wd->max_len = MAX_LEN_DEFAULT; + else { - ERR("walking was negative. fixed!\n"); - sd->walking = 0; + wd->max_len = atoi(max_len); + if (!wd->max_len) + wd->max_len = MAX_LEN_DEFAULT; } - sd->walking++; + + _update_view(obj); + _sizing_eval(obj); } static void -_sentinel_eval(Elm_Flipselector_Smart_Data *sd) +_sentinel_eval(Widget_Data *wd) { Elm_Flipselector_Item *it; Eina_List *l; - if (!sd->items) + if (!wd->items) { - sd->sentinel = NULL; + wd->sentinel = NULL; return; } - sd->sentinel = sd->items; + wd->sentinel = wd->items; - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FOREACH(wd->items, l, it) { if (strlen(elm_object_item_text_get((Elm_Object_Item *)it)) > - strlen(elm_object_item_text_get(DATA_GET(sd->sentinel)))) - sd->sentinel = l; + strlen(elm_object_item_text_get(DATA_GET(wd->sentinel)))) + wd->sentinel = l; } } /* TODO: create a flag to avoid looping here all times */ static void -_flipselector_process_deletions(Elm_Flipselector_Smart_Data *sd) +_flipselector_process_deletions(Widget_Data *wd) { - Eina_List *l; Elm_Flipselector_Item *it; + Eina_List *l; Eina_Bool skip = EINA_TRUE; Eina_Bool sentinel_eval = EINA_FALSE; - sd->walking++; /* avoid nested deletions */ + wd->walking++; /* avoid nested deletions */ - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FOREACH(wd->items, l, it) { if (!it->deleted) continue; - if (sd->current == l) + if (wd->current == l) { - if (sd->current == sd->sentinel) sentinel_eval = EINA_TRUE; - sd->current = eina_list_prev(sd->current); + if (wd->current == wd->sentinel) + sentinel_eval = EINA_TRUE; + wd->current = eina_list_prev(wd->current); } - sd->items = eina_list_remove(sd->items, it); + wd->items = eina_list_remove(wd->items, it); - if (!sd->current) sd->current = sd->items; + if (!wd->current) + wd->current = wd->items; - elm_widget_item_del(it); + _item_free(it); skip = EINA_FALSE; - if (eina_list_count(sd->items) <= 1) - elm_layout_signal_emit - (ELM_WIDGET_DATA(sd)->obj, "elm,state,button,hidden", "elm"); + if (eina_list_count(wd->items) <= 1) + edje_object_signal_emit(wd->base, "elm,state,button,hidden", "elm"); else - elm_layout_signal_emit - (ELM_WIDGET_DATA(sd)->obj, "elm,state,button,visible", "elm"); + edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm"); } - if (!skip) _update_view(ELM_WIDGET_DATA(sd)->obj); + if (!skip) + _update_view(wd->self); - if (sentinel_eval) _sentinel_eval(sd); + if (sentinel_eval) + _sentinel_eval(wd); - sd->walking--; + wd->walking--; } static inline void -_flipselector_unwalk(Elm_Flipselector_Smart_Data *sd) +_flipselector_walk(Widget_Data *wd) { - sd->walking--; + if (wd->walking < 0) + { + ERR("walking was negative. fixed!\n"); + wd->walking = 0; + } + wd->walking++; +} - if (sd->walking < 0) +static inline void +_flipselector_unwalk(Widget_Data *wd) +{ + wd->walking--; + if (wd->walking < 0) { ERR("walking became negative. fixed!\n"); - sd->walking = 0; + wd->walking = 0; } - if (sd->walking) return; + if (wd->walking) return; - _flipselector_process_deletions(sd); + _flipselector_process_deletions(wd); } -static void -_on_item_changed(Elm_Flipselector_Smart_Data *sd) +static Eina_Bool +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - Elm_Flipselector_Item *item; + Evas_Event_Key_Down *ev; + Widget_Data *wd; + Eina_Bool is_up = EINA_TRUE; - item = DATA_GET(sd->current); - if (!item) return; + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; - if (item->func) - item->func((void *)item->base.data, WIDGET(item), item); - if (!item->deleted) - evas_object_smart_callback_call - (ELM_WIDGET_DATA(sd)->obj, SIG_SELECTED, item); -} + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; -static void -_send_msg(Elm_Flipselector_Smart_Data *sd, - int flipside, - char *label) -{ - Edje_Message_String msg; + ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - msg.str = label; - edje_object_message_send - (ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_STRING, flipside, &msg); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + if (elm_widget_disabled_get(obj)) return EINA_FALSE; + + if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down"))) + is_up = EINA_FALSE; + else if ((strcmp(ev->keyname, "Up")) && (strcmp(ev->keyname, "KP_Up"))) + return EINA_FALSE; - _on_item_changed(sd); + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; + + /* TODO: if direction setting via API is not coming in, replace + these calls by flip_{next,prev} */ + _flipselector_walk(wd); + if (is_up) _flip_up(wd); + else _flip_down(wd); + _flipselector_unwalk(wd); + + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; } -static Eina_Bool -_item_del_pre_hook(Elm_Object_Item *it) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - Elm_Flipselector_Item *item, *item2; - Eina_List *l; - - item = (Elm_Flipselector_Item *)it; - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (sd->walking > 0) + /* FIXME: no treatment of this signal so far */ + if (elm_widget_focus_get(obj)) { - item->deleted = EINA_TRUE; - return EINA_FALSE; + edje_object_signal_emit(wd->base, "elm,action,focus", "elm"); + evas_object_focus_set(wd->base, EINA_TRUE); } - - _flipselector_walk(sd); - - EINA_LIST_FOREACH (sd->items, l, item2) + else { - if (item2 == item) - { - sd->items = eina_list_remove_list(sd->items, l); - - if (sd->current == l) - { - sd->current = l->prev; - if (!sd->current) sd->current = l->next; - if (sd->current) - { - item2 = sd->current->data; - _send_msg(sd, MSG_FLIP_DOWN, (char *)item2->label); - } - else _send_msg(sd, MSG_FLIP_DOWN, ""); - } - break; - } + edje_object_signal_emit(wd->base, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->base, EINA_FALSE); } - - eina_stringshare_del(item->label); - _sentinel_eval(sd); - _flipselector_unwalk(sd); - - return EINA_TRUE; } -static Elm_Flipselector_Item * -_item_new(Evas_Object *obj, - const char *label, - Evas_Smart_Cb func, - const void *data) +static void +_sizing_eval(Evas_Object *obj) { - unsigned int len; - Elm_Flipselector_Item *it; + Widget_Data *wd; + const char *tmp = NULL; + Evas_Coord minw = -1, minh = -1, w, h; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; - it = elm_widget_item_new(obj, Elm_Flipselector_Item); - if (!it) return NULL; + elm_coords_finger_size_adjust(1, &minw, 2, &minh); - elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); - elm_widget_item_text_set_hook_set(it, _item_text_set_hook); - elm_widget_item_text_get_hook_set(it, _item_text_get_hook); - elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook); + if (wd->sentinel) + { + const char *label = elm_object_item_text_get(DATA_GET(wd->sentinel)); + tmp = edje_object_part_text_get(wd->base, "elm.top"); + edje_object_part_text_escaped_set(wd->base, "elm.top", label); + } - len = strlen(label); - if (len > sd->max_len) len = sd->max_len; + edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh); + elm_coords_finger_size_adjust(1, &minw, 2, &minh); + evas_object_size_hint_min_get(obj, &w, &h); - it->label = eina_stringshare_add_length(label, len); - it->func = func; - it->base.data = data; + if (wd->sentinel) edje_object_part_text_escaped_set(wd->base, "elm.top", tmp); - /* TODO: no view here, but if one desires general contents in the - * future... */ - return it; + if (w > minw) minw = w; + if (h > minh) minh = h; + + evas_object_size_hint_min_set(obj, minw, minh); } -static Eina_Bool -_elm_flipselector_smart_theme(Evas_Object *obj) +static void +_update_view(Evas_Object *obj) { - const char *max_len; - - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_flipselector_parent_sc)->theme(obj)) - return EINA_FALSE; - - max_len = edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj, "max_len"); - if (!max_len) sd->max_len = MAX_LEN_DEFAULT; - else - { - sd->max_len = atoi(max_len); + Widget_Data *wd; + const char *label; + Elm_Flipselector_Item *item; - if (!sd->max_len) sd->max_len = MAX_LEN_DEFAULT; - } + wd = elm_widget_data_get(obj); + if (!wd) return; - _update_view(obj); - elm_layout_sizing_eval(obj); + label = NULL; + item = DATA_GET(wd->current); + if (item) label = item->label; - return EINA_TRUE; + edje_object_part_text_escaped_set(wd->base, "elm.top", label ? label : ""); + edje_object_part_text_escaped_set(wd->base, "elm.bottom", label ? label : ""); + edje_object_message_signal_process(wd->base); } static void -_flip_up(Elm_Flipselector_Smart_Data *sd) +_changed(Widget_Data *wd) { Elm_Flipselector_Item *item; - if (!sd->current) return; + item = DATA_GET(wd->current); + if (!item) return; - if (sd->current == sd->items) - { - sd->current = eina_list_last(sd->items); - evas_object_smart_callback_call - (ELM_WIDGET_DATA(sd)->obj, SIG_UNDERFLOWED, NULL); - } - else - sd->current = eina_list_prev(sd->current); + if (item->func) + item->func((void *)item->base.data, WIDGET(item), item); + if (!item->deleted) + evas_object_smart_callback_call(wd->self, SIG_SELECTED, item); +} - item = DATA_GET(sd->current); - if (!item) return; +static void +_send_msg(Widget_Data *wd, int flipside, char *label) +{ + Edje_Message_String msg; - _send_msg(sd, MSG_FLIP_UP, (char *)item->label); + msg.str = label; + edje_object_message_send(wd->base, EDJE_MESSAGE_STRING, flipside, &msg); + edje_object_message_signal_process(wd->base); + + _changed(wd); } static void -_flip_down(Elm_Flipselector_Smart_Data *sd) +_flip_up(Widget_Data *wd) { Elm_Flipselector_Item *item; - if (!sd->current) return; + if (!wd->current) return; - sd->current = eina_list_next(sd->current); - if (!sd->current) + if (wd->current == wd->items) { - sd->current = sd->items; - evas_object_smart_callback_call - (ELM_WIDGET_DATA(sd)->obj, SIG_OVERFLOWED, NULL); + wd->current = eina_list_last(wd->items); + evas_object_smart_callback_call(wd->self, SIG_UNDERFLOWED, NULL); } + else + wd->current = eina_list_prev(wd->current); - item = DATA_GET(sd->current); + item = DATA_GET(wd->current); if (!item) return; - _send_msg(sd, MSG_FLIP_DOWN, (char *)item->label); + _send_msg(wd, MSG_FLIP_UP, (char *)item->label); } static Eina_Bool -_elm_flipselector_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_signal_val_up(void *data) { - Evas_Event_Key_Down *ev; - Eina_Bool is_up = EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(data); - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + if (!wd) goto val_up_exit_on_error; - if (elm_widget_disabled_get(obj)) return EINA_FALSE; + _flipselector_walk(wd); - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + if (wd->interval > FLIP_MIN_INTERVAL) + wd->interval = wd->interval / 1.05; - ev = event_info; - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + ecore_timer_interval_set(wd->spin, wd->interval); - if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down"))) - is_up = EINA_FALSE; - else if ((strcmp(ev->keyname, "Up")) && (strcmp(ev->keyname, "KP_Up"))) - return EINA_FALSE; + _flip_up(wd); - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; + _flipselector_unwalk(wd); - /* TODO: if direction setting via API is not coming in, replace - these calls by flip_{next,prev} */ - _flipselector_walk(sd); - - if (is_up) _flip_up(sd); - else _flip_down(sd); - - _flipselector_unwalk(sd); - - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return ECORE_CALLBACK_RENEW; - return EINA_TRUE; +val_up_exit_on_error: + return ECORE_CALLBACK_CANCEL; } -static Eina_Bool -_signal_val_up(void *data) +static void +_signal_val_up_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_FLIPSELECTOR_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - _flipselector_walk(sd); + wd->interval = wd->first_interval; - if (sd->interval > FLIP_MIN_INTERVAL) sd->interval = sd->interval / 1.05; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _signal_val_up, data); - ecore_timer_interval_set(sd->spin, sd->interval); - - _flip_up(sd); - - _flipselector_unwalk(sd); - - return ECORE_CALLBACK_RENEW; + _signal_val_up(data); } static void -_signal_val_up_start(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_flip_down(Widget_Data *wd) { - ELM_FLIPSELECTOR_DATA_GET(data, sd); + Elm_Flipselector_Item *item; - sd->interval = sd->first_interval; + if (!wd->current) return; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _signal_val_up, data); + wd->current = eina_list_next(wd->current); + if (!wd->current) + { + wd->current = wd->items; + evas_object_smart_callback_call(wd->self, SIG_OVERFLOWED, NULL); + } - _signal_val_up(data); + item = DATA_GET(wd->current); + if (!item) return; + + _send_msg(wd, MSG_FLIP_DOWN, (char *)item->label); } static Eina_Bool _signal_val_down(void *data) { - ELM_FLIPSELECTOR_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + + if (!wd) goto val_down_exit_on_error; - _flipselector_walk(sd); + _flipselector_walk(wd); - if (sd->interval > FLIP_MIN_INTERVAL) sd->interval = sd->interval / 1.05; - ecore_timer_interval_set(sd->spin, sd->interval); + if (wd->interval > FLIP_MIN_INTERVAL) + wd->interval = wd->interval / 1.05; + ecore_timer_interval_set(wd->spin, wd->interval); - _flip_down(sd); + _flip_down(wd); - _flipselector_unwalk(sd); + _flipselector_unwalk(wd); return ECORE_CALLBACK_RENEW; + +val_down_exit_on_error: + return ECORE_CALLBACK_CANCEL; } static void -_signal_val_down_start(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_val_down_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_FLIPSELECTOR_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - sd->interval = sd->first_interval; + wd->interval = wd->first_interval; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = ecore_timer_add(sd->interval, _signal_val_down, data); + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = ecore_timer_add(wd->interval, _signal_val_down, data); _signal_val_down(data); } static void -_signal_val_change_stop(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_val_change_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_FLIPSELECTOR_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; } static void -_elm_flipselector_smart_add(Evas_Object *obj) +_callbacks_set(Evas_Object *obj) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Flipselector_Smart_Data); - - ELM_WIDGET_CLASS(_elm_flipselector_parent_sc)->base.add(obj); - - elm_layout_theme_set - (obj, "flipselector", "base", elm_widget_style_get(obj)); + Widget_Data *wd = elm_widget_data_get(obj); - elm_layout_signal_callback_add - (obj, "elm,action,up,start", "", _signal_val_up_start, obj); - elm_layout_signal_callback_add - (obj, "elm,action,up,stop", "", _signal_val_change_stop, obj); - elm_layout_signal_callback_add - (obj, "elm,action,down,start", "", _signal_val_down_start, obj); - elm_layout_signal_callback_add - (obj, "elm,action,down,stop", "", _signal_val_change_stop, obj); - - priv->first_interval = FLIP_FIRST_INTERVAL; - - elm_widget_can_focus_set(obj, EINA_TRUE); - - _elm_flipselector_smart_theme(obj); + edje_object_signal_callback_add(wd->base, "elm,action,up,start", + "", _signal_val_up_start, obj); + edje_object_signal_callback_add(wd->base, "elm,action,up,stop", + "", _signal_val_change_stop, obj); + edje_object_signal_callback_add(wd->base, "elm,action,down,start", + "", _signal_val_down_start, obj); + edje_object_signal_callback_add(wd->base, "elm,action,down,stop", + "", _signal_val_change_stop, obj); } -static void -_elm_flipselector_smart_del(Evas_Object *obj) +static Eina_Bool +_item_del_pre_hook(Elm_Object_Item *it) { - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - if (sd->walking) ERR("flipselector deleted while walking.\n"); - - while (sd->items) - elm_widget_item_del(DATA_GET(sd->items)); + Widget_Data *wd; + Elm_Flipselector_Item *item, *item2; + Eina_List *l; - if (sd->spin) ecore_timer_del(sd->spin); + item = (Elm_Flipselector_Item *)it; + wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return EINA_FALSE; - ELM_WIDGET_CLASS(_elm_flipselector_parent_sc)->base.del(obj); -} + if (wd->walking > 0) + { + item->deleted = EINA_TRUE; + return EINA_FALSE; + } -static void -_elm_flipselector_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_flipselector_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_flipselector_smart_del; + _flipselector_walk(wd); - ELM_WIDGET_CLASS(sc)->theme = _elm_flipselector_smart_theme; - ELM_WIDGET_CLASS(sc)->event = _elm_flipselector_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + EINA_LIST_FOREACH(wd->items, l, item2) + { + if (item2 == item) + { + wd->items = eina_list_remove_list(wd->items, l); + if (wd->current == l) + { + wd->current = l->prev; + if (!wd->current) wd->current = l->next; + if (wd->current) + { + item2 = wd->current->data; + _send_msg(wd, MSG_FLIP_DOWN, (char *)item2->label); + } + else + _send_msg(wd, MSG_FLIP_DOWN, ""); + } + break; + } + } + eina_stringshare_del(item->label); + _sentinel_eval(wd); + _flipselector_unwalk(wd); - sc->sizing_eval = _elm_flipselector_smart_sizing_eval; + return EINA_TRUE; } EAPI Evas_Object * elm_flipselector_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "flipselector"); + elm_widget_type_set(obj, "flipselector"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + + wd->self = obj; + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_event_hook_set(obj, _event_hook); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd->base = edje_object_add(e); + elm_widget_resize_object_set(obj, wd->base); - e = evas_object_evas_get(parent); - if (!e) return NULL; + _callbacks_set(obj); - obj = evas_object_smart_add(e, _elm_flipselector_smart_class_new()); + wd->first_interval = FLIP_FIRST_INTERVAL; - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + _theme_hook(obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } EAPI void elm_flipselector_flip_next(Evas_Object *obj) { - ELM_FLIPSELECTOR_CHECK(obj); - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - _flipselector_walk(sd); - _flip_down(sd); - _flipselector_unwalk(sd); + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; + + _flipselector_walk(wd); + _flip_down(wd); + _flipselector_unwalk(wd); } EAPI void elm_flipselector_flip_prev(Evas_Object *obj) { - ELM_FLIPSELECTOR_CHECK(obj); + ELM_CHECK_WIDTYPE(obj, widtype); - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (sd->spin) ecore_timer_del(sd->spin); - sd->spin = NULL; + if (wd->spin) ecore_timer_del(wd->spin); + wd->spin = NULL; - _flipselector_walk(sd); - _flip_up(sd); - _flipselector_unwalk(sd); + _flipselector_walk(wd); + _flip_up(wd); + _flipselector_unwalk(wd); } EAPI Elm_Object_Item * -elm_flipselector_item_append(Evas_Object *obj, - const char *label, - void (*func)(void *, Evas_Object *, void *), - void *data) +elm_flipselector_item_append(Evas_Object *obj, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Flipselector_Item *item; + Widget_Data *wd; - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; item = _item_new(obj, label, func, data); if (!item) return NULL; - sd->items = eina_list_append(sd->items, item); - if (!sd->current) + wd->items = eina_list_append(wd->items, item); + if (!wd->current) { - sd->current = sd->items; + wd->current = wd->items; _update_view(obj); } - if (!sd->sentinel || + if (!wd->sentinel || (strlen(elm_object_item_text_get((Elm_Object_Item *)item)) > - strlen(elm_object_item_text_get(DATA_GET(sd->sentinel))))) + strlen(elm_object_item_text_get(DATA_GET(wd->sentinel))))) { - sd->sentinel = eina_list_last(sd->items); - elm_layout_sizing_eval(obj); + wd->sentinel = eina_list_last(wd->items); + _sizing_eval(obj); } - if (eina_list_count(sd->items) >= 2) - elm_layout_signal_emit(obj, "elm,state,button,visible", "elm"); + if (eina_list_count(wd->items) >= 2) + edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm"); return (Elm_Object_Item *)item; } EAPI Elm_Object_Item * -elm_flipselector_item_prepend(Evas_Object *obj, - const char *label, - void (*func)(void *, Evas_Object *, void *), - void *data) +elm_flipselector_item_prepend(Evas_Object *obj, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Flipselector_Item *item; + Widget_Data *wd; - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; item = _item_new(obj, label, func, data); if (!item) return NULL; - sd->items = eina_list_prepend(sd->items, item); - if (!sd->current) + wd->items = eina_list_prepend(wd->items, item); + if (!wd->current) { - sd->current = sd->items; + wd->current = wd->items; _update_view(obj); } - if (!sd->sentinel || + if (!wd->sentinel || (strlen(elm_object_item_text_get((Elm_Object_Item *)item)) > - strlen(elm_object_item_text_get(DATA_GET(sd->sentinel))))) + strlen(elm_object_item_text_get(DATA_GET(wd->sentinel))))) { - sd->sentinel = sd->items; - elm_layout_sizing_eval(obj); + wd->sentinel = wd->items; + _sizing_eval(obj); } - if (eina_list_count(sd->items) >= 2) - elm_layout_signal_emit(obj, "elm,state,button,visible", "elm"); + if (eina_list_count(wd->items) >= 2) + edje_object_signal_emit(wd->base, "elm,state,button,visible", "elm"); return (Elm_Object_Item *)item; } @@ -768,134 +760,138 @@ elm_flipselector_item_prepend(Evas_Object *obj, EAPI const Eina_List * elm_flipselector_items_get(const Evas_Object *obj) { - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - return sd->items; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->items; } EAPI Elm_Object_Item * elm_flipselector_first_item_get(const Evas_Object *obj) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Flipselector_Item *it; + Widget_Data *wd; Eina_List *l; - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - if (!sd->items) return NULL; + wd = elm_widget_data_get(obj); + if (!wd || !wd->items) return NULL; - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FOREACH(wd->items, l, it) { if (it->deleted) continue; return (Elm_Object_Item *)it; } - return NULL; } EAPI Elm_Object_Item * elm_flipselector_last_item_get(const Evas_Object *obj) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Flipselector_Item *it; + Widget_Data *wd; Eina_List *l; - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); - - if (!sd->items) return NULL; + wd = elm_widget_data_get(obj); + if (!wd || !wd->items) return NULL; - EINA_LIST_REVERSE_FOREACH (sd->items, l, it) + EINA_LIST_REVERSE_FOREACH(wd->items, l, it) { if (it->deleted) continue; return (Elm_Object_Item *)it; } - return NULL; } EAPI Elm_Object_Item * elm_flipselector_selected_item_get(const Evas_Object *obj) { - ELM_FLIPSELECTOR_CHECK(obj) NULL; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - return DATA_GET(sd->current); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return DATA_GET(wd->current); } EAPI void -elm_flipselector_item_selected_set(Elm_Object_Item *it, - Eina_Bool selected) +elm_flipselector_item_selected_set(Elm_Object_Item *it, Eina_Bool selected) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Elm_Flipselector_Item *item, *_item, *cur; int flipside = MSG_FLIP_UP; + Widget_Data *wd; Eina_List *l; - ELM_FLIPSELECTOR_ITEM_CHECK_OR_RETURN(it); - item = (Elm_Flipselector_Item *)it; - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); + wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return; - cur = DATA_GET(sd->current); + cur = DATA_GET(wd->current); if ((selected) && (cur == item)) return; - _flipselector_walk(sd); + _flipselector_walk(wd); if ((!selected) && (cur == item)) { - EINA_LIST_FOREACH (sd->items, l, _item) + EINA_LIST_FOREACH(wd->items, l, _item) { if (!_item->deleted) { - sd->current = l; - _send_msg(sd, MSG_FLIP_UP, (char *)_item->label); + wd->current = l; + _send_msg(wd, MSG_FLIP_UP, (char *)_item->label); break; } } - _flipselector_unwalk(sd); + _flipselector_unwalk(wd); return; } - EINA_LIST_FOREACH (sd->items, l, _item) + EINA_LIST_FOREACH(wd->items, l, _item) { if (_item == cur) flipside = MSG_FLIP_DOWN; if (_item == item) { - sd->current = l; - _send_msg(sd, flipside, (char *)item->label); + wd->current = l; + _send_msg(wd, flipside, (char *)item->label); break; } } - _flipselector_unwalk(sd); + _flipselector_unwalk(wd); } EAPI Eina_Bool elm_flipselector_item_selected_get(const Elm_Object_Item *it) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); + Widget_Data *wd; Elm_Flipselector_Item *item; - ELM_FLIPSELECTOR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE); - item = (Elm_Flipselector_Item *)it; - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); - - return eina_list_data_get(sd->current) == item; + wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return EINA_FALSE; + return (eina_list_data_get(wd->current) == item); } EAPI Elm_Object_Item * elm_flipselector_item_prev_get(const Elm_Object_Item *it) { - Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it; - Eina_List *l; + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); - ELM_FLIPSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL); - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); + Widget_Data *wd; + Eina_List *l; + Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it; - if ((!sd->items)) return NULL; + wd = elm_widget_data_get(WIDGET(item)); + if ((!wd) || (!wd->items)) return NULL; - l = eina_list_data_find_list(sd->items, it); + l = eina_list_data_find_list(wd->items, it); if (l && l->prev) return DATA_GET(l->prev); return NULL; @@ -904,35 +900,37 @@ elm_flipselector_item_prev_get(const Elm_Object_Item *it) EAPI Elm_Object_Item * elm_flipselector_item_next_get(const Elm_Object_Item *it) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); + + Widget_Data *wd; Eina_List *l; Elm_Flipselector_Item *item = (Elm_Flipselector_Item *)it; - ELM_FLIPSELECTOR_ITEM_CHECK_OR_RETURN(it, NULL); - ELM_FLIPSELECTOR_DATA_GET(WIDGET(item), sd); - - if ((!sd->items)) return NULL; + wd = elm_widget_data_get(WIDGET(item)); + if ((!wd) || (!wd->items)) return NULL; - l = eina_list_data_find_list(sd->items, it); + l = eina_list_data_find_list(wd->items, it); if (l && l->next) return DATA_GET(l->next); return NULL; } EAPI void -elm_flipselector_first_interval_set(Evas_Object *obj, - double interval) +elm_flipselector_first_interval_set(Evas_Object *obj, double interval) { - ELM_FLIPSELECTOR_CHECK(obj); - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); - sd->first_interval = interval; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->first_interval = interval; } EAPI double elm_flipselector_first_interval_get(const Evas_Object *obj) { - ELM_FLIPSELECTOR_CHECK(obj) 0; - ELM_FLIPSELECTOR_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) 0; - return sd->first_interval; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->first_interval; } diff --git a/src/lib/elm_flipselector.h b/src/lib/elm_flipselector.h index ef03ca057..bdc52df60 100644 --- a/src/lib/elm_flipselector.h +++ b/src/lib/elm_flipselector.h @@ -16,11 +16,7 @@ * so that it helps the user to reach an item which is distant from * the current selection. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for flip selector objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * Smart callbacks one can register to: * - @c "selected" - when the widget's selected text item is changed * - @c "overflowed" - when the widget's current selection is changed * from the first item in its list to the last diff --git a/src/lib/elm_frame.c b/src/lib/elm_frame.c index 63867430b..0d32c16b7 100644 --- a/src/lib/elm_frame.c +++ b/src/lib/elm_frame.c @@ -1,269 +1,325 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char FRAME_SMART_NAME[] = "elm_frame"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Frame_Smart_Data Elm_Frame_Smart_Data; - -struct _Elm_Frame_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Eina_Bool collapsed : 1; - Eina_Bool collapsible : 1; - Eina_Bool anim : 1; + Evas_Object *frm; + Evas_Object *content; + const char *label; + unsigned int recalc_count; + Eina_Bool collapsed : 1; + Eina_Bool collapsible : 1; + Eina_Bool anim : 1; }; static const char SIG_CLICKED[] = "clicked"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CLICKED, ""}, {NULL, NULL} }; -#define ELM_FRAME_DATA_GET(o, sd) \ - Elm_Frame_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_FRAME_DATA_GET_OR_RETURN(o, ptr) \ - ELM_FRAME_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_FRAME_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_FRAME_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_FRAME_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), FRAME_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"default", "elm.swallow.content"}, - {NULL, NULL} -}; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, + Evas *e, Evas_Object *obj, + void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); -static const Elm_Layout_Part_Alias_Description _text_aliases[] = +static void +_del_hook(Evas_Object *obj) { - {"default", "elm.text"}, - {NULL, NULL} -}; - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (FRAME_SMART_NAME, _elm_frame, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + free(wd); +} static void -_sizing_eval(Evas_Object *obj, - Elm_Frame_Smart_Data *sd) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Evas_Coord minw = -1, minh = -1; - Evas_Coord cminw = -1, cminh = -1; - - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_get(obj, &cminw, &cminh); - if ((minw == cminw) && (minh == cminh)) return; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->frm, rtl); +} - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, -1, -1); +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->frm, "frame", "base", + elm_widget_style_get(obj)); + edje_object_part_text_escaped_set(wd->frm, "elm.text", wd->label); + 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); + _sizing_eval(obj); } static Eina_Bool -_elm_frame_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_frame_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - Evas_Object *content; - - content = elm_layout_content_get(obj, NULL); + Widget_Data *wd = elm_widget_data_get(obj); - if (!content) return EINA_FALSE; + if ((!wd) || (!wd->content)) + return EINA_FALSE; - /* attempt to follow focus cycle into sub-object */ - return elm_widget_focus_next_get(content, dir, next); + /* Try Focus cycle in subitem */ + return elm_widget_focus_next_get(wd->content, dir, next); } static void -_recalc(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_sizing_eval(Evas_Object *obj) { - elm_layout_sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; + Evas_Coord cminw = -1, cminh = -1; + if (!wd) return; + edje_object_size_min_calc(wd->frm, &minw, &minh); + evas_object_size_hint_min_get(obj, &cminw, &cminh); + if ((minw == cminw) && (minh == cminh)) return; + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); } static void -_on_recalc_done(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *src __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_FRAME_DATA_GET(data, sd); - - evas_object_smart_callback_del - (ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc); - sd->anim = EINA_FALSE; - - elm_layout_sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (wd->anim) return; + // FIXME: why is this needed? how does edje get this unswallowed or + // lose its callbacks to edje + edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content); + _sizing_eval(data); } static void -_on_frame_clicked(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *src __UNUSED__) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { - ELM_FRAME_DATA_GET(data, sd); - - if (sd->anim) return; - - if (sd->collapsible) + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->content) { - evas_object_smart_callback_add - (ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc, data); - elm_layout_signal_emit(data, "elm,action,toggle", "elm"); - sd->collapsed++; - sd->anim = EINA_TRUE; + evas_object_event_callback_del_full(sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->content = NULL; + _sizing_eval(obj); } - evas_object_smart_callback_call(data, SIG_CLICKED, NULL); } -/* using deferred sizing evaluation, just like the parent */ static void -_elm_frame_smart_calculate(Evas_Object *obj) +_elm_frame_label_set(Evas_Object *obj, const char *item, const char *label) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return; + if (!wd) return; + eina_stringshare_replace(&(wd->label), label); + edje_object_part_text_escaped_set(wd->frm, "elm.text", wd->label); + _sizing_eval(obj); +} + +static const char * +_elm_frame_label_get(const Evas_Object *obj, const char *item) { - ELM_FRAME_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (item && strcmp(item, "default")) return NULL; + return wd->label; +} - if (ELM_LAYOUT_DATA(sd)->needs_size_calc) +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + if (part && strcmp(part, "default")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; + if (content) { - /* calling OWN sizing evaluate code here */ - _sizing_eval(obj, sd); - ELM_LAYOUT_DATA(sd)->needs_size_calc = EINA_FALSE; + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->frm, "elm.swallow.content", content); } + _sizing_eval(obj); } -static void -_elm_frame_smart_add(Evas_Object *obj) +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Frame_Smart_Data); - - ELM_WIDGET_CLASS(_elm_frame_parent_sc)->base.add(obj); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,anim,done", "elm", - _on_recalc_done, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "elm", - _on_frame_clicked, obj); + if (part && strcmp(part, "default")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; - elm_widget_can_focus_set(obj, EINA_FALSE); + return wd->content; +} - elm_layout_theme_set(obj, "frame", "base", elm_widget_style_get(obj)); +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + Evas_Object *content; + if (part && strcmp(part, "default")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd || !wd->content) return NULL; + content = wd->content; + elm_widget_sub_object_del(obj, wd->content); + edje_object_part_unswallow(wd->frm, content); + return content; } static void -_elm_frame_smart_set_user(Elm_Layout_Smart_Class *sc) +_recalc(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_frame_smart_add; - ELM_WIDGET_CLASS(sc)->base.calculate = _elm_frame_smart_calculate; + _sizing_eval(data); +} - ELM_WIDGET_CLASS(sc)->focus_next = _elm_frame_smart_focus_next; +static void +_recalc_done(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *src __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + evas_object_smart_callback_del(wd->frm, "recalc", _recalc); + wd->anim = EINA_FALSE; + _sizing_eval(data); +} - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; +static void +_signal_click(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *src __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (wd->anim) return; + if (wd->collapsible) + { + evas_object_smart_callback_add(wd->frm, "recalc", _recalc, data); + edje_object_signal_emit(wd->frm, "elm,action,toggle", "elm"); + wd->collapsed++; + wd->anim = EINA_TRUE; + } + evas_object_smart_callback_call(data, SIG_CLICKED, NULL); } EAPI Evas_Object * elm_frame_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_frame_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_sizing_eval(obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "frame"); + elm_widget_type_set(obj, "frame"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_focus_next_hook_set(obj, _elm_frame_focus_next_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_text_set_hook_set(obj, _elm_frame_label_set); + elm_widget_text_get_hook_set(obj, _elm_frame_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->frm = edje_object_add(e); + _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); + edje_object_signal_callback_add(wd->frm, "elm,anim,done", "elm", + _recalc_done, obj); + edje_object_signal_callback_add(wd->frm, "elm,action,click", "elm", + _signal_click, obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_frame_autocollapse_set(Evas_Object *obj, - Eina_Bool autocollapse) +elm_frame_autocollapse_set(Evas_Object *obj, Eina_Bool autocollapse) { - ELM_FRAME_CHECK(obj); - ELM_FRAME_DATA_GET_OR_RETURN(obj, sd); - - sd->collapsible = !!autocollapse; + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype); + wd = elm_widget_data_get(obj); + if (!wd) return; + wd->collapsible = !!autocollapse; } EAPI Eina_Bool elm_frame_autocollapse_get(const Evas_Object *obj) { - ELM_FRAME_CHECK(obj) EINA_FALSE; - ELM_FRAME_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->collapsible; + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->collapsible; } EAPI void -elm_frame_collapse_set(Evas_Object *obj, - Eina_Bool collapse) +elm_frame_collapse_set(Evas_Object *obj, Eina_Bool collapse) { - ELM_FRAME_CHECK(obj); - ELM_FRAME_DATA_GET_OR_RETURN(obj, sd); - + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype); + wd = elm_widget_data_get(obj); + if (!wd) return; collapse = !!collapse; - if (sd->collapsed == collapse) return; - - elm_layout_signal_emit(obj, "elm,action,switch", "elm"); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - sd->collapsed = !!collapse; - sd->anim = EINA_FALSE; - - _sizing_eval(obj, sd); + if (wd->collapsed == collapse) return; + edje_object_signal_emit(wd->frm, "elm,action,switch", "elm"); + edje_object_message_signal_process(wd->frm); + wd->collapsed = !!collapse; + wd->anim = EINA_FALSE; + _sizing_eval(obj); } EAPI void -elm_frame_collapse_go(Evas_Object *obj, - Eina_Bool collapse) +elm_frame_collapse_go(Evas_Object *obj, Eina_Bool collapse) { - ELM_FRAME_CHECK(obj); - ELM_FRAME_DATA_GET_OR_RETURN(obj, sd); - + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype); + wd = elm_widget_data_get(obj); + if (!wd) return; collapse = !!collapse; - if (sd->collapsed == collapse) return; - - elm_layout_signal_emit(obj, "elm,action,toggle", "elm"); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(sd)->resize_obj, "recalc", _recalc, obj); - sd->collapsed = collapse; - sd->anim = EINA_TRUE; + if (wd->collapsed == collapse) return; + edje_object_signal_emit(wd->frm, "elm,action,toggle", "elm"); + evas_object_smart_callback_add(wd->frm, "recalc", _recalc, obj); + wd->collapsed = collapse; + wd->anim = EINA_TRUE; } EAPI Eina_Bool elm_frame_collapse_get(const Evas_Object *obj) { - ELM_FRAME_CHECK(obj) EINA_FALSE; - ELM_FRAME_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->collapsed; + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->collapsed; } diff --git a/src/lib/elm_frame.h b/src/lib/elm_frame.h index b02efd9dd..58c3d933f 100644 --- a/src/lib/elm_frame.h +++ b/src/lib/elm_frame.h @@ -19,11 +19,7 @@ * * Of all this styles only default shows the title. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for frame objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * Smart callbacks one can listen to: * - @c "clicked" - The user has clicked the frame's label * * Default content parts of the frame widget that you can use for are: diff --git a/src/lib/elm_glview.c b/src/lib/elm_glview.c index cc51bfbac..339f23fdc 100644 --- a/src/lib/elm_glview.c +++ b/src/lib/elm_glview.c @@ -1,385 +1,330 @@ #include <Elementary.h> #include "elm_priv.h" -static const char GLVIEW_SMART_NAME[] = "elm_glview"; - -#define ELM_GLVIEW_DATA_GET(o, sd) \ - Elm_Glview_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_GLVIEW_DATA_GET_OR_RETURN(o, ptr) \ - ELM_GLVIEW_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_GLVIEW_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_GLVIEW_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_GLVIEW_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), GLVIEW_SMART_NAME, __func__)) \ - return - -typedef struct _Elm_Glview_Smart_Data Elm_Glview_Smart_Data; - -struct _Elm_Glview_Smart_Data +typedef struct _Widget_Data Widget_Data; + +struct _Widget_Data { - Elm_Widget_Smart_Data base; /* base widget smart data as - * first member obligatory, as - * we're inheriting from it */ + Evas_Object *glview_image; - Elm_GLView_Mode mode; - Elm_GLView_Resize_Policy scale_policy; - Elm_GLView_Render_Policy render_policy; + Elm_GLView_Mode mode; + Elm_GLView_Resize_Policy scale_policy; + Elm_GLView_Render_Policy render_policy; - Evas_GL *evasgl; - Evas_GL_Config *config; - Evas_GL_Surface *surface; - Evas_GL_Context *context; + Evas_GL *evasgl; + Evas_GL_Config *config; + Evas_GL_Surface *surface; + Evas_GL_Context *context; - Evas_Coord w, h; + Evas_Coord w, h; - Elm_GLView_Func_Cb init_func; - Elm_GLView_Func_Cb del_func; - Elm_GLView_Func_Cb resize_func; - Elm_GLView_Func_Cb render_func; + Elm_GLView_Func_Cb init_func; + Elm_GLView_Func_Cb del_func; + Elm_GLView_Func_Cb resize_func; + Elm_GLView_Func_Cb render_func; - Ecore_Idle_Enterer *render_idle_enterer; + Ecore_Idle_Enterer *render_idle_enterer; - Eina_Bool initialized : 1; - Eina_Bool resized : 1; + Eina_Bool initialized; + Eina_Bool resized; }; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _on_focus_hook(void *data, Evas_Object *obj); + static const char SIG_FOCUSED[] = "focused"; static const char SIG_UNFOCUSED[] = "unfocused"; -/* smart callbacks coming from elm glview objects: */ -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_FOCUSED, ""}, - {SIG_UNFOCUSED, ""}, - {NULL, NULL} -}; +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; -EVAS_SMART_SUBCLASS_NEW - (GLVIEW_SMART_NAME, _elm_glview, Elm_Widget_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks); + // Call delete func if it's registered + if (wd->del_func) + { + evas_gl_make_current(wd->evasgl, wd->surface, wd->context); + wd->del_func(obj); + } -static Eina_Bool -_elm_glview_smart_on_focus(Evas_Object *obj) + if (wd->render_idle_enterer) ecore_idle_enterer_del(wd->render_idle_enterer); + + if (wd->surface) evas_gl_surface_destroy(wd->evasgl, wd->surface); + if (wd->context) evas_gl_context_destroy(wd->evasgl, wd->context); + if (wd->config) evas_gl_config_free(wd->config); + if (wd->evasgl) evas_gl_free(wd->evasgl); + + free(wd); +} + +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - ELM_GLVIEW_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (elm_widget_focus_get(obj)) { - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); + evas_object_focus_set(wd->glview_image, EINA_TRUE); evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL); } else { - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE); + evas_object_focus_set(wd->glview_image, EINA_FALSE); evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL); } - - return EINA_TRUE; } static void _glview_update_surface(Evas_Object *obj) { - ELM_GLVIEW_DATA_GET(obj, sd); - if (!sd) return; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (sd->surface) + if (wd->surface) { - evas_object_image_native_surface_set - (ELM_WIDGET_DATA(sd)->resize_obj, NULL); - evas_gl_surface_destroy(sd->evasgl, sd->surface); - sd->surface = NULL; + evas_object_image_native_surface_set(wd->glview_image, NULL); + evas_gl_surface_destroy(wd->evasgl, wd->surface); + wd->surface = NULL; } - evas_object_image_size_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->w, sd->h); + evas_object_image_size_set(wd->glview_image, wd->w, wd->h); - if (!sd->surface) + if (!wd->surface) { Evas_Native_Surface ns; - sd->surface = evas_gl_surface_create - (sd->evasgl, sd->config, sd->w, sd->h); - evas_gl_native_surface_get(sd->evasgl, sd->surface, &ns); - evas_object_image_native_surface_set - (ELM_WIDGET_DATA(sd)->resize_obj, &ns); + wd->surface = evas_gl_surface_create(wd->evasgl, wd->config, + wd->w, wd->h); + evas_gl_native_surface_get(wd->evasgl, wd->surface, &ns); + evas_object_image_native_surface_set(wd->glview_image, &ns); elm_glview_changed_set(obj); } } static void -_elm_glview_smart_resize(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +_glview_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_GLVIEW_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(data); + Evas_Coord w, h; - _elm_glview_parent_sc->base.resize(obj, w, h); + if (!wd) return; - sd->resized = EINA_TRUE; + wd->resized = EINA_TRUE; - if (sd->scale_policy == ELM_GLVIEW_RESIZE_POLICY_RECREATE) + if (wd->scale_policy == ELM_GLVIEW_RESIZE_POLICY_RECREATE) { + evas_object_geometry_get(wd->glview_image, NULL, NULL, &w, &h); if ((w == 0) || (h == 0)) { w = 64; h = 64; } - - if ((sd->w == w) && (sd->h == h)) return; - - sd->w = w; - sd->h = h; - - _glview_update_surface(obj); + if ((wd->w == w) && (wd->h == h)) return; + wd->w = w; + wd->h = h; + _glview_update_surface(data); } } static Eina_Bool _render_cb(void *obj) { - ELM_GLVIEW_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; // Do a make current - if (!evas_gl_make_current(sd->evasgl, sd->surface, sd->context)) + if (!evas_gl_make_current(wd->evasgl, wd->surface, wd->context)) { - sd->render_idle_enterer = NULL; + wd->render_idle_enterer = NULL; ERR("Failed doing make current.\n"); return EINA_FALSE; } // Call the init function if it hasn't been called already - if (!sd->initialized) + if (!wd->initialized) { - if (sd->init_func) sd->init_func(obj); - sd->initialized = EINA_TRUE; + if (wd->init_func) wd->init_func(obj); + wd->initialized = EINA_TRUE; } - if (sd->resized) + if (wd->resized) { - if (sd->resize_func) sd->resize_func(obj); - sd->resized = EINA_FALSE; + if (wd->resize_func) wd->resize_func(obj); + wd->resized = EINA_FALSE; } // Call the render function - if (sd->render_func) sd->render_func(obj); + if (wd->render_func) wd->render_func(obj); // Depending on the policy return true or false - if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ON_DEMAND) + if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ON_DEMAND) return EINA_TRUE; - else if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS) + else if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS) { // Return false so it only runs once - sd->render_idle_enterer = NULL; + wd->render_idle_enterer = NULL; return EINA_FALSE; } else { ERR("Invalid Render Policy.\n"); - sd->render_idle_enterer = NULL; + wd->render_idle_enterer = NULL; return EINA_FALSE; } - return EINA_TRUE; } static void _set_render_policy_callback(Evas_Object *obj) { - ELM_GLVIEW_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); - switch (sd->render_policy) + switch (wd->render_policy) { case ELM_GLVIEW_RENDER_POLICY_ON_DEMAND: - // Delete idle_enterer if it for some reason is around - if (sd->render_idle_enterer) - { - ecore_idle_enterer_del(sd->render_idle_enterer); - sd->render_idle_enterer = NULL; - } - - // Set pixel getter callback - evas_object_image_pixels_get_callback_set - (ELM_WIDGET_DATA(sd)->resize_obj, - (Evas_Object_Image_Pixels_Get_Cb)_render_cb, - obj); - break; - + // Delete idle_enterer if it for some reason is around + if (wd->render_idle_enterer) + { + ecore_idle_enterer_del(wd->render_idle_enterer); + wd->render_idle_enterer = NULL; + } + + // Set pixel getter callback + evas_object_image_pixels_get_callback_set + (wd->glview_image, (Evas_Object_Image_Pixels_Get_Cb)_render_cb, obj); + break; case ELM_GLVIEW_RENDER_POLICY_ALWAYS: - // Unset the pixel getter callback if set already - evas_object_image_pixels_get_callback_set - (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL); - - break; + // Unset the pixel getter callback if set already + evas_object_image_pixels_get_callback_set(wd->glview_image, NULL, NULL); + break; default: - ERR("Invalid Render Policy.\n"); - return; + ERR("Invalid Render Policy.\n"); + return; } } -static void -_elm_glview_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Glview_Smart_Data); - - // Create image to render Evas_GL Surface - ELM_WIDGET_DATA(priv)->resize_obj = - evas_object_image_filled_add(evas_object_evas_get(obj)); - evas_object_image_size_set(ELM_WIDGET_DATA(priv)->resize_obj, 1, 1); - - _elm_glview_parent_sc->base.add(obj); -} - -static void -_elm_glview_smart_del(Evas_Object *obj) -{ - ELM_GLVIEW_DATA_GET(obj, sd); - - // Call delete func if it's registered - if (sd->del_func) - { - evas_gl_make_current(sd->evasgl, sd->surface, sd->context); - sd->del_func(obj); - } - - if (sd->render_idle_enterer) ecore_idle_enterer_del(sd->render_idle_enterer); - - if (sd->surface) evas_gl_surface_destroy(sd->evasgl, sd->surface); - if (sd->context) evas_gl_context_destroy(sd->evasgl, sd->context); - if (sd->config) evas_gl_config_free(sd->config); - if (sd->evasgl) evas_gl_free(sd->evasgl); - - _elm_glview_parent_sc->base.del(obj); /* handles freeing sd */ -} - -static void -_elm_glview_smart_set_user(Elm_Widget_Smart_Class *sc) -{ - sc->base.add = _elm_glview_smart_add; - sc->base.del = _elm_glview_smart_del; - sc->base.resize = _elm_glview_smart_resize; - - sc->on_focus = _elm_glview_smart_on_focus; -} - EAPI Evas_Object * elm_glview_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_glview_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_SET_WIDTYPE(widtype, "glview"); + elm_widget_type_set(obj, "glview"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); // Evas_GL - sd->evasgl = evas_gl_new(e); - if (!sd->evasgl) + wd->evasgl = evas_gl_new(e); + if (!wd->evasgl) { ERR("Failed Creating an Evas GL Object.\n"); return NULL; } // Create a default config - sd->config = evas_gl_config_new(); - if (!sd->config) + wd->config = evas_gl_config_new(); + if (!wd->config) { ERR("Failed Creating a Config Object.\n"); - evas_object_del(obj); + evas_gl_free(wd->evasgl); return NULL; } - sd->config->color_format = EVAS_GL_RGB_888; + wd->config->color_format = EVAS_GL_RGB_888; + + // Create image to render Evas_GL Surface + wd->glview_image = evas_object_image_filled_add(e); + evas_object_image_size_set(wd->glview_image, 1, 1); + evas_object_event_callback_add(wd->glview_image, EVAS_CALLBACK_RESIZE, + _glview_resize, obj); + elm_widget_resize_object_set(obj, wd->glview_image); + evas_object_show(wd->glview_image); // Initialize variables - sd->mode = 0; - sd->scale_policy = ELM_GLVIEW_RESIZE_POLICY_RECREATE; - sd->render_policy = ELM_GLVIEW_RENDER_POLICY_ON_DEMAND; - sd->surface = NULL; + wd->mode = 0; + wd->scale_policy = ELM_GLVIEW_RESIZE_POLICY_RECREATE; + wd->render_policy = ELM_GLVIEW_RENDER_POLICY_ON_DEMAND; + wd->surface = NULL; // Initialize it to (64,64) (It's an arbitrary value) - sd->w = 64; - sd->h = 64; + wd->w = 64; + wd->h = 64; // Initialize the rest of the values - sd->init_func = NULL; - sd->del_func = NULL; - sd->render_func = NULL; - sd->render_idle_enterer = NULL; - sd->initialized = EINA_FALSE; - sd->resized = EINA_FALSE; + wd->init_func = NULL; + wd->del_func = NULL; + wd->render_func = NULL; + wd->render_idle_enterer = NULL; + wd->initialized = EINA_FALSE; + wd->resized = EINA_FALSE; // Create Context - sd->context = evas_gl_context_create(sd->evasgl, NULL); - if (!sd->context) + if (!wd->context) { - ERR("Error Creating an Evas_GL Context.\n"); - evas_object_del(obj); - return NULL; + wd->context = evas_gl_context_create(wd->evasgl, NULL); + if (!wd->context) + { + ERR("Error Creating an Evas_GL Context.\n"); + return NULL; + } } - return obj; } EAPI Evas_GL_API * elm_glview_gl_api_get(const Evas_Object *obj) { - ELM_GLVIEW_CHECK(obj) NULL; - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - return evas_gl_api_get(sd->evasgl); + return evas_gl_api_get(wd->evasgl); } EAPI Eina_Bool -elm_glview_mode_set(Evas_Object *obj, - Elm_GLView_Mode mode) +elm_glview_mode_set(Evas_Object *obj, Elm_GLView_Mode mode) { - ELM_GLVIEW_CHECK(obj) EINA_FALSE; - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; // Set the configs - if (mode & ELM_GLVIEW_ALPHA) sd->config->color_format = EVAS_GL_RGBA_8888; - else sd->config->color_format = EVAS_GL_RGB_888; + if (mode & ELM_GLVIEW_ALPHA) + wd->config->color_format = EVAS_GL_RGBA_8888; + else + wd->config->color_format = EVAS_GL_RGB_888; - if (mode & ELM_GLVIEW_DEPTH) sd->config->depth_bits = EVAS_GL_DEPTH_BIT_24; - else sd->config->depth_bits = EVAS_GL_DEPTH_NONE; + if (mode & ELM_GLVIEW_DEPTH) + wd->config->depth_bits = EVAS_GL_DEPTH_BIT_24; + else + wd->config->depth_bits = EVAS_GL_DEPTH_NONE; if (mode & ELM_GLVIEW_STENCIL) - sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8; - else sd->config->stencil_bits = EVAS_GL_STENCIL_NONE; + wd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8; + else + wd->config->stencil_bits = EVAS_GL_STENCIL_NONE; if (mode & ELM_GLVIEW_DIRECT) - sd->config->options_bits = EVAS_GL_OPTIONS_DIRECT; - else sd->config->options_bits = EVAS_GL_OPTIONS_NONE; + wd->config->options_bits = EVAS_GL_OPTIONS_DIRECT; + else + wd->config->options_bits = EVAS_GL_OPTIONS_NONE; // Check for Alpha Channel and enable it if (mode & ELM_GLVIEW_ALPHA) - evas_object_image_alpha_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); + evas_object_image_alpha_set(wd->glview_image, EINA_TRUE); else - evas_object_image_alpha_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE); + evas_object_image_alpha_set(wd->glview_image, EINA_FALSE); - sd->mode = mode; + wd->mode = mode; elm_glview_changed_set(obj); @@ -387,34 +332,33 @@ elm_glview_mode_set(Evas_Object *obj, } EAPI Eina_Bool -elm_glview_resize_policy_set(Evas_Object *obj, - Elm_GLView_Resize_Policy policy) +elm_glview_resize_policy_set(Evas_Object *obj, Elm_GLView_Resize_Policy policy) { - ELM_GLVIEW_CHECK(obj) EINA_FALSE; - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - if (policy == sd->scale_policy) return EINA_TRUE; + if (policy == wd->scale_policy) return EINA_TRUE; switch (policy) { case ELM_GLVIEW_RESIZE_POLICY_RECREATE: case ELM_GLVIEW_RESIZE_POLICY_SCALE: - sd->scale_policy = policy; - _glview_update_surface(obj); - elm_glview_changed_set(obj); - return EINA_TRUE; - + wd->scale_policy = policy; + _glview_update_surface(obj); + elm_glview_changed_set(obj); + return EINA_TRUE; default: - ERR("Invalid Scale Policy.\n"); - return EINA_FALSE; + ERR("Invalid Scale Policy.\n"); + return EINA_FALSE; } } EAPI Eina_Bool -elm_glview_render_policy_set(Evas_Object *obj, - Elm_GLView_Render_Policy policy) +elm_glview_render_policy_set(Evas_Object *obj, Elm_GLView_Render_Policy policy) { - ELM_GLVIEW_CHECK(obj) EINA_FALSE; - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; if ((policy != ELM_GLVIEW_RENDER_POLICY_ON_DEMAND) && (policy != ELM_GLVIEW_RENDER_POLICY_ALWAYS)) @@ -422,97 +366,97 @@ elm_glview_render_policy_set(Evas_Object *obj, ERR("Invalid Render Policy.\n"); return EINA_FALSE; } - - if (sd->render_policy == policy) return EINA_TRUE; - - sd->render_policy = policy; + if (wd->render_policy == policy) return EINA_TRUE; + wd->render_policy = policy; _set_render_policy_callback(obj); _glview_update_surface(obj); - return EINA_TRUE; } EAPI void -elm_glview_size_set(Evas_Object *obj, - int w, - int h) +elm_glview_size_set(Evas_Object *obj, int w, int h) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); - - if ((w == sd->w) && (h == sd->h)) return; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - sd->w = w; - sd->h = h; + if ((w == wd->w) && (h == wd->h)) return; + wd->w = w; + wd->h = h; _glview_update_surface(obj); - elm_glview_changed_set(obj); } EAPI void -elm_glview_size_get(const Evas_Object *obj, - int *w, - int *h) +elm_glview_size_get(const Evas_Object *obj, int *w, int *h) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (w) *w = sd->w; - if (h) *h = sd->h; + if (w) *w = wd->w; + if (h) *h = wd->h; } EAPI void -elm_glview_init_func_set(Evas_Object *obj, - Elm_GLView_Func_Cb func) +elm_glview_init_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - sd->initialized = EINA_FALSE; - sd->init_func = func; + wd->initialized = EINA_FALSE; + wd->init_func = func; } EAPI void -elm_glview_del_func_set(Evas_Object *obj, - Elm_GLView_Func_Cb func) +elm_glview_del_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - sd->del_func = func; + wd->del_func = func; } EAPI void -elm_glview_resize_func_set(Evas_Object *obj, - Elm_GLView_Func_Cb func) +elm_glview_resize_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + { + ERR("Invalid Widget Object.\n"); + return; + } - sd->resize_func = func; + wd->resize_func = func; } EAPI void -elm_glview_render_func_set(Evas_Object *obj, - Elm_GLView_Func_Cb func) +elm_glview_render_func_set(Evas_Object *obj, Elm_GLView_Func_Cb func) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - sd->render_func = func; + wd->render_func = func; _set_render_policy_callback(obj); } EAPI void elm_glview_changed_set(Evas_Object *obj) { - ELM_GLVIEW_CHECK(obj); - ELM_GLVIEW_DATA_GET(obj, sd); - - evas_object_image_pixels_dirty_set - (ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); - if (sd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS && - !sd->render_idle_enterer) - sd->render_idle_enterer = - ecore_idle_enterer_before_add((Ecore_Task_Cb)_render_cb, obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + evas_object_image_pixels_dirty_set(wd->glview_image, EINA_TRUE); + if (wd->render_policy == ELM_GLVIEW_RENDER_POLICY_ALWAYS) + { + if (!wd->render_idle_enterer) + wd->render_idle_enterer = ecore_idle_enterer_before_add((Ecore_Task_Cb)_render_cb, obj); + } } + +/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/ diff --git a/src/lib/elm_grid.c b/src/lib/elm_grid.c index f166e952f..22f1b232d 100644 --- a/src/lib/elm_grid.c +++ b/src/lib/elm_grid.c @@ -1,50 +1,35 @@ #include <Elementary.h> #include "elm_priv.h" -static const char GRID_SMART_NAME[] = "elm_grid"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Grid_Smart_Data Elm_Grid_Smart_Data; - -#define ELM_GRID_DATA_GET(o, sd) \ - Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_GRID_DATA_GET_OR_RETURN(o, ptr) \ - ELM_GRID_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_GRID_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_GRID_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } +struct _Widget_Data +{ + Evas_Object *obj, *grd; +}; -#define ELM_GRID_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), GRID_SMART_NAME, __func__)) \ - return +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); -EVAS_SMART_SUBCLASS_NEW - (GRID_SMART_NAME, _elm_grid, Elm_Widget_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL); +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} static Eina_Bool -_elm_grid_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_grid_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - Eina_Bool ret; + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *items; - Eina_List *(*list_free)(Eina_List *list); - void *(*list_data_get)(const Eina_List *list); + void *(*list_data_get) (const Eina_List *list); + Eina_List *(*list_free) (Eina_List *list); - ELM_GRID_DATA_GET(obj, sd); + if ((!wd) || (!wd->grd)) + return EINA_FALSE; /* Focus chain */ /* TODO: Change this to use other chain */ @@ -55,16 +40,18 @@ _elm_grid_smart_focus_next(const Evas_Object *obj, } else { - items = evas_object_grid_children_get(sd->resize_obj); + items = evas_object_grid_children_get(wd->grd); list_data_get = eina_list_data_get; list_free = eina_list_free; if (!items) return EINA_FALSE; } - ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next); + Eina_Bool ret = elm_widget_focus_list_next_get(obj, items, list_data_get, + dir, next); - if (list_free) list_free((Eina_List *)items); + if (list_free) + list_free((Eina_List *)items); return ret; } @@ -72,190 +59,119 @@ _elm_grid_smart_focus_next(const Evas_Object *obj, static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_GRID_DATA_GET(obj, sd); - - evas_object_grid_mirrored_set(sd->resize_obj, rtl); -} - -static Eina_Bool -_elm_grid_smart_theme(Evas_Object *obj) -{ - if (!_elm_grid_parent_sc->theme(obj)) return EINA_FALSE; - - _mirrored_set(obj, elm_widget_mirrored_get(obj)); - - return EINA_TRUE; -} - -static void -_elm_grid_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data); - - priv->resize_obj = evas_object_grid_add(evas_object_evas_get(obj)); - evas_object_grid_size_set(priv->resize_obj, 100, 100); - - _elm_grid_parent_sc->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); - - _elm_grid_smart_theme(obj); -} - -static void -_elm_grid_smart_del(Evas_Object *obj) -{ - Eina_List *l; - Evas_Object *child; - - ELM_GRID_DATA_GET(obj, sd); - - /* let's make our grid object the *last* to be processed, since it - * may (smart) parent other sub objects here */ - EINA_LIST_FOREACH (sd->subobjs, l, child) - { - if (child == sd->resize_obj) - { - sd->subobjs = eina_list_demote_list(sd->subobjs, l); - break; - } - } - - _elm_grid_parent_sc->base.del(obj); + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (!wd->grd)) return; + evas_object_grid_mirrored_set(wd->grd, rtl); } static void -_elm_grid_smart_set_user(Elm_Widget_Smart_Class *sc) +_theme_hook(Evas_Object *obj) { - sc->base.add = _elm_grid_smart_add; - sc->base.del = _elm_grid_smart_del; - - sc->theme = _elm_grid_smart_theme; - sc->focus_next = _elm_grid_smart_focus_next; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); } EAPI Evas_Object * elm_grid_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "grid"); + elm_widget_type_set(obj, "grid"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_focus_next_hook_set(obj, _elm_grid_focus_next_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_theme_hook_set(obj, _theme_hook); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_grid_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + wd->grd = evas_object_grid_add(e); + evas_object_grid_size_set(wd->grd, 100, 100); + elm_widget_resize_object_set(obj, wd->grd); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); return obj; } EAPI void -elm_grid_size_set(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +elm_grid_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - - evas_object_grid_size_set(sd->resize_obj, w, h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_grid_size_set(wd->grd, w, h); } EAPI void -elm_grid_size_get(const Evas_Object *obj, - Evas_Coord *w, - Evas_Coord *h) +elm_grid_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) { - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - - evas_object_grid_size_get(sd->resize_obj, w, h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_grid_size_get(wd->grd, w, h); } EAPI void -elm_grid_pack(Evas_Object *obj, - Evas_Object *subobj, - Evas_Coord x, - Evas_Coord y, - Evas_Coord w, - Evas_Coord h) +elm_grid_pack(Evas_Object *obj, Evas_Object *subobj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_grid_pack(sd->resize_obj, subobj, x, y, w, h); + evas_object_grid_pack(wd->grd, subobj, x, y, w, h); } EAPI void -elm_grid_unpack(Evas_Object *obj, - Evas_Object *subobj) +elm_grid_unpack(Evas_Object *obj, Evas_Object *subobj) { - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_del(obj, subobj); - evas_object_grid_unpack(sd->resize_obj, subobj); + evas_object_grid_unpack(wd->grd, subobj); } EAPI void -elm_grid_clear(Evas_Object *obj, - Eina_Bool clear) +elm_grid_clear(Evas_Object *obj, Eina_Bool clear) { Eina_List *chld; Evas_Object *o; - - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - - if (!clear) - { - chld = evas_object_grid_children_get(sd->resize_obj); - EINA_LIST_FREE (chld, o) - elm_widget_sub_object_del(obj, o); - } - - evas_object_grid_clear(sd->resize_obj, clear); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + chld = evas_object_grid_children_get(wd->grd); + EINA_LIST_FREE(chld, o) elm_widget_sub_object_del(obj, o); + evas_object_grid_clear(wd->grd, clear); } EAPI void -elm_grid_pack_set(Evas_Object *subobj, - Evas_Coord x, - Evas_Coord y, - Evas_Coord w, - Evas_Coord h) +elm_grid_pack_set(Evas_Object *subobj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { Evas_Object *obj = elm_widget_parent_widget_get(subobj); - - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - - evas_object_grid_pack(sd->resize_obj, subobj, x, y, w, h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_grid_pack(wd->grd, subobj, x, y, w, h); } EAPI void -elm_grid_pack_get(Evas_Object *subobj, - int *x, - int *y, - int *w, - int *h) +elm_grid_pack_get(Evas_Object *subobj, int *x, int *y, int *w, int *h) { Evas_Object *obj = elm_widget_parent_widget_get(subobj); - - ELM_GRID_CHECK(obj); - ELM_GRID_DATA_GET(obj, sd); - - evas_object_grid_pack_get(sd->resize_obj, subobj, x, y, w, h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_grid_pack_get(wd->grd, subobj, x, y, w, h); } EAPI Eina_List * elm_grid_children_get(const Evas_Object *obj) { - ELM_GRID_CHECK(obj) NULL; - ELM_GRID_DATA_GET(obj, sd); - - return evas_object_grid_children_get(sd->resize_obj); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return evas_object_grid_children_get(wd->grd); } diff --git a/src/lib/elm_hover.c b/src/lib/elm_hover.c index 6fe2413b8..ec92a9c4c 100644 --- a/src/lib/elm_hover.c +++ b/src/lib/elm_hover.c @@ -1,219 +1,276 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char HOVER_SMART_NAME[] = "elm_hover"; - -typedef struct _Elm_Hover_Smart_Data Elm_Hover_Smart_Data; -typedef struct _Content_Info Content_Info; +typedef struct _Widget_Data Widget_Data; +typedef struct _Content_Info Content_Info; #ifndef MAX # define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif -#define ELM_HOVER_PARTS_FOREACH unsigned int i; \ - for (i = 0; i < sizeof(sd->subs) / sizeof(sd->subs[0]); i++) - -#define _HOV_LEFT (&(sd->subs[0])) -#define _HOV_TOP_LEFT (&(sd->subs[1])) -#define _HOV_TOP (&(sd->subs[2])) -#define _HOV_TOP_RIGHT (&(sd->subs[2])) -#define _HOV_RIGHT (&(sd->subs[4])) -#define _HOV_BOTTOM_RIGHT (&(sd->subs[5])) -#define _HOV_BOTTOM (&(sd->subs[6])) -#define _HOV_BOTTOM_LEFT (&(sd->subs[7])) -#define _HOV_MIDDLE (&(sd->subs[8])) - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"left", "elm.swallow.slot.left"}, - {"top-left", "elm.swallow.slot.top-left"}, - {"top", "elm.swallow.slot.top"}, - {"top-right", "elm.swallow.slot.top-right"}, - {"right", "elm.swallow.slot.right"}, - {"bottom-right", "elm.swallow.slot.bottom-right"}, - {"bottom", "elm.swallow.slot.bottom"}, - {"bottom-left", "elm.swallow.slot.bottom-left"}, - {"middle", "elm.swallow.slot.middle"}, - {NULL, NULL} +#define ELM_HOVER_PARTS_FOREACH unsigned int i = 0; \ + for (i = 0; i < sizeof(wd->subs) / sizeof(wd->subs[0]); i++) + +static const char *_directions[] = { + "left", + "top-left", + "top", + "top-right", + "right", + "bottom-right", + "bottom", + "bottom-left", + "middle" }; +#define _HOV_LEFT (_directions[0]) +#define _HOV_TOP_LEFT (_directions[1]) +#define _HOV_TOP (_directions[2]) +#define _HOV_TOP_RIGHT (_directions[2]) +#define _HOV_RIGHT (_directions[4]) +#define _HOV_BOTTOM_RIGHT (_directions[5]) +#define _HOV_BOTTOM (_directions[6]) +#define _HOV_BOTTOM_LEFT (_directions[7]) +#define _HOV_MIDDLE (_directions[8]) + struct _Content_Info { - const char *swallow; + const char *swallow; Evas_Object *obj; }; -struct _Elm_Hover_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *offset, *size; - Evas_Object *parent, *target; - - Content_Info *smt_sub; /* 'smart placement' sub object */ - Content_Info subs[sizeof(_content_aliases) / - sizeof(_content_aliases[0]) - 1]; - - Eina_Bool on_del : 1; + Evas_Object *hov, *cov; + Evas_Object *offset, *size; + Evas_Object *parent, *target; + Evas_Object *smt_sub; + Content_Info subs[sizeof(_directions)/sizeof(_directions[0])]; }; +static const char *widtype = NULL; +static void _del_pre_hook(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _reval_content(Evas_Object *obj); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _hov_show_do(Evas_Object *obj); +static void _hov_move(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _hov_resize(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _hov_show(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _hov_hide(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_hover_sub_obj_placement_eval(Evas_Object *obj); +static void _content_set_hook(Evas_Object *obj, const char *swallow, Evas_Object *content); +static Evas_Object * _content_get_hook(const Evas_Object *obj, const char *swallow); +static Evas_Object * _content_unset_hook(Evas_Object *obj, const char *swallow); + static const char SIG_CLICKED[] = "clicked"; static const char SIG_SMART_LOCATION_CHANGED[] = "smart,changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CLICKED, ""}, - {SIG_SMART_LOCATION_CHANGED, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CLICKED, ""}, + {SIG_SMART_LOCATION_CHANGED, ""}, + {NULL, NULL} }; -#define ELM_HOVER_DATA_GET(o, sd) \ - Elm_Hover_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_HOVER_DATA_GET_OR_RETURN(o, ptr) \ - ELM_HOVER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_HOVER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_HOVER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_HOVER_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), HOVER_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (HOVER_SMART_NAME, _elm_hover, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return; + + if (evas_object_visible_get(obj)) + evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); + elm_hover_target_set(obj, NULL); + elm_hover_parent_set(obj, NULL); + evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj); + evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj); + evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj); + evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj); +} static void -_parent_move_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_del_hook(Evas_Object *obj) { - elm_layout_sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); } static void -_parent_resize_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - elm_layout_sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->cov, "elm,action,focus", "elm"); + evas_object_focus_set(wd->cov, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->cov, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->cov, EINA_FALSE); + } } static void -_parent_show_cb(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->cov, rtl); } static void -_parent_hide_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + // FIXME: hover contents doesn't seem to propagate resizes properly + _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); + + if (wd->smt_sub) + _elm_hover_sub_obj_placement_eval(obj); + else + _reval_content(obj); + _sizing_eval(obj); + if (evas_object_visible_get(wd->cov)) _hov_show_do(obj); +} + +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) { - evas_object_hide(data); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) + return; + + edje_object_signal_emit(wd->cov, emission, source); } static void -_parent_del_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) { - elm_hover_parent_set(data, NULL); - elm_layout_sizing_eval(data); + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) + return; + + edje_object_signal_callback_add(wd->hov, emission, source, func_cb, data); } static void -_elm_hover_parent_detach(Evas_Object *obj) +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) { - ELM_HOVER_DATA_GET(obj, sd); + Widget_Data *wd; - if (sd->parent) - { - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_MOVE, _parent_move_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_RESIZE, _parent_resize_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_SHOW, _parent_show_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj); - } + wd = elm_widget_data_get(obj); + + edje_object_signal_callback_del_full(wd->hov, emission, source, func_cb, + data); } static void -_elm_hover_left_space_calc(Elm_Hover_Smart_Data *sd, - Evas_Coord *spc_l, - Evas_Coord *spc_t, - Evas_Coord *spc_r, - Evas_Coord *spc_b) +_elm_hover_left_space_calc(Widget_Data *wd, Evas_Coord *spc_l, Evas_Coord *spc_t, Evas_Coord *spc_r, Evas_Coord *spc_b) { Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0; - if (sd->parent) evas_object_geometry_get(sd->parent, &x, &y, &w, &h); - if (sd->target) evas_object_geometry_get(sd->target, &x2, &y2, &w2, &h2); + if (wd->parent) + evas_object_geometry_get(wd->parent, &x, &y, &w, &h); + if (wd->target) + evas_object_geometry_get(wd->target, &x2, &y2, &w2, &h2); *spc_l = x2 - x; *spc_r = (x + w) - (x2 + w2); - if (*spc_l < 0) *spc_l = 0; - if (*spc_r < 0) *spc_r = 0; + if (*spc_l < 0) + *spc_l = 0; + if (*spc_r < 0) + *spc_r = 0; *spc_t = y2 - y; *spc_b = (y + h) - (y2 + h2); - if (*spc_t < 0) *spc_t = 0; - if (*spc_b < 0) *spc_b = 0; + if (*spc_t < 0) + *spc_t = 0; + if (*spc_b < 0) + *spc_b = 0; +} + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord ofs_x, x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0; + if (!wd) return; + if (wd->parent) evas_object_geometry_get(wd->parent, &x, &y, &w, &h); + if (wd->hov) evas_object_geometry_get(wd->hov, &x2, &y2, &w2, &h2); + + if (elm_widget_mirrored_get(obj)) + ofs_x = w - (x2 - x) - w2; + else + ofs_x = x2 - x; + + evas_object_move(wd->cov, x, y); + evas_object_resize(wd->cov, w, h); + evas_object_size_hint_min_set(wd->offset, ofs_x, y2 - y); + evas_object_size_hint_min_set(wd->size, w2, h2); + edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset); + edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size); +} + +static void +_reval_content(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return; + + ELM_HOVER_PARTS_FOREACH + { + char buf[1024]; + snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", wd->subs[i].swallow); + edje_object_part_swallow(wd->cov, buf, wd->subs[i].obj); + } } -static Content_Info * -_elm_hover_smart_content_location_get(Elm_Hover_Smart_Data *sd, - Evas_Coord spc_l, - Evas_Coord spc_t, - Evas_Coord spc_r, - Evas_Coord spc_b) +static const char * +_elm_hover_smart_content_location_get(Widget_Data *wd, Evas_Coord spc_l, Evas_Coord spc_t, Evas_Coord spc_r, Evas_Coord spc_b) { Evas_Coord c_w = 0, c_h = 0, mid_w, mid_h; int max; - evas_object_size_hint_min_get(sd->smt_sub->obj, &c_w, &c_h); + evas_object_size_hint_min_get(wd->smt_sub, &c_w, &c_h); mid_w = c_w / 2; mid_h = c_h / 2; - if (spc_l > spc_r) goto left; + if (spc_l > spc_r) + goto left; max = MAX(spc_t, spc_r); max = MAX(max, spc_b); if (max == spc_t) { - if (mid_w > spc_l) return _HOV_TOP_RIGHT; + if (mid_w > spc_l) + return _HOV_TOP_RIGHT; return _HOV_TOP; } if (max == spc_r) { - if (mid_h > spc_t) return _HOV_BOTTOM_RIGHT; + if (mid_h > spc_t) + return _HOV_BOTTOM_RIGHT; else if (mid_h > spc_b) return _HOV_TOP_RIGHT; @@ -231,594 +288,565 @@ left: if (max == spc_t) { - if (mid_w > spc_r) return _HOV_TOP_LEFT; + if (mid_w > spc_r) + return _HOV_TOP_LEFT; return _HOV_TOP; } if (max == spc_l) { - if (mid_h > spc_t) return _HOV_BOTTOM_LEFT; + if (mid_h > spc_t) + return _HOV_BOTTOM_LEFT; else if (mid_h > spc_b) return _HOV_TOP_LEFT; return _HOV_LEFT; } - if (mid_h > spc_r) return _HOV_BOTTOM_LEFT; + if (mid_h > spc_r) + return _HOV_BOTTOM_LEFT; return _HOV_BOTTOM; } static void -_elm_hover_smt_sub_re_eval(Evas_Object *obj) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { - Evas_Coord spc_l, spc_r, spc_t, spc_b; - Content_Info *prev; + Widget_Data *wd; Evas_Object *sub; - char buf[1024]; - - ELM_HOVER_DATA_GET(obj, sd); - - if (!sd->smt_sub) return; - prev = sd->smt_sub; - - _elm_hover_left_space_calc(sd, &spc_l, &spc_t, &spc_r, &spc_b); - elm_layout_content_unset(obj, sd->smt_sub->swallow); - sub = sd->smt_sub->obj; + sub = event_info; + wd = elm_widget_data_get(obj); + if (!wd) + return; - sd->smt_sub->obj = NULL; - - sd->smt_sub = - _elm_hover_smart_content_location_get(sd, spc_l, spc_t, spc_r, spc_b); - - sd->smt_sub->obj = sub; - - if (sd->smt_sub != prev) - evas_object_smart_callback_call - (obj, SIG_SMART_LOCATION_CHANGED, (void *)sd->smt_sub->swallow); - - if (elm_widget_mirrored_get(obj)) + if (wd->smt_sub) { - if (sd->smt_sub == _HOV_BOTTOM_LEFT) sd->smt_sub = _HOV_BOTTOM_RIGHT; - else if (sd->smt_sub == _HOV_BOTTOM_RIGHT) - sd->smt_sub = _HOV_BOTTOM_LEFT; - else if (sd->smt_sub == _HOV_RIGHT) - sd->smt_sub = _HOV_LEFT; - else if (sd->smt_sub == _HOV_LEFT) - sd->smt_sub = _HOV_RIGHT; - else if (sd->smt_sub == _HOV_TOP_RIGHT) - sd->smt_sub = _HOV_TOP_LEFT; - else if (sd->smt_sub == _HOV_TOP_LEFT) - sd->smt_sub = _HOV_TOP_RIGHT; + if (wd->smt_sub == sub) + wd->smt_sub = NULL; + } + else + { + ELM_HOVER_PARTS_FOREACH + { + if (wd->subs[i].obj == sub) + { + wd->subs[i].obj = NULL; + break; + } + } } - - snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", sd->smt_sub->swallow); - elm_layout_content_set(obj, buf, sd->smt_sub->obj); } static void _hov_show_do(Evas_Object *obj) { - ELM_HOVER_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) + return; - elm_layout_signal_emit(obj, "elm,action,show", "elm"); + if (wd->cov) + { + evas_object_show(wd->cov); + edje_object_signal_emit(wd->cov, "elm,action,show", "elm"); + } ELM_HOVER_PARTS_FOREACH - { - char buf[1024]; - - if (sd->subs[i].obj) - { - snprintf - (buf, sizeof(buf), "elm,action,slot,%s,show", - sd->subs[i].swallow); - - elm_layout_signal_emit(obj, buf, "elm"); - } - } -} - -static Eina_Bool -_elm_hover_smart_theme(Evas_Object *obj) -{ - ELM_HOVER_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_hover_parent_sc)->theme(obj)) return EINA_FALSE; - - if (sd->smt_sub) _elm_hover_smt_sub_re_eval(obj); - - elm_layout_sizing_eval(obj); - - if (evas_object_visible_get(obj)) _hov_show_do(obj); + { + char buf[1024]; - return EINA_TRUE; + if (wd->subs[i].obj) + { + snprintf(buf, sizeof(buf), "elm,action,slot,%s,show", + wd->subs[i].swallow); + edje_object_signal_emit(wd->cov, buf, "elm"); + } + } } static void -_elm_hover_smart_sizing_eval(Evas_Object *obj) +_hov_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Evas_Coord ofs_x, x = 0, y = 0, w = 0, h = 0, x2 = 0, - y2 = 0, w2 = 0, h2 = 0; - - ELM_HOVER_DATA_GET(obj, sd); - - if (sd->on_del) return; - - if (sd->parent) evas_object_geometry_get(sd->parent, &x, &y, &w, &h); - evas_object_geometry_get(obj, &x2, &y2, &w2, &h2); - - if (elm_widget_mirrored_get(obj)) ofs_x = w - (x2 - x) - w2; - else ofs_x = x2 - x; - - evas_object_move(ELM_WIDGET_DATA(sd)->resize_obj, x, y); - evas_object_resize(ELM_WIDGET_DATA(sd)->resize_obj, w, h); - evas_object_size_hint_min_set(sd->offset, ofs_x, y2 - y); - evas_object_size_hint_min_set(sd->size, w2, h2); + _sizing_eval(data); } static void -_on_smt_sub_changed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_hov_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - _elm_hover_smt_sub_re_eval(data); + _sizing_eval(data); } -static Eina_Bool -_elm_hover_smart_sub_object_add(Evas_Object *obj, - Evas_Object *sobj) +static void +_hov_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_HOVER_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_hover_parent_sc)->sub_object_add(obj, sobj)) - return EINA_FALSE; - - if (sd->smt_sub && sd->smt_sub->obj == sobj) - evas_object_event_callback_add - (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_smt_sub_changed, obj); - - return EINA_TRUE; + _hov_show_do(data); } -static Eina_Bool -_elm_hover_smart_sub_object_del(Evas_Object *obj, - Evas_Object *sobj) +static void +_hov_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_HOVER_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_hover_parent_sc)->sub_object_del(obj, sobj)) - return EINA_FALSE; - - if (sd->smt_sub && sd->smt_sub->obj == sobj) - { - evas_object_event_callback_del_full - (sd->smt_sub->obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_smt_sub_changed, obj); - - sd->smt_sub->obj = NULL; - sd->smt_sub = NULL; - } - else + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (wd->cov) { - ELM_HOVER_PARTS_FOREACH - { - if (sd->subs[i].obj == sobj) - { - sd->subs[i].obj = NULL; - break; - } - } + edje_object_signal_emit(wd->cov, "elm,action,hide", "elm"); + evas_object_hide(wd->cov); } - return EINA_TRUE; -} - -static void -_elm_hover_subs_del(Elm_Hover_Smart_Data *sd) -{ ELM_HOVER_PARTS_FOREACH - { - if (sd->subs[i].obj) - { - evas_object_del(sd->subs[i].obj); - sd->subs[i].obj = NULL; - } - } -} - -static Eina_Bool -_elm_hover_smart_content_set(Evas_Object *obj, - const char *swallow, - Evas_Object *content) -{ - ELM_HOVER_CHECK(obj) EINA_FALSE; - ELM_HOVER_DATA_GET(obj, sd); - - if (!swallow) return EINA_FALSE; - - if (!strcmp(swallow, "smart")) { - if (sd->smt_sub) /* already under 'smart' mode */ - { - if (sd->smt_sub->obj != content) - { - evas_object_del(sd->smt_sub->obj); - sd->smt_sub = _HOV_LEFT; - sd->smt_sub->obj = content; - } + char buf[1024]; - if (!content) - { - sd->smt_sub->obj = NULL; - sd->smt_sub = NULL; - } - else _elm_hover_smt_sub_re_eval(obj); - - goto end; - } - else /* switch from pristine spots to 'smart' */ + if (wd->subs[i].obj) { - _elm_hover_subs_del(sd); - sd->smt_sub = _HOV_LEFT; - sd->smt_sub->obj = content; - - _elm_hover_smt_sub_re_eval(obj); - - goto end; + snprintf(buf, sizeof(buf), "elm,action,slot,%s,hide", + wd->subs[i].swallow); + edje_object_signal_emit(wd->cov, buf, "elm"); } } - - if (!ELM_CONTAINER_CLASS(_elm_hover_parent_sc)->content_set - (obj, swallow, content)) - return EINA_FALSE; - - if (strstr(swallow, "elm.swallow.slot.")) - swallow += sizeof("elm.swallow.slot."); - - ELM_HOVER_PARTS_FOREACH - { - if (!strcmp(swallow, sd->subs[i].swallow)) - { - sd->subs[i].obj = content; - break; - } - } - -end: - elm_layout_sizing_eval(obj); - return EINA_TRUE; } -static Evas_Object * -_elm_hover_smart_content_get(const Evas_Object *obj, - const char *swallow) +static void +_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_HOVER_CHECK(obj) NULL; - - ELM_HOVER_DATA_GET(obj, sd); - - if (!swallow) return NULL; - - if (!strcmp(swallow, "smart")) - return ELM_CONTAINER_CLASS(_elm_hover_parent_sc)->content_get - (obj, sd->smt_sub->swallow); - - return ELM_CONTAINER_CLASS(_elm_hover_parent_sc)->content_get(obj, swallow); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->target = NULL; } -static Evas_Object * -_elm_hover_smart_content_unset(Evas_Object *obj, - const char *swallow) +static void +_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_HOVER_CHECK(obj) NULL; - - ELM_HOVER_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) + return; - if (!swallow) return NULL; - - if (!strcmp(swallow, "smart")) - return ELM_CONTAINER_CLASS(_elm_hover_parent_sc)->content_unset - (obj, sd->smt_sub->swallow); - - return ELM_CONTAINER_CLASS(_elm_hover_parent_sc)->content_unset - (obj, swallow); - - return NULL; + _sizing_eval(data); + _elm_hover_sub_obj_placement_eval(data); } static void -_target_del_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_signal_dismiss(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_HOVER_DATA_GET(data, sd); - - sd->target = NULL; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + evas_object_hide(data); + evas_object_smart_callback_call(data, SIG_CLICKED, NULL); } static void -_target_move_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_parent_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_sizing_eval(data); - _elm_hover_smt_sub_re_eval(data); + _sizing_eval(data); } static void -_hov_dismiss_cb(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - evas_object_hide(data); - evas_object_smart_callback_call(data, SIG_CLICKED, NULL); + _sizing_eval(data); } static void -_elm_hover_smart_add(Evas_Object *obj) +_parent_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - unsigned int i; - - EVAS_SMART_DATA_ALLOC(obj, Elm_Hover_Smart_Data); - - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.add(obj); +} - for (i = 0; i < sizeof(priv->subs) / sizeof(priv->subs[0]); i++) - priv->subs[i].swallow = _content_aliases[i].alias; +static void +_parent_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + evas_object_hide(wd->cov); +} - elm_layout_theme_set(obj, "hover", "base", elm_widget_style_get(obj)); - elm_layout_signal_callback_add - (obj, "elm,action,dismiss", "", _hov_dismiss_cb, obj); +static void +_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + elm_hover_parent_set(data, NULL); + _sizing_eval(data); +} - priv->offset = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_pass_events_set(priv->offset, EINA_TRUE); - evas_object_color_set(priv->offset, 0, 0, 0, 0); +EAPI Evas_Object * +elm_hover_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "hover"); + elm_widget_type_set(obj, "hover"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); - priv->size = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_pass_events_set(priv->size, EINA_TRUE); - evas_object_color_set(priv->size, 0, 0, 0, 0); + ELM_HOVER_PARTS_FOREACH + wd->subs[i].swallow = _directions[i]; + + wd->hov = evas_object_rectangle_add(e); + evas_object_pass_events_set(wd->hov, EINA_TRUE); + evas_object_color_set(wd->hov, 0, 0, 0, 0); + elm_widget_resize_object_set(obj, wd->hov); + evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj); + evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj); + evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj); + evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj); + + wd->cov = edje_object_add(e); + _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); + + wd->offset = evas_object_rectangle_add(e); + evas_object_pass_events_set(wd->offset, EINA_TRUE); + evas_object_color_set(wd->offset, 0, 0, 0, 0); + elm_widget_sub_object_add(obj, wd->offset); + + wd->size = evas_object_rectangle_add(e); + evas_object_pass_events_set(wd->size, EINA_TRUE); + evas_object_color_set(wd->size, 0, 0, 0, 0); + elm_widget_sub_object_add(obj, wd->size); + + edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset); + edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); - elm_layout_content_set(obj, "elm.swallow.offset", priv->offset); - elm_layout_content_set(obj, "elm.swallow.size", priv->size); + elm_hover_parent_set(obj, parent); + evas_object_smart_callbacks_descriptions_set(obj, _signals); - elm_widget_can_focus_set(obj, EINA_TRUE); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + return obj; } -static void -_elm_hover_smart_del(Evas_Object *obj) +EAPI void +elm_hover_target_set(Evas_Object *obj, Evas_Object *target) { - ELM_HOVER_DATA_GET(obj, sd); - - sd->on_del = EINA_TRUE; - - if (evas_object_visible_get(obj)) - evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - elm_hover_target_set(obj, NULL); + if (wd->target) + { + evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_DEL, + _target_del, obj); + evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_MOVE, + _target_move, obj); + } + wd->target = target; + if (wd->target) + { + evas_object_event_callback_add(wd->target, EVAS_CALLBACK_DEL, + _target_del, obj); + evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOVE, + _target_move, obj); + elm_widget_hover_object_set(target, obj); + _sizing_eval(obj); + } +} - _elm_hover_parent_detach(obj); - sd->parent = NULL; - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.del(obj); +EAPI void +elm_hover_parent_set(Evas_Object *obj, Evas_Object *parent) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->parent) + { + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE, + _parent_move, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, + _parent_resize, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_SHOW, + _parent_show, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE, + _parent_hide, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL, + _parent_del, obj); + } + wd->parent = parent; + if (wd->parent) + { + evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_MOVE, + _parent_move, obj); + evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_RESIZE, + _parent_resize, obj); + evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_SHOW, + _parent_show, obj); + evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_HIDE, + _parent_hide, obj); + evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_DEL, + _parent_del, obj); + // elm_widget_sub_object_add(parent, obj); + } + _sizing_eval(obj); } -static void -_elm_hover_smart_move(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +EAPI Evas_Object * +elm_hover_target_get(const Evas_Object *obj) { - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.move(obj, x, y); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - elm_layout_sizing_eval(obj); + return wd->target; } -static void -_elm_hover_smart_resize(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +EAPI Evas_Object * +elm_hover_parent_get(const Evas_Object *obj) { - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.resize(obj, w, h); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - elm_layout_sizing_eval(obj); + return wd->parent; } static void -_elm_hover_smart_show(Evas_Object *obj) +_elm_hover_subs_del(Widget_Data *wd) { - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.show(obj); - - _hov_show_do(obj); + ELM_HOVER_PARTS_FOREACH + { + if (wd->subs[i].obj) + { + evas_object_del(wd->subs[i].obj); + wd->subs[i].obj = NULL; + } + } } static void -_elm_hover_smart_hide(Evas_Object *obj) +_elm_hover_sub_obj_placement_eval(Evas_Object *obj) { - ELM_HOVER_DATA_GET(obj, sd); + Evas_Coord spc_l, spc_r, spc_t, spc_b; + const char *smart_dir; + Widget_Data *wd; + char buf[1024]; - ELM_WIDGET_CLASS(_elm_hover_parent_sc)->base.hide(obj); + wd = elm_widget_data_get(obj); + if (!wd->smt_sub) + return; - elm_layout_signal_emit(obj, "elm,action,hide", "elm"); + _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b); - ELM_HOVER_PARTS_FOREACH - { - char buf[1024]; + edje_object_part_unswallow(wd->cov, wd->smt_sub); + + smart_dir = _elm_hover_smart_content_location_get(wd, spc_l, spc_t, spc_r, + spc_b); + evas_object_smart_callback_call(obj, SIG_SMART_LOCATION_CHANGED, + (void *)smart_dir); - if (sd->subs[i].obj) - { - snprintf(buf, sizeof(buf), "elm,action,slot,%s,hide", - sd->subs[i].swallow); - elm_layout_signal_emit(obj, buf, "elm"); - } - } + if (elm_widget_mirrored_get(obj)) + { + if (smart_dir == _HOV_BOTTOM_LEFT) + smart_dir = _HOV_BOTTOM_RIGHT; + else if (smart_dir == _HOV_BOTTOM_RIGHT) + smart_dir = _HOV_BOTTOM_LEFT; + else if (smart_dir == _HOV_RIGHT) + smart_dir = _HOV_LEFT; + else if (smart_dir == _HOV_LEFT) + smart_dir = _HOV_RIGHT; + else if (smart_dir == _HOV_TOP_RIGHT) + smart_dir = _HOV_TOP_LEFT; + else if (smart_dir == _HOV_TOP_LEFT) + smart_dir = _HOV_TOP_RIGHT; + } + snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", smart_dir); + edje_object_part_swallow(wd->cov, buf, wd->smt_sub); } static void -_elm_hover_smart_set_user(Elm_Layout_Smart_Class *sc) +_elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_hover_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_hover_smart_del; - ELM_WIDGET_CLASS(sc)->base.move = _elm_hover_smart_move; - ELM_WIDGET_CLASS(sc)->base.resize = _elm_hover_smart_resize; - ELM_WIDGET_CLASS(sc)->base.show = _elm_hover_smart_show; - ELM_WIDGET_CLASS(sc)->base.hide = _elm_hover_smart_hide; - - ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_hover_smart_sub_object_add; - ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_hover_smart_sub_object_del; - ELM_WIDGET_CLASS(sc)->theme = _elm_hover_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + _elm_hover_sub_obj_placement_eval(data); +} - ELM_CONTAINER_CLASS(sc)->content_set = _elm_hover_smart_content_set; - ELM_CONTAINER_CLASS(sc)->content_get = _elm_hover_smart_content_get; - ELM_CONTAINER_CLASS(sc)->content_unset = _elm_hover_smart_content_unset; +static void +_elm_hover_sub_obj_unparent(Evas_Object *obj) +{ + Widget_Data *wd; + Evas_Object *smt_sub; - sc->sizing_eval = _elm_hover_smart_sizing_eval; + wd = elm_widget_data_get(obj); + if (!wd) return; - sc->content_aliases = _content_aliases; + smt_sub = wd->smt_sub; + elm_widget_sub_object_del(obj, wd->smt_sub); + evas_object_event_callback_del_full(smt_sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _elm_hover_sub_obj_placement_eval_cb, + obj); + edje_object_part_unswallow(wd->cov, smt_sub); } -EAPI Evas_Object * -elm_hover_add(Evas_Object *parent) +EAPI const char * +elm_hover_best_content_location_get(const Evas_Object *obj, Elm_Hover_Axis pref_axis) { - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - e = evas_object_evas_get(parent); - if (!e) return NULL; + Evas_Coord spc_l, spc_r, spc_t, spc_b; + Widget_Data *wd; - obj = evas_object_smart_add(e, _elm_hover_smart_class_new()); + wd = elm_widget_data_get(obj); + if (!wd) + return NULL; - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b); - elm_hover_parent_set(obj, parent); - elm_layout_sizing_eval(obj); + if (pref_axis == ELM_HOVER_AXIS_HORIZONTAL) + { + if (spc_l < spc_r) return _HOV_RIGHT; + else return _HOV_LEFT; + } + else if (pref_axis == ELM_HOVER_AXIS_VERTICAL) + { + if (spc_t < spc_b) return _HOV_BOTTOM; + else return _HOV_TOP; + } - return obj; + if (spc_l < spc_r) + { + if (spc_t > spc_r) return _HOV_TOP; + else if (spc_b > spc_r) return _HOV_BOTTOM; + return _HOV_RIGHT; + } + if (spc_t > spc_r) return _HOV_TOP; + else if (spc_b > spc_r) return _HOV_BOTTOM; + return _HOV_LEFT; } EAPI void -elm_hover_target_set(Evas_Object *obj, - Evas_Object *target) +elm_hover_dismiss(Evas_Object *obj) { - ELM_HOVER_CHECK(obj); - ELM_HOVER_DATA_GET(obj, sd); + Widget_Data *wd; + ELM_CHECK_WIDTYPE(obj, widtype); + wd = elm_widget_data_get(obj); + if (!wd) return; + + edje_object_signal_emit(wd->cov, "elm,action,dismiss", ""); +} - if (sd->target) +static void +_content_set_hook(Evas_Object *obj, const char *swallow, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (!strcmp(swallow, "smart")) { - evas_object_event_callback_del_full - (sd->target, EVAS_CALLBACK_DEL, _target_del_cb, obj); - evas_object_event_callback_del_full - (sd->target, EVAS_CALLBACK_MOVE, _target_move_cb, obj); - elm_widget_hover_object_set(sd->target, NULL); + if (wd->smt_sub != content) + { + _elm_hover_subs_del(wd); + wd->smt_sub = content; + } + + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(wd->smt_sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _elm_hover_sub_obj_placement_eval_cb, + obj); + + _elm_hover_sub_obj_placement_eval(obj); + } + + goto end; } - sd->target = target; - if (sd->target) + if (wd->smt_sub) { - evas_object_event_callback_add - (sd->target, EVAS_CALLBACK_DEL, _target_del_cb, obj); - evas_object_event_callback_add - (sd->target, EVAS_CALLBACK_MOVE, _target_move_cb, obj); - elm_widget_hover_object_set(target, obj); - elm_layout_sizing_eval(obj); + evas_object_del(wd->smt_sub); + wd->smt_sub = NULL; } -} -EAPI void -elm_hover_parent_set(Evas_Object *obj, - Evas_Object *parent) -{ - ELM_HOVER_CHECK(obj); - ELM_HOVER_DATA_GET(obj, sd); + ELM_HOVER_PARTS_FOREACH + { + if (!strcmp(swallow, wd->subs[i].swallow)) + { + if (content == wd->subs[i].obj) + return; + evas_object_del(wd->subs[i].obj); + wd->subs[i].obj = NULL; - _elm_hover_parent_detach(obj); + if (content) + { + char buf[1024]; - sd->parent = parent; - if (sd->parent) - { - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_MOVE, _parent_move_cb, obj); - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_RESIZE, _parent_resize_cb, obj); - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_SHOW, _parent_show_cb, obj); - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj); - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj); + snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", swallow); + elm_widget_sub_object_add(obj, content); + edje_object_part_swallow(wd->cov, buf, content); + wd->subs[i].obj = content; + } + break; + } } - - elm_layout_sizing_eval(obj); +end: + _sizing_eval(obj); } -EAPI Evas_Object * -elm_hover_target_get(const Evas_Object *obj) +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *swallow) { - ELM_HOVER_CHECK(obj) NULL; - ELM_HOVER_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - return sd->target; -} + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; -EAPI Evas_Object * -elm_hover_parent_get(const Evas_Object *obj) -{ - ELM_HOVER_CHECK(obj) NULL; - ELM_HOVER_DATA_GET(obj, sd); + if (!strcmp(swallow, "smart")) + return wd->smt_sub; + + ELM_HOVER_PARTS_FOREACH + if (!strcmp(swallow, wd->subs[i].swallow)) + return wd->subs[i].obj; - return sd->parent; + return NULL; } -EAPI const char * -elm_hover_best_content_location_get(const Evas_Object *obj, - Elm_Hover_Axis pref_axis) +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *swallow) { - Evas_Coord spc_l, spc_r, spc_t, spc_b; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - ELM_HOVER_CHECK(obj) NULL; - ELM_HOVER_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - _elm_hover_left_space_calc(sd, &spc_l, &spc_t, &spc_r, &spc_b); - - if (pref_axis == ELM_HOVER_AXIS_HORIZONTAL) - { - if (spc_l < spc_r) return (_HOV_RIGHT)->swallow; - else return (_HOV_LEFT)->swallow; - } - else if (pref_axis == ELM_HOVER_AXIS_VERTICAL) + if (!strcmp(swallow, "smart")) { - if (spc_t < spc_b) return (_HOV_BOTTOM)->swallow; - else return (_HOV_TOP)->swallow; + if (!wd->smt_sub) return NULL; + Evas_Object *content = wd->smt_sub; + _elm_hover_sub_obj_unparent(obj); + return content; } - if (spc_l < spc_r) + ELM_HOVER_PARTS_FOREACH { - if (spc_t > spc_r) return (_HOV_TOP)->swallow; - else if (spc_b > spc_r) - return (_HOV_BOTTOM)->swallow; - - return (_HOV_RIGHT)->swallow; + if (!strcmp(swallow, wd->subs[i].swallow)) + { + if (!wd->subs[i].obj) return NULL; + Evas_Object *content = wd->subs[i].obj; + elm_widget_sub_object_del(obj, wd->subs[i].obj); + edje_object_part_unswallow(wd->cov, content); + return content; + } } - if (spc_t > spc_r) return (_HOV_TOP)->swallow; - else if (spc_b > spc_r) - return (_HOV_BOTTOM)->swallow; - - return (_HOV_LEFT)->swallow; -} - -EAPI void -elm_hover_dismiss(Evas_Object *obj) -{ - ELM_HOVER_CHECK(obj); - - elm_layout_signal_emit(obj, "elm,action,dismiss", ""); + return NULL; } diff --git a/src/lib/elm_hover.h b/src/lib/elm_hover.h index 0f114aebf..1413098e1 100644 --- a/src/lib/elm_hover.h +++ b/src/lib/elm_hover.h @@ -24,26 +24,34 @@ * @li menu * @li hoversel_vertical * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for hover objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @c "clicked" - the user clicked the empty space in the hover to dismiss - * @li @c "smart,changed" - a content object placed under the "smart" + * The following are the available position for content: + * @li left + * @li top-left + * @li top + * @li top-right + * @li right + * @li bottom-right + * @li bottom + * @li bottom-left + * @li middle + * @li smart + * + * Signals that you can add callbacks for are: + * @li "clicked" - the user clicked the empty space in the hover to dismiss + * @li "smart,changed" - a content object placed under the "smart" * policy was replaced to a new slot direction. * * Default content parts of the hover widget that you can use for are: - * @li @c "left" - * @li @c "top-left" - * @li @c "top" - * @li @c "top-right" - * @li @c "right" - * @li @c "bottom-right" - * @li @c "bottom" - * @li @c "bottom-left" - * @li @c "middle" - * @li @c "smart" + * @li "left" + * @li "top-left" + * @li "top" + * @li "top-right" + * @li "right" + * @li "bottom-right" + * @li "bottom" + * @li "bottom-left" + * @li "middle" + * @li "smart" * * @note These content parts indicates the direction that the content will be * displayed diff --git a/src/lib/elm_index.c b/src/lib/elm_index.c index b2007745d..985b1819f 100644 --- a/src/lib/elm_index.c +++ b/src/lib/elm_index.c @@ -1,83 +1,52 @@ #include <Elementary.h> #include "elm_priv.h" #include "els_box.h" -#include "elm_widget_layout.h" -static const char INDEX_SMART_NAME[] = "elm_index"; - -typedef struct _Elm_Index_Smart_Data Elm_Index_Smart_Data; -typedef struct _Elm_Index_Item Elm_Index_Item; - -struct _Elm_Index_Smart_Data -{ - Elm_Layout_Smart_Data base; - - Evas_Object *event[2]; - Evas_Object *bx[2]; // 2 - for now all that's supported - Eina_List *items; /* 1 list. N levels, but only 2 - * for now and # of items will be - * small */ - int level; - Evas_Coord dx, dy; - Ecore_Timer *delay; - Eina_Bool level_active[2]; - - Eina_Bool down : 1; - Eina_Bool horizontal : 1; - Eina_Bool autohide_disabled : 1; - Eina_Bool indicator_disabled : 1; +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Index_Item Elm_Index_Item; + +struct _Widget_Data +{ + Evas_Object *base; + Evas_Object *event[2]; + Evas_Object *bx[2]; // 2 - for now all that's supported + Eina_List *items; // 1 list. yes N levels, but only 2 for now and # of items will be small + int level; + Evas_Coord dx, dy; + Ecore_Timer *delay; + Eina_Bool level_active[2]; + Eina_Bool horizontal : 1; + Eina_Bool autohide_disabled : 1; + Eina_Bool down : 1; + Eina_Bool indicator_disabled : 1; }; struct _Elm_Index_Item { ELM_WIDGET_ITEM; - - const char *letter; - int level; + const char *letter; + int level; Evas_Smart_Cb func; - - Eina_Bool selected : 1; + Eina_Bool selected : 1; }; -#define ELM_INDEX_DATA_GET(o, sd) \ - Elm_Index_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_INDEX_DATA_GET_OR_RETURN(o, ptr) \ - ELM_INDEX_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_INDEX_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_INDEX_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_INDEX_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), INDEX_SMART_NAME, __func__)) \ - return - -#define ELM_INDEX_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_INDEX_CHECK(it->base.widget); - -#define ELM_INDEX_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_INDEX_CHECK(it->base.widget) __VA_ARGS__; +static const char *widtype = NULL; + +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level); +static void _index_box_clear(Evas_Object *obj, Evas_Object *box, int level); +static void _item_free(Elm_Index_Item *it); static const char SIG_CHANGED[] = "changed"; static const char SIG_DELAY_CHANGED[] = "delay,changed"; static const char SIG_SELECTED[] = "selected"; static const char SIG_LEVEL_UP[] = "level,up"; static const char SIG_LEVEL_DOWN[] = "level,down"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { + +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {SIG_DELAY_CHANGED, ""}, {SIG_SELECTED, ""}, @@ -86,106 +55,237 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (INDEX_SMART_NAME, _elm_index, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static void -_item_free(Elm_Index_Item *it) +_del_pre_hook(Evas_Object *obj) { - ELM_INDEX_DATA_GET(WIDGET(it), sd); + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Index_Item *it; + if (!wd) return; + _index_box_clear(obj, wd->bx[wd->level], wd->level); + _index_box_clear(obj, wd->bx[0], 0); + while (wd->items) + { + it = wd->items->data; + _item_free(it); + elm_widget_item_free(it); + } + if (wd->delay) ecore_timer_del(wd->delay); +} - sd->items = eina_list_remove(sd->items, it); - if (it->letter) eina_stringshare_del(it->letter); +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + free(wd); } static void -_box_custom_layout(Evas_Object *o, - Evas_Object_Box_Data *priv, - void *data) +_layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) { - Elm_Index_Smart_Data *sd = data; + Widget_Data *wd = data; + if (!wd) return; + _els_box_layout(o, priv, wd->horizontal, 1, 0); +} - _els_box_layout(o, priv, sd->horizontal, 1, 0); +static void +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_emit(wd->base, emission, source); } static void -_index_box_clear(Evas_Object *obj, - Evas_Object *box __UNUSED__, - int level) +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) { - Eina_List *l; - Elm_Index_Item *it; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_signal_callback_add(wd->base, emission, source, func_cb, data); +} - ELM_INDEX_DATA_GET(obj, sd); +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_callback_del_full(wd->base, emission, source, func_cb, + data); +} - if (!sd->level_active[level]) return; +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (!wd->horizontal) + edje_object_mirrored_set(wd->base, rtl); +} - EINA_LIST_FOREACH (sd->items, l, it) +static void +_theme_hook(Evas_Object *obj) +{ + Evas_Coord minw = 0, minh = 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + + _index_box_clear(obj, wd->bx[0], 0); + _index_box_clear(obj, wd->bx[1], 1); + if (wd->horizontal) + _elm_theme_object_set(obj, wd->base, "index", "base/horizontal", elm_widget_style_get(obj)); + else { - if (!VIEW(it)) continue; - if (it->level != level) continue; + _elm_theme_object_set(obj, wd->base, "index", "base/vertical", elm_widget_style_get(obj)); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + } + edje_object_part_swallow(wd->base, "elm.swallow.event.0", wd->event[0]); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + evas_object_size_hint_min_set(wd->event[0], minw, minh); + edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]); + if (edje_object_part_exists(wd->base, "elm.swallow.index.1")) + { + if (!wd->bx[1]) + { + wd->bx[1] = evas_object_box_add(evas_object_evas_get(wd->base)); + evas_object_box_layout_set(wd->bx[1], _layout, wd, NULL); + elm_widget_sub_object_add(obj, wd->bx[1]); + } + edje_object_part_swallow(wd->base, "elm.swallow.index.1", wd->bx[1]); + evas_object_show(wd->bx[1]); + } + else if (wd->bx[1]) + { + evas_object_del(wd->bx[1]); + wd->bx[1] = NULL; + } + if (edje_object_part_exists(wd->base, "elm.swallow.event.1")) + { + if (!wd->event[1]) + { + wd->event[1] = evas_object_rectangle_add(evas_object_evas_get(wd->base)); + evas_object_color_set(wd->event[1], 0, 0, 0, 0); + elm_widget_sub_object_add(obj, wd->event[1]); + } + edje_object_part_swallow(wd->base, "elm.swallow.event.1", wd->event[1]); + evas_object_size_hint_min_set(wd->event[1], minw, minh); + } + else if (wd->event[1]) + { + evas_object_del(wd->event[1]); + wd->event[1] = NULL; + } + edje_object_message_signal_process(wd->base); + edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); + _index_box_auto_fill(obj, wd->bx[0], 0); - evas_object_del(VIEW(it)); - VIEW(it) = NULL; + if (wd->autohide_disabled) + { + if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1); + edje_object_signal_emit(wd->base, "elm,state,active", "elm"); } + else + edje_object_signal_emit(wd->base, "elm,state,inactive", "elm"); +} + +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; + if (!wd) return; + edje_object_size_min_calc(wd->base, &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); +} + +static Eina_Bool +_item_del_pre_hook(Elm_Object_Item *it) +{ + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); + if (!wd) return EINA_FALSE; + _item_free((Elm_Index_Item *)it); + _index_box_clear(WIDGET(it), wd->bx[wd->level], wd->level); + return EINA_TRUE; +} + +static Elm_Index_Item * +_item_new(Evas_Object *obj, const char *letter, Evas_Smart_Cb func, const void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Elm_Index_Item *it; + if (!wd) return NULL; + it = elm_widget_item_new(obj, Elm_Index_Item); + if (!it) return NULL; + elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); + if (letter) it->letter = eina_stringshare_add(letter); + it->func = func; + it->base.data = data; + it->level = wd->level; + return it; +} + +static Elm_Index_Item * +_item_find(Evas_Object *obj, const void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_List *l; + Elm_Index_Item *it; + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->items, l, it) + if (it->base.data == data) return it; + return NULL; +} - sd->level_active[level] = 0; +static void +_item_free(Elm_Index_Item *it) +{ + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); + if (!wd) return; + wd->items = eina_list_remove(wd->items, it); + if (it->letter) eina_stringshare_del(it->letter); } // FIXME: always have index filled static void -_index_box_auto_fill(Evas_Object *obj, - Evas_Object *box, - int level) +_index_box_auto_fill(Evas_Object *obj, Evas_Object *box, int level) { - int i = 0; - Eina_List *l; + Widget_Data *wd = elm_widget_data_get(obj); Eina_Bool rtl; + Eina_List *l; Elm_Index_Item *it; Evas_Coord mw, mh, w, h; - - ELM_INDEX_DATA_GET(obj, sd); - - if (sd->level_active[level]) return; - + int i = 0; + if (!wd) return; + if (wd->level_active[level]) return; rtl = elm_widget_mirrored_get(obj); evas_object_geometry_get(box, NULL, NULL, &w, &h); - - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FOREACH(wd->items, l, it) { Evas_Object *o; const char *stacking; if (it->level != level) continue; - o = edje_object_add(evas_object_evas_get(obj)); VIEW(it) = o; edje_object_mirrored_set(VIEW(it), rtl); - if (sd->horizontal) + if (wd->horizontal) { if (i & 0x1) - elm_widget_theme_object_set - (obj, o, "index", "item_odd/horizontal", - elm_widget_style_get(obj)); + _elm_theme_object_set(obj, o, "index", "item_odd/horizontal", + elm_widget_style_get(obj)); else - elm_widget_theme_object_set - (obj, o, "index", "item/horizontal", - elm_widget_style_get(obj)); + _elm_theme_object_set(obj, o, "index", "item/horizontal", + elm_widget_style_get(obj)); } else { if (i & 0x1) - elm_widget_theme_object_set - (obj, o, "index", "item_odd/vertical", - elm_widget_style_get(obj)); + _elm_theme_object_set(obj, o, "index", "item_odd/vertical", + elm_widget_style_get(obj)); else - elm_widget_theme_object_set - (obj, o, "index", "item/vertical", - elm_widget_style_get(obj)); + _elm_theme_object_set(obj, o, "index", "item/vertical", + elm_widget_style_get(obj)); } edje_object_part_text_escaped_set(o, "elm.text", it->letter); @@ -196,16 +296,12 @@ _index_box_auto_fill(Evas_Object *obj, elm_widget_sub_object_add(obj, o); evas_object_box_append(box, o); stacking = edje_object_data_get(o, "stacking"); - if (stacking) { if (!strcmp(stacking, "below")) evas_object_lower(o); - else if (!strcmp(stacking, "above")) - evas_object_raise(o); + else if (!strcmp(stacking, "above")) evas_object_raise(o); } - evas_object_show(o); - i++; evas_object_smart_calculate(box); // force a calc so we know the size evas_object_size_hint_min_get(box, &mw, &mh); @@ -218,181 +314,62 @@ _index_box_auto_fill(Evas_Object *obj, } } } - evas_object_smart_calculate(box); - sd->level_active[level] = 1; -} - -static Eina_Bool -_elm_index_smart_theme(Evas_Object *obj) -{ - Evas_Coord minw = 0, minh = 0; - - ELM_INDEX_DATA_GET(obj, sd); - - _index_box_clear(obj, sd->bx[0], 0); - _index_box_clear(obj, sd->bx[1], 1); - - if (sd->horizontal) - eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/horizontal"); - else - eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "base/vertical"); - - if (!ELM_WIDGET_CLASS(_elm_index_parent_sc)->theme(obj)) return EINA_FALSE; - - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_size_hint_min_set(sd->event[0], minw, minh); - - if (edje_object_part_exists - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.index.1")) - { - if (!sd->bx[1]) - { - sd->bx[1] = evas_object_box_add(evas_object_evas_get(obj)); - evas_object_box_layout_set - (sd->bx[1], _box_custom_layout, sd, NULL); - elm_widget_sub_object_add(obj, sd->bx[1]); - } - elm_layout_content_set(obj, "elm.swallow.index.1", sd->bx[1]); - } - else if (sd->bx[1]) - { - evas_object_del(sd->bx[1]); - sd->bx[1] = NULL; - } - if (edje_object_part_exists - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.event.1")) - { - if (!sd->event[1]) - { - sd->event[1] = - evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_color_set(sd->event[1], 0, 0, 0, 0); - elm_widget_sub_object_add(obj, sd->event[1]); - } - elm_layout_content_set(obj, "elm.swallow.event.1", sd->event[1]); - evas_object_size_hint_min_set(sd->event[1], minw, minh); - } - else if (sd->event[1]) - { - evas_object_del(sd->event[1]); - sd->event[1] = NULL; - } - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); - _index_box_auto_fill(obj, sd->bx[0], 0); - - if (sd->autohide_disabled) - { - if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1); - elm_layout_signal_emit(obj, "elm,state,active", "elm"); - } - else elm_layout_signal_emit(obj, "elm,state,inactive", "elm"); - - return EINA_TRUE; + wd->level_active[level] = 1; } static void -_elm_index_smart_sizing_eval(Evas_Object *obj) -{ - Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; - - ELM_INDEX_DATA_GET(obj, sd); - - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, maxw, maxh); -} - -static Eina_Bool -_item_del_pre_hook(Elm_Object_Item *it) -{ - ELM_INDEX_DATA_GET(WIDGET(it), sd); - - _item_free((Elm_Index_Item *)it); - _index_box_clear(WIDGET(it), sd->bx[sd->level], sd->level); - - return EINA_TRUE; -} - -static Elm_Index_Item * -_item_new(Evas_Object *obj, - const char *letter, - Evas_Smart_Cb func, - const void *data) -{ - Elm_Index_Item *it; - - ELM_INDEX_DATA_GET(obj, sd); - - it = elm_widget_item_new(obj, Elm_Index_Item); - if (!it) return NULL; - - elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); - if (letter) it->letter = eina_stringshare_add(letter); - it->func = func; - it->base.data = data; - it->level = sd->level; - - return it; -} - -static Elm_Index_Item * -_item_find(Evas_Object *obj, - const void *data) +_index_box_clear(Evas_Object *obj, Evas_Object *box __UNUSED__, int level) { + Widget_Data *wd = elm_widget_data_get(obj); Eina_List *l; Elm_Index_Item *it; - - ELM_INDEX_DATA_GET(obj, sd); - - EINA_LIST_FOREACH (sd->items, l, it) - if (it->base.data == data) return it; - - return NULL; + if (!wd) return; + if (!wd->level_active[level]) return; + EINA_LIST_FOREACH(wd->items, l, it) + { + if (!VIEW(it)) continue; + if (it->level != level) continue; + evas_object_del(VIEW(it)); + VIEW(it) = NULL; + } + wd->level_active[level] = 0; } static Eina_Bool _delay_change(void *data) { + Widget_Data *wd = elm_widget_data_get(data); Elm_Object_Item *item; - - ELM_INDEX_DATA_GET(data, sd); - - sd->delay = NULL; - item = elm_index_selected_item_get(data, sd->level); + if (!wd) return ECORE_CALLBACK_CANCEL; + wd->delay = NULL; + item = elm_index_selected_item_get(data, wd->level); if (item) evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, item); - return ECORE_CALLBACK_CANCEL; } static void -_sel_eval(Evas_Object *obj, - Evas_Coord evx, - Evas_Coord evy) +_sel_eval(Evas_Object *obj, Evas_Coord evx, Evas_Coord evy) { - Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it, *it_closest, *it_last; - char *label = NULL, *last = NULL; + Eina_List *l; + Evas_Coord x, y, w, h, bx, by, bw, bh, xx, yy; double cdv = 0.5; Evas_Coord dist; - Eina_List *l; + char *label = NULL, *last = NULL; int i; - - ELM_INDEX_DATA_GET(obj, sd); - - for (i = 0; i <= sd->level; i++) + if (!wd) return; + for (i = 0; i <= wd->level; i++) { it_last = NULL; - it_closest = NULL; + it_closest = NULL; dist = 0x7fffffff; - evas_object_geometry_get(sd->bx[i], &bx, &by, &bw, &bh); - - EINA_LIST_FOREACH (sd->items, l, it) + evas_object_geometry_get(wd->bx[i], &bx, &by, &bw, &bh); + EINA_LIST_FOREACH(wd->items, l, it) { if (it->level != i) continue; - if (it->level != sd->level) + if (it->level != wd->level) { if (it->selected) { @@ -414,7 +391,7 @@ _sel_eval(Evas_Object *obj, x = (x * x) + (y * y); if ((x < dist) || (!it_closest)) { - if (sd->horizontal) + if (wd->horizontal) cdv = (double)(xx - bx) / (double)bw; else cdv = (double)(yy - by) / (double)bh; @@ -422,9 +399,9 @@ _sel_eval(Evas_Object *obj, dist = x; } } - if ((i == 0) && (sd->level == 0)) - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.index.1", cdv, cdv); + if ((i == 0) && (wd->level == 0)) + edje_object_part_drag_value_set(wd->base, "elm.dragable.index.1", + cdv, cdv); if (it_closest) it_closest->selected = 1; if (it_closest != it_last) { @@ -433,8 +410,7 @@ _sel_eval(Evas_Object *obj, const char *stacking, *selectraise; it = it_last; - edje_object_signal_emit - (VIEW(it), "elm,state,inactive", "elm"); + edje_object_signal_emit(VIEW(it), "elm,state,inactive", "elm"); stacking = edje_object_data_get(VIEW(it), "stacking"); selectraise = edje_object_data_get(VIEW(it), "selectraise"); if ((selectraise) && (!strcmp(selectraise, "on"))) @@ -452,16 +428,16 @@ _sel_eval(Evas_Object *obj, selectraise = edje_object_data_get(VIEW(it), "selectraise"); if ((selectraise) && (!strcmp(selectraise, "on"))) evas_object_raise(VIEW(it)); - evas_object_smart_callback_call - (obj, SIG_CHANGED, (void *)it); - if (sd->delay) ecore_timer_del(sd->delay); - sd->delay = ecore_timer_add(0.2, _delay_change, obj); + evas_object_smart_callback_call((void *)obj, SIG_CHANGED, (void *)it); + if (wd->delay) ecore_timer_del(wd->delay); + wd->delay = ecore_timer_add(0.2, _delay_change, obj); } } if (it_closest) { it = it_closest; - if (!last && it->letter) last = strdup(it->letter); + if (!last && it->letter) + last = strdup(it->letter); else { if (!label && last) label = strdup(last); @@ -482,67 +458,57 @@ _sel_eval(Evas_Object *obj, } if (!label) label = strdup(""); if (!last) last = strdup(""); - - elm_layout_text_set(obj, "elm.text.body", label); - elm_layout_text_set(obj, "elm.text", last); - + edje_object_part_text_escaped_set(wd->base, "elm.text.body", label); + edje_object_part_text_escaped_set(wd->base, "elm.text", last); free(label); free(last); } static void -_on_mouse_wheel(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *o __UNUSED__, - void *event_info __UNUSED__) +_wheel(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) { + Widget_Data *wd = elm_widget_data_get(data); + // Evas_Event_Mouse_Wheel *ev = event_info; + // Evas_Object *obj = o; + if (!wd) return; } static void -_on_mouse_down(void *data, - Evas *e __UNUSED__, - Evas_Object *o __UNUSED__, - void *event_info) +_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { + Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Down *ev = event_info; Evas_Coord x, y, w; - - ELM_INDEX_DATA_GET(data, sd); - + if (!wd) return; if (ev->button != 1) return; - sd->down = 1; - evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL); - sd->dx = ev->canvas.x - x; - sd->dy = ev->canvas.y - y; - if (!sd->autohide_disabled) + wd->down = 1; + evas_object_geometry_get(wd->base, &x, &y, &w, NULL); + wd->dx = ev->canvas.x - x; + wd->dy = ev->canvas.y - y; + if (!wd->autohide_disabled) { - _index_box_clear(data, sd->bx[1], 1); - _index_box_auto_fill(data, sd->bx[0], 0); - elm_layout_signal_emit(data, "elm,state,active", "elm"); + _index_box_clear(data, wd->bx[1], 1); + _index_box_auto_fill(data, wd->bx[0], 0); + edje_object_signal_emit(wd->base, "elm,state,active", "elm"); } _sel_eval(data, ev->canvas.x, ev->canvas.y); - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer", - (!elm_object_mirrored_get(data)) ? sd->dx : (sd->dx - w), sd->dy); - if (sd->items && !sd->indicator_disabled) - elm_layout_signal_emit(data, "elm,indicator,state,active", "elm"); + edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer", + (!edje_object_mirrored_get(wd->base)) ? wd->dx : (wd->dx - w), wd->dy); + if (wd->items && !wd->indicator_disabled) + edje_object_signal_emit(wd->base, "elm,indicator,state,active", "elm"); } static void -_on_mouse_up(void *data, - Evas *e __UNUSED__, - Evas_Object *o __UNUSED__, - void *event_info) +_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { + Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Up *ev = event_info; Elm_Object_Item *item; Elm_Index_Item *id_item; - - ELM_INDEX_DATA_GET(data, sd); - + if (!wd) return; if (ev->button != 1) return; - sd->down = 0; - item = elm_index_selected_item_get(data, sd->level); + wd->down = 0; + item = elm_index_selected_item_get(data, wd->level); if (item) { evas_object_smart_callback_call(data, SIG_SELECTED, item); @@ -550,58 +516,50 @@ _on_mouse_up(void *data, if (id_item->func) id_item->func((void *)id_item->base.data, WIDGET(id_item), id_item); } - if (!sd->autohide_disabled) - elm_layout_signal_emit(data, "elm,state,inactive", "elm"); - - elm_layout_signal_emit(data, "elm,state,level,0", "elm"); - if (sd->items && !sd->indicator_disabled) - elm_layout_signal_emit(data, "elm,indicator,state,inactive", "elm"); + if (!wd->autohide_disabled) + edje_object_signal_emit(wd->base, "elm,state,inactive", "elm"); + edje_object_signal_emit(wd->base, "elm,state,level,0", "elm"); + if (wd->items && !wd->indicator_disabled) + edje_object_signal_emit(wd->base, "elm,indicator,state,inactive", "elm"); } static void -_on_mouse_move(void *data, - Evas *e __UNUSED__, - Evas_Object *o __UNUSED__, - void *event_info) +_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info) { + Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Move *ev = event_info; Evas_Coord minw = 0, minh = 0, x, y, dx, adx, w; char buf[1024]; - - ELM_INDEX_DATA_GET(data, sd); - - if (!sd->down) return; - + if (!wd) return; + if (!wd->down) return; elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, NULL); + evas_object_geometry_get(wd->base, &x, &y, &w, NULL); x = ev->cur.canvas.x - x; y = ev->cur.canvas.y - y; - dx = x - sd->dx; + dx = x - wd->dx; adx = dx; if (adx < 0) adx = -dx; - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.pointer", - (!edje_object_mirrored_get(ELM_WIDGET_DATA(sd)->resize_obj)) ? - x : (x - w), y); - if (!sd->horizontal) + edje_object_part_drag_value_set(wd->base, "elm.dragable.pointer" + , (!edje_object_mirrored_get(wd->base)) ? x : (x - w), y); + if (!wd->horizontal) { if (adx > minw) { - if (!sd->level) + if (!wd->level) { - sd->level = 1; - snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level); - elm_layout_signal_emit(data, buf, "elm"); + wd->level = 1; + snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); + edje_object_signal_emit(wd->base, buf, "elm"); evas_object_smart_callback_call(data, SIG_LEVEL_UP, NULL); } } else { - if (sd->level == 1) + if (wd->level == 1) { - sd->level = 0; - snprintf(buf, sizeof(buf), "elm,state,level,%i", sd->level); - elm_layout_signal_emit(data, buf, "elm"); + wd->level = 0; + snprintf(buf, sizeof(buf), "elm,state,level,%i", wd->level); + edje_object_signal_emit(wd->base, buf, "elm"); evas_object_smart_callback_call(data, SIG_LEVEL_DOWN, NULL); } } @@ -609,142 +567,100 @@ _on_mouse_move(void *data, _sel_eval(data, ev->cur.canvas.x, ev->cur.canvas.y); } -static void -_elm_index_smart_add(Evas_Object *obj) +EAPI Evas_Object * +elm_index_add(Evas_Object *parent) { + Evas_Object *obj; Evas_Object *o; + Evas *e; + Widget_Data *wd; Evas_Coord minw, minh; - EVAS_SMART_DATA_ALLOC(obj, Elm_Index_Smart_Data); - - ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.add(obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "index"); + elm_widget_type_set(obj, "index"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); - priv->indicator_disabled = EINA_FALSE; - priv->horizontal = EINA_FALSE; - priv->autohide_disabled = EINA_FALSE; + wd->indicator_disabled = EINA_FALSE; + wd->horizontal = EINA_FALSE; + wd->autohide_disabled = EINA_FALSE; - elm_layout_theme_set - (obj, "index", "base/vertical", elm_widget_style_get(obj)); + wd->base = edje_object_add(e); + _elm_theme_object_set(obj, wd->base, "index", "base/vertical", "default"); + elm_widget_resize_object_set(obj, wd->base); - o = evas_object_rectangle_add(evas_object_evas_get(obj)); - priv->event[0] = o; + o = evas_object_rectangle_add(e); + wd->event[0] = o; evas_object_color_set(o, 0, 0, 0, 0); minw = minh = 0; elm_coords_finger_size_adjust(1, &minw, 1, &minh); evas_object_size_hint_min_set(o, minw, minh); - elm_layout_content_set(obj, "elm.swallow.event.0", o); + edje_object_part_swallow(wd->base, "elm.swallow.event.0", o); elm_widget_sub_object_add(obj, o); - - evas_object_event_callback_add - (o, EVAS_CALLBACK_MOUSE_WHEEL, _on_mouse_wheel, obj); - evas_object_event_callback_add - (o, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, obj); - evas_object_event_callback_add - (o, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, obj); - evas_object_event_callback_add - (o, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move, obj); - - if (edje_object_part_exists - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.event.1")) + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _wheel, obj); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, obj); + evas_object_show(o); + if (edje_object_part_exists(wd->base, "elm.swallow.event.1")) { - o = evas_object_rectangle_add(evas_object_evas_get(obj)); - priv->event[1] = o; + o = evas_object_rectangle_add(e); + wd->event[1] = o; evas_object_color_set(o, 0, 0, 0, 0); evas_object_size_hint_min_set(o, minw, minh); - elm_layout_content_set(obj, "elm.swallow.event.1", o); + edje_object_part_swallow(wd->base, "elm.swallow.event.1", o); elm_widget_sub_object_add(obj, o); } - priv->bx[0] = evas_object_box_add(evas_object_evas_get(obj)); - evas_object_box_layout_set(priv->bx[0], _box_custom_layout, priv, NULL); - elm_widget_sub_object_add(obj, priv->bx[0]); - elm_layout_content_set(obj, "elm.swallow.index.0", priv->bx[0]); - evas_object_show(priv->bx[0]); + wd->bx[0] = evas_object_box_add(e); + evas_object_box_layout_set(wd->bx[0], _layout, wd, NULL); + elm_widget_sub_object_add(obj, wd->bx[0]); + edje_object_part_swallow(wd->base, "elm.swallow.index.0", wd->bx[0]); + evas_object_show(wd->bx[0]); - if (edje_object_part_exists - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.swallow.index.1")) + if (edje_object_part_exists(wd->base, "elm.swallow.index.1")) { - priv->bx[1] = evas_object_box_add(evas_object_evas_get(obj)); - evas_object_box_layout_set - (priv->bx[1], _box_custom_layout, priv, NULL); - elm_widget_sub_object_add(obj, priv->bx[1]); - elm_layout_content_set(obj, "elm.swallow.index.1", priv->bx[1]); - evas_object_show(priv->bx[1]); + wd->bx[1] = evas_object_box_add(e); + evas_object_box_layout_set(wd->bx[1], _layout, wd, NULL); + elm_widget_sub_object_add(obj, wd->bx[1]); + edje_object_part_swallow(wd->base, "elm.swallow.index.1", wd->bx[1]); + evas_object_show(wd->bx[1]); } - elm_layout_sizing_eval(obj); - elm_widget_can_focus_set(obj, EINA_FALSE); -} - -static void -_elm_index_smart_del(Evas_Object *obj) -{ - Elm_Index_Item *it; - - ELM_INDEX_DATA_GET(obj, sd); - - while (sd->items) - { - it = sd->items->data; - _item_free(it); - elm_widget_item_free(it); - } - - if (sd->delay) ecore_timer_del(sd->delay); - - ELM_WIDGET_CLASS(_elm_index_parent_sc)->base.del(obj); -} - -static void -_elm_index_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_index_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_index_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_index_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_index_smart_sizing_eval; -} - -EAPI Evas_Object * -elm_index_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_index_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_index_autohide_disabled_set(Evas_Object *obj, - Eina_Bool disabled) +elm_index_autohide_disabled_set(Evas_Object *obj, Eina_Bool disabled) { - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; disabled = !!disabled; - if (sd->autohide_disabled == disabled) return; - sd->autohide_disabled = disabled; - sd->level = 0; - if (sd->autohide_disabled) + if (wd->autohide_disabled == disabled) return; + wd->autohide_disabled = disabled; + wd->level = 0; + if (wd->autohide_disabled) { - _index_box_clear(obj, sd->bx[1], 1); - _index_box_auto_fill(obj, sd->bx[0], 0); - elm_layout_signal_emit(obj, "elm,state,active", "elm"); + _index_box_clear(obj, wd->bx[1], 1); + _index_box_auto_fill(obj, wd->bx[0], 0); + edje_object_signal_emit(wd->base, "elm,state,active", "elm"); } else - elm_layout_signal_emit(obj, "elm,state,inactive", "elm"); + edje_object_signal_emit(wd->base, "elm,state,inactive", "elm"); //FIXME: Should be update indicator based on the indicator visiblility } @@ -752,196 +668,158 @@ elm_index_autohide_disabled_set(Evas_Object *obj, EAPI Eina_Bool elm_index_autohide_disabled_get(const Evas_Object *obj) { - ELM_INDEX_CHECK(obj) EINA_FALSE; - ELM_INDEX_DATA_GET(obj, sd); - - return sd->autohide_disabled; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->autohide_disabled; } EAPI void -elm_index_item_level_set(Evas_Object *obj, - int level) +elm_index_item_level_set(Evas_Object *obj, int level) { - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); - - if (sd->level == level) return; - sd->level = level; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->level == level) return; + wd->level = level; } EAPI int elm_index_item_level_get(const Evas_Object *obj) { - ELM_INDEX_CHECK(obj) 0; - ELM_INDEX_DATA_GET(obj, sd); - - return sd->level; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->level; } EAPI void -elm_index_item_selected_set(Elm_Object_Item *it, - Eina_Bool selected) +elm_index_item_selected_set(Elm_Object_Item *it, Eina_Bool selected) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); Evas_Coord x, y, w, h; + Widget_Data *wd = elm_widget_data_get(WIDGET(it)); + if (!wd) return; - ELM_INDEX_ITEM_CHECK_OR_RETURN(it); - - //FIXME: Should be update indicator based on the autohidden status - //& indicator visiblility + //FIXME: Should be update indicator based on the autohidden status & indicator visiblility if (selected) { evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); - _sel_eval(WIDGET(it), x + (w / 2), y + (h / 2)); + _sel_eval(WIDGET(it), x + (w/2), y + (h/2)); } - else _sel_eval(WIDGET(it), -99999, -9999); + else + _sel_eval(WIDGET(it), -99999, -9999); + } EAPI Elm_Object_Item * -elm_index_selected_item_get(const Evas_Object *obj, - int level) +elm_index_selected_item_get(const Evas_Object *obj, int level) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_List *l; Elm_Index_Item *it; - - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - - EINA_LIST_FOREACH (sd->items, l, it) + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->items, l, it) { if ((it->selected) && (it->level == level)) return (Elm_Object_Item *)it; } - return NULL; } EAPI Elm_Object_Item * -elm_index_item_append(Evas_Object *obj, - const char *letter, - Evas_Smart_Cb func, - const void *data) +elm_index_item_append(Evas_Object *obj, const char *letter, Evas_Smart_Cb func, const void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it; - - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - + if (!wd) return NULL; it = _item_new(obj, letter, func, data); if (!it) return NULL; - - sd->items = eina_list_append(sd->items, it); - _index_box_clear(obj, sd->bx[sd->level], sd->level); - + wd->items = eina_list_append(wd->items, it); + _index_box_clear(obj, wd->bx[wd->level], wd->level); return (Elm_Object_Item *)it; } EAPI Elm_Object_Item * -elm_index_item_prepend(Evas_Object *obj, - const char *letter, - Evas_Smart_Cb func, - const void *data) +elm_index_item_prepend(Evas_Object *obj, const char *letter, Evas_Smart_Cb func, const void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it; - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - + if (!wd) return NULL; it = _item_new(obj, letter, func, data); if (!it) return NULL; - - sd->items = eina_list_prepend(sd->items, it); - _index_box_clear(obj, sd->bx[sd->level], sd->level); - + wd->items = eina_list_prepend(wd->items, it); + _index_box_clear(obj, wd->bx[wd->level], wd->level); return (Elm_Object_Item *)it; } EINA_DEPRECATED EAPI Elm_Object_Item * -elm_index_item_prepend_relative(Evas_Object *obj, - const char *letter, - const void *item, - const Elm_Object_Item *relative) +elm_index_item_prepend_relative(Evas_Object *obj, const char *letter, const void *item, const Elm_Object_Item *relative) { - return elm_index_item_insert_before - (obj, (Elm_Object_Item *)relative, letter, NULL, item); + return elm_index_item_insert_before(obj, (Elm_Object_Item *) relative, letter, NULL, item); } EAPI Elm_Object_Item * -elm_index_item_insert_after(Evas_Object *obj, - Elm_Object_Item *after, - const char *letter, - Evas_Smart_Cb func, - const void *data) +elm_index_item_insert_after(Evas_Object *obj, Elm_Object_Item *after, const char *letter, Evas_Smart_Cb func, const void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it; - - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - + if (!wd) return NULL; if (!after) return elm_index_item_append(obj, letter, func, data); - it = _item_new(obj, letter, func, data); if (!it) return NULL; - - sd->items = eina_list_append_relative(sd->items, it, after); - _index_box_clear(obj, sd->bx[sd->level], sd->level); - + wd->items = eina_list_append_relative(wd->items, it, after); + _index_box_clear(obj, wd->bx[wd->level], wd->level); return (Elm_Object_Item *)it; } EAPI Elm_Object_Item * -elm_index_item_insert_before(Evas_Object *obj, - Elm_Object_Item *before, - const char *letter, - Evas_Smart_Cb func, - const void *data) +elm_index_item_insert_before(Evas_Object *obj, Elm_Object_Item *before, const char *letter, Evas_Smart_Cb func, const void *data) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it; - - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - + if (!wd) return NULL; if (!before) return elm_index_item_prepend(obj, letter, func, data); - it = _item_new(obj, letter, func, data); if (!it) return NULL; - - sd->items = eina_list_prepend_relative(sd->items, it, before); - _index_box_clear(obj, sd->bx[sd->level], sd->level); - + wd->items = eina_list_prepend_relative(wd->items, it, before); + _index_box_clear(obj, wd->bx[wd->level], wd->level); return (Elm_Object_Item *)it; } EAPI Elm_Object_Item * -elm_index_item_sorted_insert(Evas_Object *obj, - const char *letter, - Evas_Smart_Cb func, - const void *data, - Eina_Compare_Cb cmp_func, - Eina_Compare_Cb cmp_data_func) +elm_index_item_sorted_insert(Evas_Object *obj, const char *letter, Evas_Smart_Cb func, const void *data, Eina_Compare_Cb cmp_func, Eina_Compare_Cb cmp_data_func) { - Elm_Index_Item *it; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_List *lnear; + Elm_Index_Item *it; int cmp; - ELM_INDEX_CHECK(obj) NULL; - ELM_INDEX_DATA_GET(obj, sd); - - if (!(sd->items)) return elm_index_item_append(obj, letter, func, data); + if (!wd) return NULL; + if (!(wd->items)) + return elm_index_item_append(obj, letter, func, data); it = _item_new(obj, letter, func, data); if (!it) return NULL; - lnear = eina_list_search_sorted_near_list(sd->items, cmp_func, it, &cmp); + lnear = eina_list_search_sorted_near_list(wd->items, cmp_func, it, &cmp); if (cmp < 0) - sd->items = eina_list_append_relative_list(sd->items, it, lnear); + wd->items = eina_list_append_relative_list(wd->items, it, lnear); else if (cmp > 0) - sd->items = eina_list_prepend_relative_list(sd->items, it, lnear); + wd->items = eina_list_prepend_relative_list(wd->items, it, lnear); else { /* If cmp_data_func is not provided, append a duplicated item */ if (!cmp_data_func) - sd->items = eina_list_append_relative_list(sd->items, it, lnear); + wd->items = eina_list_append_relative_list(wd->items, it, lnear); else { Elm_Index_Item *p_it = eina_list_data_get(lnear); @@ -951,36 +829,34 @@ elm_index_item_sorted_insert(Evas_Object *obj, elm_widget_item_free(it); } } - _index_box_clear(obj, sd->bx[sd->level], sd->level); - + _index_box_clear(obj, wd->bx[wd->level], wd->level); return (Elm_Object_Item *)it; } EAPI Elm_Object_Item * -elm_index_item_find(Evas_Object *obj, - const void *data) +elm_index_item_find(Evas_Object *obj, const void *data) { - ELM_INDEX_CHECK(obj) NULL; - - return (Elm_Object_Item *)_item_find(obj, data); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return (Elm_Object_Item *) _item_find(obj, data); } EAPI void elm_index_item_clear(Evas_Object *obj) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); Elm_Index_Item *it; Eina_List *l, *clear = NULL; - - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); - - _index_box_clear(obj, sd->bx[sd->level], sd->level); - EINA_LIST_FOREACH (sd->items, l, it) + if (!wd) return; + _index_box_clear(obj, wd->bx[wd->level], wd->level); + EINA_LIST_FOREACH(wd->items, l, it) { - if (it->level != sd->level) continue; + if (it->level != wd->level) continue; clear = eina_list_append(clear, it); } - EINA_LIST_FREE (clear, it) + EINA_LIST_FREE(clear, it) { _item_free(it); elm_widget_item_free(it); @@ -988,69 +864,69 @@ elm_index_item_clear(Evas_Object *obj) } EAPI void -elm_index_level_go(Evas_Object *obj, - int level __UNUSED__) +elm_index_level_go(Evas_Object *obj, int level __UNUSED__) { - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); - - _index_box_auto_fill(obj, sd->bx[0], 0); - if (sd->level == 1) _index_box_auto_fill(obj, sd->bx[1], 1); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _index_box_auto_fill(obj, wd->bx[0], 0); + if (wd->level == 1) _index_box_auto_fill(obj, wd->bx[1], 1); } EAPI void -elm_index_indicator_disabled_set(Evas_Object *obj, - Eina_Bool disabled) +elm_index_indicator_disabled_set(Evas_Object *obj, Eina_Bool disabled) { - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; disabled = !!disabled; - if (sd->indicator_disabled == disabled) return; - sd->indicator_disabled = disabled; - if (!sd->items) return; + if (wd->indicator_disabled == disabled) return; + wd->indicator_disabled = disabled; + if (!wd->items) return; if (disabled) - elm_layout_signal_emit(obj, "elm,indicator,state,inactive", "elm"); + edje_object_signal_emit(wd->base, "elm,indicator,state,inactive", "elm"); else - elm_layout_signal_emit(obj, "elm,indicator,state,active", "elm"); + edje_object_signal_emit(wd->base, "elm,indicator,state,active", "elm"); } EAPI Eina_Bool elm_index_indicator_disabled_get(const Evas_Object *obj) { - ELM_INDEX_CHECK(obj) EINA_FALSE; - ELM_INDEX_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - return sd->indicator_disabled; + return wd->indicator_disabled; } EAPI const char * elm_index_item_letter_get(const Elm_Object_Item *it) { - ELM_INDEX_ITEM_CHECK_OR_RETURN(it, NULL); - + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); return ((Elm_Index_Item *)it)->letter; } EAPI void -elm_index_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_index_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_INDEX_CHECK(obj); - ELM_INDEX_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; horizontal = !!horizontal; - if (horizontal == sd->horizontal) return; - - sd->horizontal = horizontal; - _elm_index_smart_theme(obj); + if (horizontal == wd->horizontal) return; + wd->horizontal = horizontal; + _theme_hook(obj); } EAPI Eina_Bool elm_index_horizontal_get(const Evas_Object *obj) { - ELM_INDEX_CHECK(obj) EINA_FALSE; - ELM_INDEX_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } + + diff --git a/src/lib/elm_index.h b/src/lib/elm_index.h index 25adb8b73..b26b12a45 100644 --- a/src/lib/elm_index.h +++ b/src/lib/elm_index.h @@ -21,11 +21,7 @@ * List "lists", @ref Genlist "generic lists" or @ref Gengrid * "general grids". * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for index objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * Smart events one can add callbacks for are: * - @c "changed" - When the selected index item changes. @c * event_info is the selected item's data pointer. * - @c "delay,changed" - When the selected index item changes, but diff --git a/src/lib/elm_label.c b/src/lib/elm_label.c index f7a70f910..b31ef2f31 100644 --- a/src/lib/elm_label.c +++ b/src/lib/elm_label.c @@ -1,213 +1,138 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char LABEL_SMART_NAME[] = "elm_label"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Label_Smart_Data Elm_Label_Smart_Data; - -struct _Elm_Label_Smart_Data -{ - Elm_Layout_Smart_Data base; - - const char *format; - double slide_duration; - Evas_Coord lastw; - Evas_Coord wrap_w; - Elm_Wrap_Type linewrap; - - Eina_Bool ellipsis : 1; - Eina_Bool slidingmode : 1; - Eina_Bool slidingellipsis : 1; -}; - -#define ELM_LABEL_DATA_GET(o, sd) \ - Elm_Label_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_LABEL_DATA_GET_OR_RETURN(o, ptr) \ - ELM_LABEL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_LABEL_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_LABEL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_LABEL_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), LABEL_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _text_aliases[] = +struct _Widget_Data { - {"default", "elm.text"}, - {NULL, NULL} + Evas_Object *lbl; + const char *label; + const char *format; + Ecore_Job *deferred_recalc_job; + double slide_duration; + Evas_Coord lastw; + Evas_Coord wrap_w; + Elm_Wrap_Type linewrap; + Eina_Bool changed : 1; + Eina_Bool ellipsis : 1; + Eina_Bool slidingmode : 1; + Eina_Bool slidingellipsis : 1; }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (LABEL_SMART_NAME, _elm_label, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static int _get_value_in_key_string(const char *oldstring, const char *key, char **value); +static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag); +static int _stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag); +static void _label_sliding_change(Evas_Object *obj); +static void _label_format_set(Evas_Object *obj, const char *format); static void -_recalc(void *data) +_elm_recalc_job(void *data) { - ELM_LABEL_DATA_GET(data, sd); - + Widget_Data *wd = elm_widget_data_get(data); Evas_Coord minw = -1, minh = -1; Evas_Coord resw; - + if (!wd) return; evas_event_freeze(evas_object_evas_get(data)); - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, NULL); - if (sd->wrap_w > resw) - resw = sd->wrap_w; - - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, resw, 0); + wd->deferred_recalc_job = NULL; + evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, NULL); + if (wd->wrap_w > resw) + resw = wd->wrap_w; + edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0); /* This is a hack to workaround the way min size hints are treated. * If the minimum width is smaller than the restricted width, it means * the mininmum doesn't matter. */ - if ((minw <= resw) && (minw != sd->wrap_w)) + if ((minw <= resw) && (minw != wd->wrap_w)) { Evas_Coord ominw = -1; - evas_object_size_hint_min_get(data, &ominw, NULL); minw = ominw; } - evas_object_size_hint_min_set(data, minw, minh); evas_event_thaw(evas_object_evas_get(data)); evas_event_thaw_eval(evas_object_evas_get(data)); } static void -_label_format_set(Evas_Object *obj, - const char *format) +_del_hook(Evas_Object *obj) { - if (format) - edje_object_part_text_style_user_push(obj, "elm.text", format); - else - edje_object_part_text_style_user_pop(obj, "elm.text"); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_event_freeze(evas_object_evas_get(obj)); + if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job); + if (wd->label) eina_stringshare_del(wd->label); + free(wd); + evas_event_thaw(evas_object_evas_get(obj)); + evas_event_thaw_eval(evas_object_evas_get(obj)); } static void -_label_sliding_change(Evas_Object *obj) +_theme_change(Evas_Object *obj) { - char *plaintxt; - int plainlen = 0; - - ELM_LABEL_DATA_GET(obj, sd); - - // doesn't support multiline sliding effect - if (sd->linewrap) - { - sd->slidingmode = EINA_FALSE; - return; - } - - plaintxt = _elm_util_mkup_to_text - (edje_object_part_text_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.text")); - if (plaintxt != NULL) - { - plainlen = strlen(plaintxt); - free(plaintxt); - } - // too short to slide label - if (plainlen < 1) - { - sd->slidingmode = EINA_TRUE; - return; - } - - if (sd->slidingmode) - { - Edje_Message_Float_Set *msg = - alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double))); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - if (sd->ellipsis) - { - sd->slidingellipsis = EINA_TRUE; - elm_label_ellipsis_set(obj, EINA_FALSE); - } - - msg->count = 1; - msg->val[0] = sd->slide_duration; - - edje_object_message_send - (ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_FLOAT_SET, 0, msg); - edje_object_signal_emit - (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,slide,start", "elm"); - } - else - { - edje_object_signal_emit - (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,slide,stop", "elm"); - if (sd->slidingellipsis) - { - sd->slidingellipsis = EINA_FALSE; - elm_label_ellipsis_set(obj, EINA_TRUE); - } - } + _elm_theme_object_set(obj, wd->lbl, "label", "base", + elm_widget_style_get(obj)); } -static Eina_Bool -_elm_label_smart_theme(Evas_Object *obj) +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Eina_Bool ret; - - ELM_LABEL_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->lbl, rtl); +} +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; evas_event_freeze(evas_object_evas_get(obj)); - - ret = ELM_WIDGET_CLASS(_elm_label_parent_sc)->theme(obj); - if (!ret) goto end; - - _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format); + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _theme_change(obj); + _label_format_set(wd->lbl, wd->format); + 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); _label_sliding_change(obj); - -end: + _sizing_eval(obj); evas_event_thaw(evas_object_evas_get(obj)); evas_event_thaw_eval(evas_object_evas_get(obj)); - - return ret; } static void -_elm_label_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; Evas_Coord resw, resh; + if (!wd) return; - ELM_LABEL_DATA_GET(obj, sd); - - if (sd->linewrap) + if (wd->linewrap) { - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh); - if (resw == sd->lastw) return; - sd->lastw = resw; - _recalc(obj); + evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh); + if ((resw == wd->lastw) && (!wd->changed)) return; + wd->changed = EINA_FALSE; + wd->lastw = resw; + _elm_recalc_job(obj); + // FIXME: works ok. but NOT for genlist. what should genlist do? + // if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job); + // wd->deferred_recalc_job = ecore_job_add(_elm_recalc_job, obj); } else { evas_event_freeze(evas_object_evas_get(obj)); - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh); - edje_object_size_min_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - if (sd->wrap_w > 0 && minw > sd->wrap_w) minw = sd->wrap_w; + evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh); + edje_object_size_min_calc(wd->lbl, &minw, &minh); + if (wd->wrap_w > 0 && minw > wd->wrap_w) minw = wd->wrap_w; evas_object_size_hint_min_set(obj, minw, minh); evas_event_thaw(evas_object_evas_get(obj)); evas_event_thaw_eval(evas_object_evas_get(obj)); @@ -215,20 +140,24 @@ _elm_label_smart_sizing_eval(Evas_Object *obj) } static void -_on_label_resize(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_lbl_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_LABEL_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (wd->linewrap) _sizing_eval(data); +} - if (sd->linewrap) elm_layout_sizing_eval(data); +static void +_label_format_set(Evas_Object *obj, const char *format) +{ + if (format) + edje_object_part_text_style_user_push(obj, "elm.text", format); + else + edje_object_part_text_style_user_pop(obj, "elm.text"); } static int -_get_value_in_key_string(const char *oldstring, - const char *key, - char **value) +_get_value_in_key_string(const char *oldstring, const char *key, char **value) { char *curlocater, *endtag; int firstindex = 0, foundflag = -1; @@ -259,11 +188,9 @@ _get_value_in_key_string(const char *oldstring, return -1; } + static int -_strbuf_key_value_replace(Eina_Strbuf *srcbuf, - const char *key, - const char *value, - int deleteflag) +_strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag) { char *kvalue; const char *srcstring = NULL; @@ -278,9 +205,9 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf, val_end = strchr(kvalue, ' '); if (val_end) - val_end_idx = val_end - srcstring; + val_end_idx = val_end - srcstring; else - val_end_idx = kvalue - srcstring + strlen(kvalue) - 1; + val_end_idx = kvalue - srcstring + strlen(kvalue) - 1; /* -1 is because of the '=' */ key_start_idx = kvalue - srcstring - 1 - strlen(key); @@ -288,7 +215,7 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf, if (!deleteflag) { eina_strbuf_insert_printf(srcbuf, "%s=%s", key_start_idx, key, - value); + value); } } else if (!deleteflag) @@ -296,24 +223,19 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf, if (*srcstring) { /* -1 because we want it before the ' */ - eina_strbuf_insert_printf - (srcbuf, " %s=%s", eina_strbuf_length_get(srcbuf) - 1, key, - value); + eina_strbuf_insert_printf(srcbuf, " %s=%s", + eina_strbuf_length_get(srcbuf) - 1, key, value); } else { eina_strbuf_append_printf(srcbuf, "DEFAULT='%s=%s'", key, value); } } - return 0; } static int -_stringshare_key_value_replace(const char **srcstring, - const char *key, - const char *value, - int deleteflag) +_stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag) { Eina_Strbuf *sharebuf = NULL; @@ -327,190 +249,223 @@ _stringshare_key_value_replace(const char **srcstring, return 0; } -static Eina_Bool -_elm_label_smart_text_set(Evas_Object *obj, - const char *item, - const char *label) -{ - ELM_LABEL_DATA_GET(obj, sd); - - if (!label) label = ""; - _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format); - - return _elm_label_parent_sc->text_set(obj, item, label); -} - -static Eina_Bool -_elm_label_smart_translate(Evas_Object *obj) -{ - evas_object_smart_callback_call(obj, "language,changed", NULL); - - return EINA_TRUE; -} - static void -_elm_label_smart_add(Evas_Object *obj) +_label_sliding_change(Evas_Object *obj) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Label_Smart_Data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + char *plaintxt; + int plainlen = 0; - ELM_WIDGET_CLASS(_elm_label_parent_sc)->base.add(obj); + // dosen't support multiline sliding effect + if (wd->linewrap) + { + wd->slidingmode = EINA_FALSE; + return; + } - priv->linewrap = ELM_WRAP_NONE; - priv->ellipsis = EINA_FALSE; - priv->slidingmode = EINA_FALSE; - priv->slidingellipsis = EINA_FALSE; - priv->wrap_w = -1; - priv->slide_duration = 10; + plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text")); + if (plaintxt != NULL) + { + plainlen = strlen(plaintxt); + free(plaintxt); + } + // too short to slide label + if (plainlen < 1) + { + wd->slidingmode = EINA_TRUE; + return; + } - priv->format = eina_stringshare_add(""); - _label_format_set(ELM_WIDGET_DATA(priv)->resize_obj, priv->format); + if (wd->slidingmode) + { + Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double))); - evas_object_event_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_RESIZE, - _on_label_resize, obj); + if (wd->ellipsis) + { + wd->slidingellipsis = EINA_TRUE; + elm_label_ellipsis_set(obj, EINA_FALSE); + } - elm_widget_can_focus_set(obj, EINA_FALSE); + msg->count = 1; + msg->val[0] = wd->slide_duration; - elm_layout_theme_set(obj, "label", "base", elm_widget_style_get(obj)); - elm_layout_text_set(obj, NULL, "<br>"); + edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg); + edje_object_signal_emit(wd->lbl, "elm,state,slide,start", "elm"); + } + else + { + edje_object_signal_emit(wd->lbl, "elm,state,slide,stop", "elm"); + if (wd->slidingellipsis) + { + wd->slidingellipsis = EINA_FALSE; + elm_label_ellipsis_set(obj, EINA_TRUE); + } + } } static void -_elm_label_smart_set_user(Elm_Layout_Smart_Class *sc) +_elm_label_label_set(Evas_Object *obj, const char *item, const char *label) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_label_smart_add; - - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - ELM_WIDGET_CLASS(sc)->theme = _elm_label_smart_theme; - ELM_WIDGET_CLASS(sc)->translate = _elm_label_smart_translate; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (item && strcmp(item, "default")) return; + if (!label) label = ""; + eina_stringshare_replace(&wd->label, label); + _label_format_set(wd->lbl, wd->format); + edje_object_part_text_set(wd->lbl, "elm.text", wd->label); + wd->changed = 1; + _sizing_eval(obj); +} - sc->sizing_eval = _elm_label_smart_sizing_eval; - sc->text_set = _elm_label_smart_text_set; +static const char * +_elm_label_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if (!wd) return NULL; + return wd->label; +} - sc->text_aliases = _text_aliases; +static void +_translate_hook(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, "language,changed", NULL); } EAPI Evas_Object * elm_label_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_label_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_sizing_eval(obj); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "label"); + elm_widget_type_set(obj, "label"); + elm_widget_sub_object_add(parent, obj); + 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, EINA_FALSE); + elm_widget_text_set_hook_set(obj, _elm_label_label_set); + elm_widget_text_get_hook_set(obj, _elm_label_label_get); + elm_widget_translate_hook_set(obj, _translate_hook); + + wd->linewrap = ELM_WRAP_NONE; + wd->ellipsis = EINA_FALSE; + wd->slidingmode = EINA_FALSE; + wd->slidingellipsis = EINA_FALSE; + wd->wrap_w = -1; + wd->slide_duration = 10; + + wd->lbl = edje_object_add(e); + _elm_theme_object_set(obj, wd->lbl, "label", "base", "default"); + wd->format = eina_stringshare_add(""); + wd->label = eina_stringshare_add("<br>"); + _label_format_set(wd->lbl, wd->format); + edje_object_part_text_set(wd->lbl, "elm.text", wd->label); + + elm_widget_resize_object_set(obj, wd->lbl); + + evas_object_event_callback_add(wd->lbl, EVAS_CALLBACK_RESIZE, _lbl_resize, obj); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + wd->changed = 1; + _sizing_eval(obj); return obj; } EAPI void -elm_label_line_wrap_set(Evas_Object *obj, - Elm_Wrap_Type wrap) +elm_label_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap) { - const char *wrap_str, *text; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + const char *wrap_str; int len; - ELM_LABEL_CHECK(obj); - ELM_LABEL_DATA_GET(obj, sd); - - if (sd->linewrap == wrap) return; - - sd->linewrap = wrap; - text = elm_layout_text_get(obj, NULL); - if (!text) return; - - len = strlen(text); + if (!wd) return; + if (wd->linewrap == wrap) return; + wd->linewrap = wrap; + len = strlen(wd->label); if (len <= 0) return; switch (wrap) { case ELM_WRAP_CHAR: - wrap_str = "char"; - break; - + wrap_str = "char"; + break; case ELM_WRAP_WORD: - wrap_str = "word"; - break; - + wrap_str = "word"; + break; case ELM_WRAP_MIXED: - wrap_str = "mixed"; - break; - + wrap_str = "mixed"; + break; default: - wrap_str = "none"; - break; + wrap_str = "none"; + break; } - if (_stringshare_key_value_replace(&sd->format, "wrap", wrap_str, 0) == 0) + if (_stringshare_key_value_replace(&wd->format, + "wrap", wrap_str, 0) == 0) { - _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format); - elm_layout_sizing_eval(obj); + _label_format_set(wd->lbl, wd->format); + edje_object_part_text_set(wd->lbl, "elm.text", wd->label); + wd->changed = 1; + _sizing_eval(obj); } } EAPI Elm_Wrap_Type elm_label_line_wrap_get(const Evas_Object *obj) { - ELM_LABEL_CHECK(obj) EINA_FALSE; - ELM_LABEL_DATA_GET(obj, sd); - - return sd->linewrap; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->linewrap; } EAPI void -elm_label_wrap_width_set(Evas_Object *obj, - Evas_Coord w) +elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w) { - ELM_LABEL_CHECK(obj); - ELM_LABEL_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (w < 0) w = 0; - - if (sd->wrap_w == w) return; - - if (sd->ellipsis) - _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format); - sd->wrap_w = w; - - elm_layout_sizing_eval(obj); + if (wd->wrap_w == w) return; + if (wd->ellipsis) + { + _label_format_set(wd->lbl, wd->format); + edje_object_part_text_set(wd->lbl, "elm.text", wd->label); + } + wd->wrap_w = w; + _sizing_eval(obj); } EAPI Evas_Coord elm_label_wrap_width_get(const Evas_Object *obj) { - ELM_LABEL_CHECK(obj) 0; - ELM_LABEL_DATA_GET(obj, sd); - - return sd->wrap_w; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->wrap_w; } EAPI void -elm_label_ellipsis_set(Evas_Object *obj, - Eina_Bool ellipsis) +elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis) { + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); Eina_Strbuf *fontbuf = NULL; int len, removeflag = 0; - const char *text; - - ELM_LABEL_CHECK(obj); - ELM_LABEL_DATA_GET(obj, sd); - if (sd->ellipsis == ellipsis) return; - sd->ellipsis = ellipsis; - - text = elm_layout_text_get(obj, NULL); - if (!text) return; - - len = strlen(text); + if (!wd) return; + if (wd->ellipsis == ellipsis) return; + wd->ellipsis = ellipsis; + len = strlen(wd->label); if (len <= 0) return; if (ellipsis == EINA_FALSE) removeflag = 1; // remove fontsize tag @@ -518,69 +473,71 @@ elm_label_ellipsis_set(Evas_Object *obj, fontbuf = eina_strbuf_new(); eina_strbuf_append_printf(fontbuf, "%f", 1.0); - if (_stringshare_key_value_replace - (&sd->format, "ellipsis", eina_strbuf_string_get - (fontbuf), removeflag) == 0) + if (_stringshare_key_value_replace(&wd->format, + "ellipsis", eina_strbuf_string_get(fontbuf), removeflag) == 0) { - _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format); - elm_layout_sizing_eval(obj); + _label_format_set(wd->lbl, wd->format); + edje_object_part_text_set(wd->lbl, "elm.text", wd->label); + wd->changed = 1; + _sizing_eval(obj); } eina_strbuf_free(fontbuf); + } EAPI Eina_Bool elm_label_ellipsis_get(const Evas_Object *obj) { - ELM_LABEL_CHECK(obj) EINA_FALSE; - ELM_LABEL_DATA_GET(obj, sd); - - return sd->ellipsis; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->ellipsis; } EAPI void elm_label_slide_set(Evas_Object *obj, - Eina_Bool slide) + Eina_Bool slide) { - ELM_LABEL_CHECK(obj); - ELM_LABEL_DATA_GET(obj, sd); - - if (sd->slidingmode == slide) return; - sd->slidingmode = slide; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->slidingmode == slide) return; + wd->slidingmode = slide; _label_sliding_change(obj); - elm_layout_sizing_eval(obj); + wd->changed = 1; + _sizing_eval(obj); } EAPI Eina_Bool elm_label_slide_get(const Evas_Object *obj) { - ELM_LABEL_CHECK(obj) EINA_FALSE; - ELM_LABEL_DATA_GET(obj, sd); - - return sd->slidingmode; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->slidingmode; } EAPI void elm_label_slide_duration_set(Evas_Object *obj, double duration) { - ELM_LABEL_CHECK(obj); - ELM_LABEL_DATA_GET(obj, sd); - - Edje_Message_Float_Set *msg = - alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double))); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double))); - sd->slide_duration = duration; + if (!wd) return; + wd->slide_duration = duration; msg->count = 1; - msg->val[0] = sd->slide_duration; - edje_object_message_send - (ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_FLOAT_SET, 0, msg); + msg->val[0] = wd->slide_duration; + edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg); } EAPI double elm_label_slide_duration_get(const Evas_Object *obj) { - ELM_LABEL_CHECK(obj) 0.0; - ELM_LABEL_DATA_GET(obj, sd); - - return sd->slide_duration; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->slide_duration; } + diff --git a/src/lib/elm_label.h b/src/lib/elm_label.h index d7ec89f0a..7fdc61924 100644 --- a/src/lib/elm_label.h +++ b/src/lib/elm_label.h @@ -25,12 +25,8 @@ * Custom themes can of course invent new markup tags and style them any way * they like. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for label objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * @li @c "language,changed": The program's language changed. + * The following signals may be emitted by the label widget: + * @li "language,changed": The program's language changed. * * See @ref tutorial_label for a demonstration of how to use a label widget. * @{ diff --git a/src/lib/elm_layout.c b/src/lib/elm_layout.c index c2708f575..6f144849b 100644 --- a/src/lib/elm_layout.c +++ b/src/lib/elm_layout.c @@ -1,268 +1,245 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" - -static const char LAYOUT_SMART_NAME[] = "elm_layout"; - -#define ELM_LAYOUT_DATA_GET(o, sd) \ - Elm_Layout_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_LAYOUT_DATA_GET_OR_RETURN(o, ptr) \ - ELM_LAYOUT_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_LAYOUT_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_LAYOUT_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), LAYOUT_SMART_NAME, __func__)) \ - return -static const char SIG_THEME_CHANGED[] = "theme,changed"; - -/* no *direct* instantiation of this class, so far */ -__UNUSED__ static Evas_Smart *_elm_layout_smart_class_new(void); +typedef struct _Widget_Data Widget_Data; +typedef struct _Subinfo Subinfo; +typedef struct _Part_Cursor Part_Cursor; -/* smart callbacks coming from elm layout objects: */ -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_THEME_CHANGED, ""}, - {NULL, NULL} +struct _Widget_Data +{ + Evas_Object *obj; + Evas_Object *lay; + Eina_List *subs; + Eina_List *parts_cursors; + Eina_Bool needs_size_calc:1; + const char *clas, *group, *style; }; -/* these are data operated by layout's class functions internally, and - * should not be messed up by inhering classes */ -typedef struct _Elm_Layout_Sub_Object_Data Elm_Layout_Sub_Object_Data; -typedef struct _Elm_Layout_Sub_Object_Cursor Elm_Layout_Sub_Object_Cursor; - -struct _Elm_Layout_Sub_Object_Data +struct _Subinfo { - const char *part; + const char *part; Evas_Object *obj; - - enum { - SWALLOW, - BOX_APPEND, - BOX_PREPEND, - BOX_INSERT_BEFORE, - BOX_INSERT_AT, - TABLE_PACK, - TEXT - } type; - - union { - union { - const Evas_Object *reference; - unsigned int pos; - } box; - struct - { - unsigned short col, row, colspan, rowspan; - } table; - struct - { - const char *text; - } text; - } p; + enum + { + SWALLOW, + BOX_APPEND, + BOX_PREPEND, + BOX_INSERT_BEFORE, + BOX_INSERT_AT, + TABLE_PACK, + TEXT + } type; + union + { + union + { + const Evas_Object *reference; + unsigned int pos; + } box; + struct + { + unsigned short col, row, colspan, rowspan; + } table; + struct + { + const char *text; + } text; + } p; }; -struct _Elm_Layout_Sub_Object_Cursor +struct _Part_Cursor { Evas_Object *obj; - const char *part; - const char *cursor; - const char *style; - - Eina_Bool engine_only : 1; + const char *part; + const char *cursor; + const char *style; + Eina_Bool engine_only:1; }; -/* FIXME: get rid of Edje_Signal_Data after the last compat widget is - * migrated */ +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Widget_Data *wd); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _part_cursor_free(Part_Cursor *pc); -/* this is here in order to hide the layout's inner Edje object - * (unless the user wants to bypass it and call elm_layout_edje_get()) - * as much as possible. so, when registering signal callbacks on it, - * we call back passing the actual widget as object, not the Edje - * object, for example */ -typedef struct _Layout_Signal_Data Layout_Signal_Data; -struct _Layout_Signal_Data -{ - Evas_Object *obj; - Edje_Signal_Cb func; - const char *emission; - const char *source; - void *data; +static const char SIG_THEME_CHANGED[] = "theme,changed"; + +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_THEME_CHANGED, ""}, + {NULL, NULL} }; -/* layout's sizing evaluation is deferred. evaluation requests are - * queued up and only flag the object as 'changed'. when it comes to - * Evas's rendering phase, it will be addressed, finally (see - * _elm_layout_smart_calculate()). */ static void -_elm_layout_smart_sizing_eval(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - ELM_LAYOUT_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + Part_Cursor *pc; - if (sd->needs_size_calc) return; - sd->needs_size_calc = EINA_TRUE; - - evas_object_smart_changed(obj); + if (!wd) return; + EINA_LIST_FREE(wd->subs, si) + { + eina_stringshare_del(si->part); + if (si->type == TEXT) + eina_stringshare_del(si->p.text.text); + free(si); + } + EINA_LIST_FREE(wd->parts_cursors, pc) _part_cursor_free(pc); + free(wd); } static void -_on_sub_object_size_hint_change(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_LAYOUT_DATA_GET(data, sd); - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->lay, rtl); } static void -_part_cursor_free(Elm_Layout_Sub_Object_Cursor *pc) -{ - eina_stringshare_del(pc->part); - eina_stringshare_del(pc->style); - eina_stringshare_del(pc->cursor); - - free(pc); +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->lay, wd->clas, wd->group, wd->style); + edje_object_scale_set(wd->lay, elm_widget_scale_get(obj) * + _elm_config->scale); + evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL); + _sizing_eval(wd); } -/* Elementary smart class for all widgets having an Edje layout as a - * building block */ -EVAS_SMART_SUBCLASS_NEW - (LAYOUT_SMART_NAME, _elm_layout, Elm_Layout_Smart_Class, - Elm_Container_Smart_Class, elm_container_smart_class_get, _smart_callbacks); - -EAPI const Elm_Layout_Smart_Class * -elm_layout_smart_class_get(void) +static void +_changed_hook(Evas_Object *obj) { - static Elm_Layout_Smart_Class _sc = - ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION(LAYOUT_SMART_NAME); - static const Elm_Layout_Smart_Class *class = NULL; - - if (class) - return class; - - _elm_layout_smart_set(&_sc); - class = &_sc; - - return class; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->needs_size_calc) + { + _sizing_eval(wd); + wd->needs_size_calc = 0; + } } static void -_sizing_eval(Evas_Object *obj, Elm_Layout_Smart_Data *sd) +_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) { - Evas_Coord minw = -1, minh = -1; - - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, -1, -1); + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_emit(wd->lay, emission, source); } -/* common content cases for layout objects: icon and text */ -static inline void -_icon_signal_emit(Elm_Layout_Smart_Data *sd, - Elm_Layout_Sub_Object_Data *sub_d, - Eina_Bool visible) +static void +_signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) { - char buf[64]; - const char *type; - - if (sub_d->type != SWALLOW || - (strcmp("elm.swallow.icon", sub_d->part) && - (strcmp("elm.swallow.end", sub_d->part)))) - return; - - type = sub_d->part + 12; + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_callback_add(wd->lay, emission, source, func_cb, data); +} - snprintf(buf, sizeof(buf), "elm,state,%s,%s", type, - visible ? "visible" : "hidden"); +static void +_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) +{ + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_callback_del_full(wd->lay, emission, source, func_cb, + data); +} - edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, buf, "elm"); - /* themes might need imediate action here */ - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); +static void * +_elm_layout_list_data_get(const Eina_List *list) +{ + Subinfo *si = eina_list_data_get(list); + return si->obj; } -static inline void -_text_signal_emit(Elm_Layout_Smart_Data *sd, - Elm_Layout_Sub_Object_Data *sub_d, - Eina_Bool visible) +static Eina_Bool +_elm_layout_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - char buf[64]; + Widget_Data *wd = elm_widget_data_get(obj); + const Eina_List *items; + void *(*list_data_get) (const Eina_List *list); - if (sub_d->type != TEXT || strcmp("elm.text", sub_d->part)) - return; + if ((!wd) || (!wd->subs)) + return EINA_FALSE; - snprintf(buf, sizeof(buf), - visible ? "elm,state,text,visible" : "elm,state,text,hidden"); + /* Focus chain (This block is diferent of elm_win cycle)*/ + if ((items = elm_widget_focus_custom_chain_get(obj))) + list_data_get = eina_list_data_get; + else + { + items = wd->subs; + list_data_get = _elm_layout_list_data_get; - edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, buf, "elm"); + if (!items) return EINA_FALSE; + } - /* themes might need imediate action here */ - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, + next); } static void -_parts_signals_emit(Elm_Layout_Smart_Data *sd) +_sizing_eval(Widget_Data *wd) { - const Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) - { - _icon_signal_emit(sd, sub_d, EINA_TRUE); - _text_signal_emit(sd, sub_d, EINA_TRUE); - } + Evas_Coord minw = -1, minh = -1; + edje_object_size_min_calc(wd->lay, &minw, &minh); + evas_object_size_hint_min_set(wd->obj, minw, minh); + evas_object_size_hint_max_set(wd->obj, -1, -1); } static void -_parts_text_fix(Elm_Layout_Smart_Data *sd) +_request_sizing_eval(Widget_Data *wd) { - const Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; + if (wd->needs_size_calc) return; + wd->needs_size_calc = 1; + evas_object_smart_changed(wd->obj); +} - EINA_LIST_FOREACH (sd->subs, l, sub_d) - { - if (sub_d->type == TEXT) - edje_object_part_text_escaped_set - (ELM_WIDGET_DATA(sd)->resize_obj, sub_d->part, sub_d->p.text.text); - } +static void +_part_cursor_free(Part_Cursor *pc) +{ + eina_stringshare_del(pc->part); + eina_stringshare_del(pc->style); + eina_stringshare_del(pc->cursor); + free(pc); } static void -_part_cursor_part_apply(const Elm_Layout_Sub_Object_Cursor *pc) +_part_cursor_part_apply(const Part_Cursor *pc) { elm_object_cursor_set(pc->obj, pc->cursor); elm_object_cursor_style_set(pc->obj, pc->style); elm_object_cursor_theme_search_enabled_set(pc->obj, pc->engine_only); } -static void -_parts_cursors_apply(Elm_Layout_Smart_Data *sd) +static Part_Cursor * +_parts_cursors_find(Widget_Data *wd, const char *part) { const Eina_List *l; + Part_Cursor *pc; + EINA_LIST_FOREACH(wd->parts_cursors, l, pc) + { + if (!strcmp(pc->part, part)) + return pc; + } + return NULL; +} + +static void +_parts_cursors_apply(Widget_Data *wd) +{ const char *file, *group; - Elm_Layout_Sub_Object_Cursor *pc; + const Eina_List *l; + Part_Cursor *pc; - edje_object_file_get(ELM_WIDGET_DATA(sd)->resize_obj, &file, &group); + edje_object_file_get(wd->lay, &file, &group); - EINA_LIST_FOREACH (sd->parts_cursors, l, pc) + EINA_LIST_FOREACH(wd->parts_cursors, l, pc) { Evas_Object *obj = (Evas_Object *)edje_object_part_object_get - (ELM_WIDGET_DATA(sd)->resize_obj, pc->part); + (wd->lay, pc->part); if (!obj) { @@ -287,1317 +264,598 @@ _parts_cursors_apply(Elm_Layout_Smart_Data *sd) } static void -_visuals_refresh(Evas_Object *obj, Elm_Layout_Smart_Data *sd) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - _parts_signals_emit(sd); - _parts_text_fix(sd); - _parts_cursors_apply(sd); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + _request_sizing_eval(data); } -static Eina_Bool -_elm_layout_smart_disable(Evas_Object *obj) -{ - ELM_LAYOUT_DATA_GET(obj, sd); - - if (elm_object_disabled_get(obj)) - edje_object_signal_emit - (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,disabled", "elm"); - else - edje_object_signal_emit - (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,enabled", "elm"); - - return EINA_TRUE; -} - -static Eina_Bool -_elm_layout_smart_theme(Evas_Object *obj) -{ - Eina_Bool ret; - const char *fh; - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_layout_parent_sc)->theme(obj)) return EINA_FALSE; - - edje_object_mirrored_set - (ELM_WIDGET_DATA(sd)->resize_obj, elm_widget_mirrored_get(obj)); - - /* function already prints error messages, if any */ - ret = elm_widget_theme_object_set - (obj, ELM_WIDGET_DATA(sd)->resize_obj, sd->klass, sd->group, - elm_widget_style_get(obj)); - - edje_object_scale_set - (ELM_WIDGET_DATA(sd)->resize_obj, - elm_widget_scale_get(obj) * elm_config_scale_get()); - - fh = edje_object_data_get - (ELM_WIDGET_DATA(sd)->resize_obj, "focus_highlight"); - if ((fh) && (!strcmp(fh, "on"))) - elm_widget_highlight_in_theme_set(obj, EINA_TRUE); - else - elm_widget_highlight_in_theme_set(obj, EINA_FALSE); - - evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL); - - _visuals_refresh(obj, sd); - - return ret; -} - -static void * -_elm_layout_list_data_get(const Eina_List *list) -{ - Elm_Layout_Sub_Object_Data *sub_d = eina_list_data_get(list); - - return sub_d->obj; -} - -static Eina_Bool -_elm_layout_smart_on_focus(Evas_Object *obj) -{ - ELM_LAYOUT_DATA_GET(obj, sd); - - if (elm_widget_focus_get(obj)) - { - elm_layout_signal_emit(obj, "elm,action,focus", "elm"); - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); - } - else - { - elm_layout_signal_emit(obj, "elm,action,unfocus", "elm"); - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE); - } - - return EINA_TRUE; -} - -/* WARNING: if you're making a widget *not* supposed to have focusable - * child objects, but still inheriting from elm_layout, just set its - * focus_next smart function back to NULL */ -static Eina_Bool -_elm_layout_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) -{ - const Eina_List *items; - void *(*list_data_get)(const Eina_List *list); - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!sd->subs) return EINA_FALSE; - - if ((items = elm_widget_focus_custom_chain_get(obj))) - list_data_get = eina_list_data_get; - else - { - items = sd->subs; - list_data_get = _elm_layout_list_data_get; - } - - return elm_widget_focus_list_next_get - (obj, items, list_data_get, dir, next); -} - -static Eina_Bool -_elm_layout_smart_sub_object_add(Evas_Object *obj, - Evas_Object *sobj) -{ - if (!ELM_WIDGET_CLASS(_elm_layout_parent_sc)->sub_object_add(obj, sobj)) - return EINA_FALSE; - - evas_object_event_callback_add - (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_sub_object_size_hint_change, obj); - - return EINA_TRUE; -} - -static Eina_Bool -_elm_layout_smart_sub_object_del(Evas_Object *obj, - Evas_Object *sobj) +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_layout_parent_sc)->sub_object_del(obj, sobj)) - return EINA_FALSE; - - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_sub_object_size_hint_change, obj); - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + Subinfo *si; + if (!wd) return; + EINA_LIST_FOREACH(wd->subs, l, si) { - if (sub_d->obj != sobj) continue; - - sd->subs = eina_list_remove_list(sd->subs, l); - - _icon_signal_emit(sd, sub_d, EINA_FALSE); - - eina_stringshare_del(sub_d->part); - free(sub_d); - - break; + if (si->obj == sub) + { + evas_object_event_callback_del_full(sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, + wd); + wd->subs = eina_list_remove_list(wd->subs, l); + eina_stringshare_del(si->part); + free(si); + break; + } } - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); - - return EINA_TRUE; } static void -_elm_layout_smart_signal(Evas_Object *obj, - const char *emission, - const char *source) +_signal_size_eval(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_LAYOUT_DATA_GET(obj, sd); - - edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, emission, source); + _request_sizing_eval(data); } static void -_edje_signal_callback(void *data, - Evas_Object *obj __UNUSED__, - const char *emission, - const char *source) +_parts_text_fix(Widget_Data *wd) { - Layout_Signal_Data *lsd = data; - - lsd->func(lsd->data, lsd->obj, emission, source); -} - -static void -_elm_layout_smart_callback_add(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func_cb, - void *data) -{ - Layout_Signal_Data *lsd; - - ELM_LAYOUT_DATA_GET(obj, sd); - - lsd = ELM_NEW(Layout_Signal_Data); - if (!lsd) return; - - lsd->obj = obj; - lsd->func = func_cb; - lsd->emission = eina_stringshare_add(emission); - lsd->source = eina_stringshare_add(source); - lsd->data = data; - sd->edje_signals = eina_list_append(sd->edje_signals, lsd); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(sd)->resize_obj, emission, source, - _edje_signal_callback, lsd); -} - -static void * -_elm_layout_smart_callback_del(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func_cb) -{ - Layout_Signal_Data *lsd = NULL; - void *data = NULL; - Eina_List *l; - - ELM_LAYOUT_DATA_GET(obj, sd); - - EINA_LIST_FOREACH (sd->edje_signals, l, lsd) - { - if ((lsd->func == func_cb) && (!strcmp(lsd->emission, emission)) && - (!strcmp(lsd->source, source))) - { - sd->edje_signals = eina_list_remove_list(sd->edje_signals, l); - eina_stringshare_del(lsd->emission); - eina_stringshare_del(lsd->source); - data = lsd->data; - free(lsd); - - edje_object_signal_callback_del_full - (ELM_WIDGET_DATA(sd)->resize_obj, emission, source, - _edje_signal_callback, lsd); - - return data; /* stop at 1st match */ - } - } - - return data; -} - -static Eina_Bool -_elm_layout_part_aliasing_eval(Elm_Layout_Smart_Data *sd, - const char **part, - Eina_Bool is_text) -{ -#define ALIAS_LIST(_sd, _list) \ - ((ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(_sd)->api))->_list) - - const Elm_Layout_Part_Alias_Description *aliases = is_text ? - ALIAS_LIST(sd, text_aliases) : ALIAS_LIST(sd, content_aliases); - -#undef ALIAS_LIST - - if (!aliases) return EINA_TRUE; - - while (aliases->alias && aliases->real_part) - { - /* NULL matches the 1st */ - if ((!*part) || (!strcmp(*part, aliases->alias))) - { - *part = aliases->real_part; - break; - } - - aliases++; - } + const Eina_List *l; + Subinfo *si; - if (!*part) + EINA_LIST_FOREACH(wd->subs, l, si) { - ERR("no default content part set for object %p -- " - "part must not be NULL", ELM_WIDGET_DATA(sd)->obj); - return EINA_FALSE; + if (si->type == TEXT) + edje_object_part_text_escaped_set(wd->lay, si->part, si->p.text.text); } - - /* if no match, part goes on with the same value */ - - return EINA_TRUE; } -static Eina_Bool -_elm_layout_smart_text_set(Evas_Object *obj, - const char *part, - const char *text) +static void +_elm_layout_label_set(Evas_Object *obj, const char *part, const char *text) { + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si = NULL; Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d = NULL; - - ELM_LAYOUT_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + if (!part) part = "elm.text"; - if (!_elm_layout_part_aliasing_eval(sd, &part, EINA_TRUE)) - return EINA_FALSE; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + EINA_LIST_FOREACH(wd->subs, l, si) { - if ((sub_d->type == TEXT) && (!strcmp(part, sub_d->part))) + if ((si->type == TEXT) && (!strcmp(part, si->part))) { if (!text) { - eina_stringshare_del(sub_d->part); - eina_stringshare_del(sub_d->p.text.text); - free(sub_d); - edje_object_part_text_escaped_set - (ELM_WIDGET_DATA(sd)->resize_obj, part, NULL); - sd->subs = eina_list_remove_list(sd->subs, l); - return EINA_TRUE; + eina_stringshare_del(si->part); + eina_stringshare_del(si->p.text.text); + free(si); + edje_object_part_text_escaped_set(wd->lay, part, NULL); + wd->subs = eina_list_remove_list(wd->subs, l); + return; } else break; } - sub_d = NULL; + si = NULL; } - if (!edje_object_part_text_escaped_set - (ELM_WIDGET_DATA(sd)->resize_obj, part, text)) - return EINA_FALSE; - - if (!sub_d) + if (!si) { - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - if (!sub_d) return EINA_FALSE; - sub_d->type = TEXT; - sub_d->part = eina_stringshare_add(part); - sd->subs = eina_list_append(sd->subs, sub_d); + si = ELM_NEW(Subinfo); + if (!si) return; + si->type = TEXT; + si->part = eina_stringshare_add(part); + wd->subs = eina_list_append(wd->subs, si); } - eina_stringshare_replace(&sub_d->p.text.text, text); - - _text_signal_emit(sd, sub_d, !!text); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); - - return EINA_TRUE; + eina_stringshare_replace(&si->p.text.text, text); + edje_object_part_text_escaped_set(wd->lay, part, text); + _request_sizing_eval(wd); } static const char * -_elm_layout_smart_text_get(const Evas_Object *obj, - const char *part) +_elm_layout_label_get(const Evas_Object *obj, const char *part) { - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!_elm_layout_part_aliasing_eval(sd, &part, EINA_TRUE)) - return EINA_FALSE; - - return edje_object_part_text_get(ELM_WIDGET_DATA(sd)->resize_obj, part); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!part) part = "elm.text"; + return edje_object_part_text_get(wd->lay, part); } -static Eina_Bool -_elm_layout_smart_content_set(Evas_Object *obj, - const char *part, - Evas_Object *content) +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - Elm_Layout_Sub_Object_Data *sub_d; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; const Eina_List *l; - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!_elm_layout_part_aliasing_eval(sd, &part, EINA_FALSE)) - return EINA_FALSE; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + if (!wd) return; + EINA_SAFETY_ON_NULL_RETURN(part); + EINA_LIST_FOREACH(wd->subs, l, si) { - if ((sub_d->type == SWALLOW)) + if ((si->type == SWALLOW) && (!strcmp(part, si->part))) { - if (!strcmp(part, sub_d->part)) - { - if (content == sub_d->obj) return EINA_TRUE; - evas_object_del(sub_d->obj); - break; - } - /* was previously swallowed at another part -- mimic - * edje_object_part_swallow()'s behavior, then */ - else if (content == sub_d->obj) - { - elm_widget_sub_object_del(obj, content); - break; - } + if (content == si->obj) return; + evas_object_del(si->obj); + break; } } - if (content) { - if (!edje_object_part_swallow - (ELM_WIDGET_DATA(sd)->resize_obj, part, content)) - { - ERR("could not swallow %p into part '%s'", content, part); - return EINA_FALSE; - } - - if (!elm_widget_sub_object_add(obj, content)) - { - ERR("could not add %p as sub object of %p", content, obj); - edje_object_part_unswallow - (ELM_WIDGET_DATA(sd)->resize_obj, content); - return EINA_FALSE; - } - - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = SWALLOW; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = content; - sd->subs = eina_list_append(sd->subs, sub_d); - - _icon_signal_emit(sd, sub_d, EINA_TRUE); + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, wd); + if (!edje_object_part_swallow(wd->lay, part, content)) + WRN("could not swallow %p into part '%s'", content, part); + si = ELM_NEW(Subinfo); + si->type = SWALLOW; + si->part = eina_stringshare_add(part); + si->obj = content; + wd->subs = eina_list_append(wd->subs, si); } - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); - - return EINA_TRUE; + _request_sizing_eval(wd); } static Evas_Object * -_elm_layout_smart_content_get(const Evas_Object *obj, - const char *part) +_content_get_hook(const Evas_Object *obj, const char *part) { + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; + Subinfo *si; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!_elm_layout_part_aliasing_eval(sd, &part, EINA_FALSE)) - return EINA_FALSE; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + EINA_LIST_FOREACH(wd->subs, l, si) { - if ((sub_d->type == SWALLOW) && !strcmp(part, sub_d->part)) - return sub_d->obj; + if ((si->type == SWALLOW) && !strcmp(part, si->part)) + return si->obj; } return NULL; } static Evas_Object * -_elm_layout_smart_content_unset(Evas_Object *obj, - const char *part) +_content_unset_hook(Evas_Object *obj, const char *part) { - Elm_Layout_Sub_Object_Data *sub_d; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; const Eina_List *l; - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!_elm_layout_part_aliasing_eval(sd, &part, EINA_FALSE)) - return EINA_FALSE; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + if (!wd) return NULL; + EINA_LIST_FOREACH(wd->subs, l, si) { - if ((sub_d->type == SWALLOW) && (!strcmp(part, sub_d->part))) + if ((si->type == SWALLOW) && (!strcmp(part, si->part))) { Evas_Object *content; - - if (!sub_d->obj) return NULL; - - content = sub_d->obj; /* sub_d will die in - * _elm_layout_smart_sub_object_del */ - - if (!elm_widget_sub_object_del(obj, content)) - { - ERR("could not remove sub object %p from %p", content, obj); - return NULL; - } - - edje_object_part_unswallow - (ELM_WIDGET_DATA(sd)->resize_obj, content); + if (!si->obj) return NULL; + content = si->obj; /* si will die in _sub_del due elm_widget_sub_object_del() */ + elm_widget_sub_object_del(obj, content); + evas_object_event_callback_del_full(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, wd); + edje_object_part_unswallow(wd->lay, content); return content; } } - return NULL; } -static Eina_Bool -_elm_layout_smart_box_append(Evas_Object *obj, - const char *part, - Evas_Object *child) +EAPI Evas_Object * +elm_layout_add(Evas_Object *parent) { - Elm_Layout_Sub_Object_Data *sub_d; + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - ELM_LAYOUT_DATA_GET(obj, sd); + ELM_SET_WIDTYPE(widtype, "layout"); + elm_widget_type_set(obj, "layout"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_changed_hook_set(obj, _changed_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_focus_next_hook_set(obj, _elm_layout_focus_next_hook); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); + elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); + elm_widget_text_set_hook_set(obj, _elm_layout_label_set); + elm_widget_text_get_hook_set(obj, _elm_layout_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->obj = obj; + wd->lay = edje_object_add(e); + elm_widget_resize_object_set(obj, wd->lay); + edje_object_signal_callback_add(wd->lay, "size,eval", "elm", + _signal_size_eval, wd); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _request_sizing_eval(wd); + return obj; +} - if (!edje_object_part_box_append - (ELM_WIDGET_DATA(sd)->resize_obj, part, child)) +EAPI Eina_Bool +elm_layout_file_set(Evas_Object *obj, const char *file, const char *group) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + Eina_Bool ret = edje_object_file_set(wd->lay, file, group); + if (ret) { - ERR("child %p could not be appended to box part '%s'", child, part); - return EINA_FALSE; + _parts_text_fix(wd); + _request_sizing_eval(wd); + _parts_cursors_apply(wd); } + else DBG("failed to set edje file '%s', group '%s': %s", + file, group, + edje_load_error_str(edje_object_load_error_get(wd->lay))); + return ret; +} - if (!elm_widget_sub_object_add(obj, child)) +EAPI Eina_Bool +elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style) +{ + 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_object_set(obj, wd->lay, clas, group, style); + wd->clas = clas; + wd->group = group; + wd->style = style; + if (ret) { - ERR("could not add %p as sub object of %p", child, obj); - edje_object_part_box_remove - (ELM_WIDGET_DATA(sd)->resize_obj, part, child); - return EINA_FALSE; + _parts_text_fix(wd); + _request_sizing_eval(wd); + _parts_cursors_apply(wd); } + return ret; +} - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = BOX_APPEND; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = child; - sd->subs = eina_list_append(sd->subs, sub_d); +EAPI Eina_Bool +elm_layout_box_append(Evas_Object *obj, const char *part, Evas_Object *child) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + if (!wd) return EINA_FALSE; - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + if (!edje_object_part_box_append(wd->lay, part, child)) + WRN("child %p could not be appended to box part '%s'", child, part); + elm_widget_sub_object_add(obj, child); + evas_object_event_callback_add + (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, wd); + + si = ELM_NEW(Subinfo); + si->type = BOX_APPEND; + si->part = eina_stringshare_add(part); + si->obj = child; + wd->subs = eina_list_append(wd->subs, si); + _request_sizing_eval(wd); return EINA_TRUE; } -static Eina_Bool -_elm_layout_smart_box_prepend(Evas_Object *obj, - const char *part, - Evas_Object *child) +EAPI Eina_Bool +elm_layout_box_prepend(Evas_Object *obj, const char *part, Evas_Object *child) { - Elm_Layout_Sub_Object_Data *sub_d; - - ELM_LAYOUT_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + if (!wd) return EINA_FALSE; - if (!edje_object_part_box_prepend - (ELM_WIDGET_DATA(sd)->resize_obj, part, child)) - { - ERR("child %p could not be prepended to box part '%s'", child, part); - return EINA_FALSE; - } - - if (!elm_widget_sub_object_add(obj, child)) - { - ERR("could not add %p as sub object of %p", child, obj); - edje_object_part_box_remove - (ELM_WIDGET_DATA(sd)->resize_obj, part, child); - return EINA_FALSE; - } - - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = BOX_PREPEND; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = child; - sd->subs = eina_list_prepend(sd->subs, sub_d); + if (!edje_object_part_box_prepend(wd->lay, part, child)) + WRN("child %p could not be prepended to box part '%s'", child, part); + elm_widget_sub_object_add(obj, child); + evas_object_event_callback_add + (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, wd); - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + si = ELM_NEW(Subinfo); + si->type = BOX_PREPEND; + si->part = eina_stringshare_add(part); + si->obj = child; + wd->subs = eina_list_prepend(wd->subs, si); + _request_sizing_eval(wd); return EINA_TRUE; } static void -_box_reference_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_box_reference_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Layout_Sub_Object_Data *sub_d = data; - sub_d->p.box.reference = NULL; + Subinfo *si = data; + si->p.box.reference = NULL; } -static Eina_Bool -_elm_layout_smart_box_insert_before(Evas_Object *obj, - const char *part, - Evas_Object *child, - const Evas_Object *reference) +EAPI Eina_Bool +elm_layout_box_insert_before(Evas_Object *obj, const char *part, Evas_Object *child, const Evas_Object *reference) { - Elm_Layout_Sub_Object_Data *sub_d; - - ELM_LAYOUT_DATA_GET(obj, sd); - - if (!edje_object_part_box_insert_before - (ELM_WIDGET_DATA(sd)->resize_obj, part, child, reference)) - { - ERR("child %p could not be inserted before %p inf box part '%s'", - child, reference, part); - return EINA_FALSE; - } + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + if (!wd) return EINA_FALSE; - if (!elm_widget_sub_object_add(obj, child)) - { - ERR("could not add %p as sub object of %p", child, obj); - edje_object_part_box_remove - (ELM_WIDGET_DATA(sd)->resize_obj, part, child); - return EINA_FALSE; - } + if (!edje_object_part_box_insert_before(wd->lay, part, child, reference)) + WRN("child %p could not be inserted before %p inf box part '%s'", + child, reference, part); - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = BOX_INSERT_BEFORE; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = child; - sub_d->p.box.reference = reference; - sd->subs = eina_list_append(sd->subs, sub_d); + si = ELM_NEW(Subinfo); + si->type = BOX_INSERT_BEFORE; + si->part = eina_stringshare_add(part); + si->obj = child; + si->p.box.reference = reference; + elm_widget_sub_object_add(obj, child); evas_object_event_callback_add - ((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, sub_d); + (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, wd); + evas_object_event_callback_add + ((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, si); - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + wd->subs = eina_list_append(wd->subs, si); + _request_sizing_eval(wd); return EINA_TRUE; } -static Eina_Bool -_elm_layout_smart_box_insert_at(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned int pos) +EAPI Eina_Bool +elm_layout_box_insert_at(Evas_Object *obj, const char *part, Evas_Object *child, unsigned int pos) { - Elm_Layout_Sub_Object_Data *sub_d; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + if (!wd) return EINA_FALSE; - ELM_LAYOUT_DATA_GET(obj, sd); + if (!edje_object_part_box_insert_at(wd->lay, part, child, pos)) + WRN("child %p could not be inserted at %u to box part '%s'", + child, pos, part); - if (!edje_object_part_box_insert_at - (ELM_WIDGET_DATA(sd)->resize_obj, part, child, pos)) - { - ERR("child %p could not be inserted at %u to box part '%s'", - child, pos, part); - return EINA_FALSE; - } - - if (!elm_widget_sub_object_add(obj, child)) - { - ERR("could not add %p as sub object of %p", child, obj); - edje_object_part_box_remove - (ELM_WIDGET_DATA(sd)->resize_obj, part, child); - return EINA_FALSE; - } - - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = BOX_INSERT_AT; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = child; - sub_d->p.box.pos = pos; - sd->subs = eina_list_append(sd->subs, sub_d); + elm_widget_sub_object_add(obj, child); + evas_object_event_callback_add + (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, wd); - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + si = ELM_NEW(Subinfo); + si->type = BOX_INSERT_AT; + si->part = eina_stringshare_add(part); + si->obj = child; + si->p.box.pos = pos; + wd->subs = eina_list_append(wd->subs, si); + _request_sizing_eval(wd); return EINA_TRUE; } static Evas_Object * -_sub_box_remove(Evas_Object *obj, - Elm_Layout_Smart_Data *sd, - Elm_Layout_Sub_Object_Data *sub_d) +_sub_box_remove(Widget_Data *wd, Subinfo *si) { - Evas_Object *child = sub_d->obj; /* sub_d will die in - * _elm_layout_smart_sub_object_del */ - - if (!elm_widget_sub_object_del(obj, child)) - { - ERR("could not remove sub object %p from %p", child, obj); - return NULL; - } + Evas_Object *child; - if (sub_d->type == BOX_INSERT_BEFORE) + if (si->type == BOX_INSERT_BEFORE) evas_object_event_callback_del_full - ((Evas_Object *)sub_d->p.box.reference, - EVAS_CALLBACK_DEL, _box_reference_del, sub_d); + ((Evas_Object *)si->p.box.reference, + EVAS_CALLBACK_DEL, _box_reference_del, si); + + child = si->obj; /* si will die in _sub_del due elm_widget_sub_object_del() */ + edje_object_part_box_remove(wd->lay, si->part, child); + elm_widget_sub_object_del(wd->obj, child); + return child; +} - edje_object_part_box_remove - (ELM_WIDGET_DATA(sd)->resize_obj, sub_d->part, child); +static Evas_Object * +_sub_table_remove(Widget_Data *wd, Subinfo *si) +{ + Evas_Object *child; + child = si->obj; /* si will die in _sub_del due elm_widget_sub_object_del() */ + edje_object_part_table_unpack(wd->lay, si->part, child); + elm_widget_sub_object_del(wd->obj, child); return child; } static Eina_Bool -_sub_box_is(const Elm_Layout_Sub_Object_Data *sub_d) +_sub_box_is(const Subinfo *si) { - switch (sub_d->type) + switch (si->type) { case BOX_APPEND: case BOX_PREPEND: case BOX_INSERT_BEFORE: case BOX_INSERT_AT: - return EINA_TRUE; - + return EINA_TRUE; default: - return EINA_FALSE; + return EINA_FALSE; } } -static Evas_Object * -_elm_layout_smart_box_remove(Evas_Object *obj, - const char *part, - Evas_Object *child) +EAPI Evas_Object * +elm_layout_box_remove(Evas_Object *obj, const char *part, Evas_Object *child) { - EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL); - - ELM_LAYOUT_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; + Subinfo *si; - EINA_LIST_FOREACH (sd->subs, l, sub_d) + if (!wd) return NULL; + + EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL); + EINA_LIST_FOREACH(wd->subs, l, si) { - if (!_sub_box_is(sub_d)) continue; - if ((sub_d->obj == child) && (!strcmp(sub_d->part, part))) - return _sub_box_remove(obj, sd, sub_d); + if (!_sub_box_is(si)) continue; + if ((si->obj == child) && (!strcmp(si->part, part))) + return _sub_box_remove(wd, si); } - return NULL; } -static Eina_Bool -_elm_layout_smart_box_remove_all(Evas_Object *obj, - const char *part, - Eina_Bool clear) +EAPI Eina_Bool +elm_layout_box_remove_all(Evas_Object *obj, const char *part, Eina_Bool clear) { - EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); - - ELM_LAYOUT_DATA_GET(obj, sd); - - Elm_Layout_Sub_Object_Data *sub_d; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; Eina_List *lst; - lst = eina_list_clone(sd->subs); - EINA_LIST_FREE (lst, sub_d) + if (!wd) return EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); + + lst = eina_list_clone(wd->subs); + EINA_LIST_FREE(lst, si) { - if (!_sub_box_is(sub_d)) continue; - if (!strcmp(sub_d->part, part)) + if (!_sub_box_is(si)) continue; + if (!strcmp(si->part, part)) { - /* original item's deletion handled at sub-obj-del */ - Evas_Object *child = _sub_box_remove(obj, sd, sub_d); + Evas_Object *child = _sub_box_remove(wd, si); if ((clear) && (child)) evas_object_del(child); } } - - /* eventually something may not be added with elm_layout, delete them - * as well */ - edje_object_part_box_remove_all - (ELM_WIDGET_DATA(sd)->resize_obj, part, clear); + /* eventually something may not be added with layout, del them as well */ + edje_object_part_box_remove_all(wd->lay, part, clear); return EINA_TRUE; } -static Eina_Bool -_elm_layout_smart_table_pack(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned short col, - unsigned short row, - unsigned short colspan, - unsigned short rowspan) +EAPI Eina_Bool +elm_layout_table_pack(Evas_Object *obj, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) { - Elm_Layout_Sub_Object_Data *sub_d; - - ELM_LAYOUT_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; + if (!wd) return EINA_FALSE; if (!edje_object_part_table_pack - (ELM_WIDGET_DATA(sd)->resize_obj, part, child, col, - row, colspan, rowspan)) - { - ERR("child %p could not be packed into box part '%s' col=%uh, row=%hu," - " colspan=%hu, rowspan=%hu", child, part, col, row, colspan, - rowspan); - return EINA_FALSE; - } + (wd->lay, part, child, col, row, colspan, rowspan)) + WRN("child %p could not be packed into box part '%s' col=%uh, row=%hu, " + "colspan=%hu, rowspan=%hu", child, part, col, row, colspan, rowspan); - if (!elm_widget_sub_object_add(obj, child)) - { - ERR("could not add %p as sub object of %p", child, obj); - edje_object_part_table_unpack - (ELM_WIDGET_DATA(sd)->resize_obj, part, child); - return EINA_FALSE; - } - - sub_d = ELM_NEW(Elm_Layout_Sub_Object_Data); - sub_d->type = TABLE_PACK; - sub_d->part = eina_stringshare_add(part); - sub_d->obj = child; - sub_d->p.table.col = col; - sub_d->p.table.row = row; - sub_d->p.table.colspan = colspan; - sub_d->p.table.rowspan = rowspan; - sd->subs = eina_list_append(sd->subs, sub_d); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + elm_widget_sub_object_add(obj, child); + evas_object_event_callback_add + (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, wd); + + si = ELM_NEW(Subinfo); + si->type = TABLE_PACK; + si->part = eina_stringshare_add(part); + si->obj = child; + si->p.table.col = col; + si->p.table.row = row; + si->p.table.colspan = colspan; + si->p.table.rowspan = rowspan; + wd->subs = eina_list_append(wd->subs, si); + _request_sizing_eval(wd); return EINA_TRUE; } -static Evas_Object * -_sub_table_remove(Evas_Object *obj, - Elm_Layout_Smart_Data *sd, - Elm_Layout_Sub_Object_Data *sub_d) +EAPI Evas_Object * +elm_layout_table_unpack(Evas_Object *obj, const char *part, Evas_Object *child) { - Evas_Object *child; - - child = sub_d->obj; /* sub_d will die in _elm_layout_smart_sub_object_del */ - - if (!elm_widget_sub_object_del(obj, child)) - { - ERR("could not remove sub object %p from %p", child, obj); - return NULL; - } + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + const Eina_List *l; + Subinfo *si; - edje_object_part_table_unpack - (ELM_WIDGET_DATA(sd)->resize_obj, sub_d->part, child); + if (!wd) return NULL; - return child; -} - -static Evas_Object * -_elm_layout_smart_table_unpack(Evas_Object *obj, - const char *part, - Evas_Object *child) -{ EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL); - - ELM_LAYOUT_DATA_GET(obj, sd); - - const Eina_List *l; - Elm_Layout_Sub_Object_Data *sub_d; - - EINA_LIST_FOREACH (sd->subs, l, sub_d) + EINA_LIST_FOREACH(wd->subs, l, si) { - if (sub_d->type != TABLE_PACK) continue; - if ((sub_d->obj == child) && (!strcmp(sub_d->part, part))) - return _sub_table_remove(obj, sd, sub_d); + if (si->type != TABLE_PACK) continue; + if ((si->obj == child) && (!strcmp(si->part, part))) + return _sub_table_remove(wd, si); } - return NULL; } -static Eina_Bool -_elm_layout_smart_table_clear(Evas_Object *obj, - const char *part, - Eina_Bool clear) +EAPI Eina_Bool +elm_layout_table_clear(Evas_Object *obj, const char *part, Eina_Bool clear) { - EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); - ELM_LAYOUT_DATA_GET(obj, sd); - - Elm_Layout_Sub_Object_Data *sub_d; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + Subinfo *si; Eina_List *lst; - lst = eina_list_clone(sd->subs); - EINA_LIST_FREE (lst, sub_d) + if (!wd) return EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); + + lst = eina_list_clone(wd->subs); + EINA_LIST_FREE(lst, si) { - if (sub_d->type != TABLE_PACK) continue; - if (!strcmp(sub_d->part, part)) + if (si->type != TABLE_PACK) continue; + if (!strcmp(si->part, part)) { - /* original item's deletion handled at sub-obj-del */ - Evas_Object *child = _sub_table_remove(obj, sd, sub_d); + Evas_Object *child = _sub_table_remove(wd, si); if ((clear) && (child)) evas_object_del(child); } } - - /* eventually something may not be added with elm_layout, delete them - * as well */ - edje_object_part_table_clear(ELM_WIDGET_DATA(sd)->resize_obj, part, clear); + /* eventually something may not be added with layout, del them as well */ + edje_object_part_table_clear(wd->lay, part, clear); return EINA_TRUE; } -static void -_on_size_evaluate_signal(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) -{ - ELM_LAYOUT_DATA_GET(data, sd); - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(data); -} - -static void -_elm_layout_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Layout_Smart_Data); - - /* has to be there *before* parent's smart_add() */ - ELM_WIDGET_DATA(priv)->resize_obj = - edje_object_add(evas_object_evas_get(obj)); - - ELM_WIDGET_CLASS(_elm_layout_parent_sc)->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "size,eval", "elm", - _on_size_evaluate_signal, obj); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(priv)->api)->sizing_eval(obj); -} - -static void -_elm_layout_smart_del(Evas_Object *obj) -{ - Elm_Layout_Sub_Object_Data *sub_d; - Elm_Layout_Sub_Object_Cursor *pc; - Layout_Signal_Data *lsd; - Evas_Object *child; - Eina_List *l; - - ELM_LAYOUT_DATA_GET(obj, sd); - - EINA_LIST_FREE (sd->subs, sub_d) - { - eina_stringshare_del(sub_d->part); - - if (sub_d->type == TEXT) - eina_stringshare_del(sub_d->p.text.text); - - free(sub_d); - } - - EINA_LIST_FREE (sd->parts_cursors, pc) - _part_cursor_free(pc); - - EINA_LIST_FREE (sd->edje_signals, lsd) - { - eina_stringshare_del(lsd->emission); - eina_stringshare_del(lsd->source); - free(lsd); - } - - eina_stringshare_del(sd->klass); - eina_stringshare_del(sd->group); - - /* let's make our Edje object the *last* to be processed, since it - * may (smart) parent other sub objects here */ - EINA_LIST_FOREACH (ELM_WIDGET_DATA(sd)->subobjs, l, child) - { - if (child == ELM_WIDGET_DATA(sd)->resize_obj) - { - ELM_WIDGET_DATA(sd)->subobjs = - eina_list_demote_list(ELM_WIDGET_DATA(sd)->subobjs, l); - break; - } - } - - ELM_WIDGET_CLASS(_elm_layout_parent_sc)->base.del(obj); -} - -/* rewrite or extend this one on your derived class as to suit your - * needs */ -static void -_elm_layout_smart_calculate(Evas_Object *obj) -{ - ELM_LAYOUT_DATA_GET(obj, sd); - - if (sd->needs_size_calc) - { - _sizing_eval(obj, sd); - sd->needs_size_calc = EINA_FALSE; - } -} - -static void -_elm_layout_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_layout_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_layout_smart_del; - ELM_WIDGET_CLASS(sc)->base.calculate = _elm_layout_smart_calculate; - - ELM_WIDGET_CLASS(sc)->theme = _elm_layout_smart_theme; - ELM_WIDGET_CLASS(sc)->disable = _elm_layout_smart_disable; - ELM_WIDGET_CLASS(sc)->focus_next = _elm_layout_smart_focus_next; - ELM_WIDGET_CLASS(sc)->on_focus = _elm_layout_smart_on_focus; - - ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_layout_smart_sub_object_add; - ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_layout_smart_sub_object_del; - - ELM_CONTAINER_CLASS(sc)->content_set = _elm_layout_smart_content_set; - ELM_CONTAINER_CLASS(sc)->content_get = _elm_layout_smart_content_get; - ELM_CONTAINER_CLASS(sc)->content_unset = _elm_layout_smart_content_unset; - - sc->sizing_eval = _elm_layout_smart_sizing_eval; - sc->signal = _elm_layout_smart_signal; - sc->callback_add = _elm_layout_smart_callback_add; - sc->callback_del = _elm_layout_smart_callback_del; - sc->text_set = _elm_layout_smart_text_set; - sc->text_get = _elm_layout_smart_text_get; - sc->box_append = _elm_layout_smart_box_append; - sc->box_prepend = _elm_layout_smart_box_prepend; - sc->box_insert_before = _elm_layout_smart_box_insert_before; - sc->box_insert_at = _elm_layout_smart_box_insert_at; - sc->box_remove = _elm_layout_smart_box_remove; - sc->box_remove_all = _elm_layout_smart_box_remove_all; - sc->table_pack = _elm_layout_smart_table_pack; - sc->table_unpack = _elm_layout_smart_table_unpack; - sc->table_clear = _elm_layout_smart_table_clear; -} - -static Elm_Layout_Sub_Object_Cursor * -_parts_cursors_find(Elm_Layout_Smart_Data *sd, - const char *part) -{ - const Eina_List *l; - Elm_Layout_Sub_Object_Cursor *pc; - - EINA_LIST_FOREACH (sd->parts_cursors, l, pc) - { - if (!strcmp(pc->part, part)) - return pc; - } - - return NULL; -} - -/* The public functions down here are meant to operate on whichever - * widget inheriting from elm_layout */ - -EAPI Eina_Bool -elm_layout_file_set(Evas_Object *obj, - const char *file, - const char *group) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - Eina_Bool ret = - edje_object_file_set(ELM_WIDGET_DATA(sd)->resize_obj, file, group); - - if (ret) _visuals_refresh(obj, sd); - else - ERR("failed to set edje file '%s', group '%s': %s", - file, group, - edje_load_error_str - (edje_object_load_error_get(ELM_WIDGET_DATA(sd)->resize_obj))); - - return ret; -} - -EAPI Eina_Bool -elm_layout_theme_set(Evas_Object *obj, - const char *klass, - const char *group, - const char *style) -{ - Eina_Bool ret; - - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - eina_stringshare_replace(&(sd->klass), klass); - eina_stringshare_replace(&(sd->group), group); - eina_stringshare_replace(&(ELM_WIDGET_DATA(sd)->style), style); - - /* not issuing smart theme directly here, because one may want to - use this function inside a smart theme routine of its own */ - ret = elm_widget_theme_object_set - (obj, ELM_WIDGET_DATA(sd)->resize_obj, sd->klass, sd->group, - elm_widget_style_get(obj)); - evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL); - - return ret; -} - -EAPI void -elm_layout_signal_emit(Evas_Object *obj, - const char *emission, - const char *source) -{ - ELM_LAYOUT_CHECK(obj); - ELM_LAYOUT_DATA_GET_OR_RETURN(obj, sd); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->signal(obj, emission, source); -} - -EAPI void -elm_layout_signal_callback_add(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func, - void *data) -{ - ELM_LAYOUT_CHECK(obj); - ELM_LAYOUT_DATA_GET_OR_RETURN(obj, sd); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->callback_add - (obj, emission, source, func, data); -} - -EAPI void * -elm_layout_signal_callback_del(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->callback_del - (obj, emission, source, func); -} - -EAPI Eina_Bool -elm_layout_content_set(Evas_Object *obj, - const char *swallow, - Evas_Object *content) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_CONTAINER_CLASS(ELM_WIDGET_DATA(sd)->api)->content_set - (obj, swallow, content); -} - -EAPI Evas_Object * -elm_layout_content_get(const Evas_Object *obj, - const char *swallow) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_CONTAINER_CLASS(ELM_WIDGET_DATA(sd)->api)->content_get - (obj, swallow); -} - -EAPI Evas_Object * -elm_layout_content_unset(Evas_Object *obj, - const char *swallow) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_CONTAINER_CLASS(ELM_WIDGET_DATA(sd)->api)->content_unset - (obj, swallow); -} - -EAPI Eina_Bool -elm_layout_text_set(Evas_Object *obj, - const char *part, - const char *text) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->text_set(obj, part, text); -} - -EAPI const char * -elm_layout_text_get(const Evas_Object *obj, - const char *part) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->text_get(obj, part); -} - -EAPI Eina_Bool -elm_layout_box_append(Evas_Object *obj, - const char *part, - Evas_Object *child) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_append - (obj, part, child); -} - -EAPI Eina_Bool -elm_layout_box_prepend(Evas_Object *obj, - const char *part, - Evas_Object *child) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_prepend - (obj, part, child); -} - -EAPI Eina_Bool -elm_layout_box_insert_before(Evas_Object *obj, - const char *part, - Evas_Object *child, - const Evas_Object *reference) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_insert_before - (obj, part, child, reference); -} - -EAPI Eina_Bool -elm_layout_box_insert_at(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned int pos) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_insert_at - (obj, part, child, pos); -} - -EAPI Evas_Object * -elm_layout_box_remove(Evas_Object *obj, - const char *part, - Evas_Object *child) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_remove - (obj, part, child); -} - -EAPI Eina_Bool -elm_layout_box_remove_all(Evas_Object *obj, - const char *part, - Eina_Bool clear) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->box_remove_all - (obj, part, clear); -} - -EAPI Eina_Bool -elm_layout_table_pack(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned short col, - unsigned short row, - unsigned short colspan, - unsigned short rowspan) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->table_pack - (obj, part, child, col, row, colspan, rowspan); -} - -EAPI Evas_Object * -elm_layout_table_unpack(Evas_Object *obj, - const char *part, - Evas_Object *child) -{ - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->table_unpack - (obj, part, child); -} - -EAPI Eina_Bool -elm_layout_table_clear(Evas_Object *obj, - const char *part, - Eina_Bool clear) -{ - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->table_clear - (obj, part, clear); -} - EAPI Evas_Object * elm_layout_edje_get(const Evas_Object *obj) { - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_WIDGET_DATA(sd)->resize_obj; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->lay; } EAPI const char * -elm_layout_data_get(const Evas_Object *obj, - const char *key) +elm_layout_data_get(const Evas_Object *obj, const char *key) { - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj, key); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + return edje_object_data_get(wd->lay, key); } EAPI void elm_layout_sizing_eval(Evas_Object *obj) { - ELM_LAYOUT_CHECK(obj); - ELM_LAYOUT_DATA_GET(obj, sd); - - ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->sizing_eval(obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN(wd); + _request_sizing_eval(wd); } EAPI Eina_Bool -elm_layout_part_cursor_set(Evas_Object *obj, - const char *part_name, - const char *cursor) +elm_layout_part_cursor_set(Evas_Object *obj, const char *part_name, const char *cursor) { - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE); - + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE); Evas_Object *part_obj; - Elm_Layout_Sub_Object_Cursor *pc; + Part_Cursor *pc; - part_obj = (Evas_Object *)edje_object_part_object_get - (ELM_WIDGET_DATA(sd)->resize_obj, part_name); + part_obj = (Evas_Object *)edje_object_part_object_get(wd->lay, part_name); if (!part_obj) { const char *group, *file; - - edje_object_file_get(ELM_WIDGET_DATA(sd)->resize_obj, &file, &group); - ERR("no part '%s' in group '%s' of file '%s'. Cannot set cursor '%s'", + edje_object_file_get(wd->lay, &file, &group); + WRN("no part '%s' in group '%s' of file '%s'. Cannot set cursor '%s'", part_name, group, file, cursor); return EINA_FALSE; } if (evas_object_pass_events_get(part_obj)) { const char *group, *file; - - edje_object_file_get(ELM_WIDGET_DATA(sd)->resize_obj, &file, &group); - ERR("part '%s' in group '%s' of file '%s' has mouse_events: 0. " + edje_object_file_get(wd->lay, &file, &group); + WRN("part '%s' in group '%s' of file '%s' has mouse_events: 0. " "Cannot set cursor '%s'", part_name, group, file, cursor); return EINA_FALSE; } - pc = _parts_cursors_find(sd, part_name); + pc = _parts_cursors_find(wd, part_name); if (pc) eina_stringshare_replace(&pc->cursor, cursor); else { @@ -1605,48 +863,44 @@ elm_layout_part_cursor_set(Evas_Object *obj, pc->part = eina_stringshare_add(part_name); pc->cursor = eina_stringshare_add(cursor); pc->style = eina_stringshare_add("default"); - sd->parts_cursors = eina_list_append(sd->parts_cursors, pc); + wd->parts_cursors = eina_list_append(wd->parts_cursors, pc); } pc->obj = part_obj; elm_object_sub_cursor_set(part_obj, obj, pc->cursor); - return EINA_TRUE; } EAPI const char * -elm_layout_part_cursor_get(const Evas_Object *obj, - const char *part_name) +elm_layout_part_cursor_get(const Evas_Object *obj, const char *part_name) { - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, NULL); - - Elm_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + Part_Cursor *pc = _parts_cursors_find(wd, part_name); EINA_SAFETY_ON_NULL_RETURN_VAL(pc, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, NULL); - return elm_object_cursor_get(pc->obj); } EAPI Eina_Bool -elm_layout_part_cursor_unset(Evas_Object *obj, - const char *part_name) +elm_layout_part_cursor_unset(Evas_Object *obj, const char *part_name) { - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE); - + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE); Eina_List *l; - Elm_Layout_Sub_Object_Cursor *pc; + Part_Cursor *pc; - EINA_LIST_FOREACH (sd->parts_cursors, l, pc) + EINA_LIST_FOREACH(wd->parts_cursors, l, pc) { if (!strcmp(part_name, pc->part)) { if (pc->obj) elm_object_cursor_unset(pc->obj); _part_cursor_free(pc); - sd->parts_cursors = eina_list_remove_list(sd->parts_cursors, l); + wd->parts_cursors = eina_list_remove_list(wd->parts_cursors, l); return EINA_TRUE; } } @@ -1655,106 +909,59 @@ elm_layout_part_cursor_unset(Evas_Object *obj, } EAPI Eina_Bool -elm_layout_part_cursor_style_set(Evas_Object *obj, - const char *part_name, - const char *style) +elm_layout_part_cursor_style_set(Evas_Object *obj, const char *part_name, const char *style) { - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE); - - Elm_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE); + Part_Cursor *pc = _parts_cursors_find(wd, part_name); EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE); eina_stringshare_replace(&pc->style, style); elm_object_cursor_style_set(pc->obj, pc->style); - return EINA_TRUE; } EAPI const char * -elm_layout_part_cursor_style_get(const Evas_Object *obj, - const char *part_name) +elm_layout_part_cursor_style_get(const Evas_Object *obj, const char *part_name) { - ELM_LAYOUT_CHECK(obj) NULL; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, NULL); - - Elm_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + Part_Cursor *pc = _parts_cursors_find(wd, part_name); EINA_SAFETY_ON_NULL_RETURN_VAL(pc, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, NULL); - return elm_object_cursor_style_get(pc->obj); } EAPI Eina_Bool -elm_layout_part_cursor_engine_only_set(Evas_Object *obj, - const char *part_name, - Eina_Bool engine_only) +elm_layout_part_cursor_engine_only_set(Evas_Object *obj, const char *part_name, Eina_Bool engine_only) { - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE); - - Elm_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE); + Part_Cursor *pc = _parts_cursors_find(wd, part_name); EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE); pc->engine_only = !!engine_only; elm_object_cursor_theme_search_enabled_set(pc->obj, pc->engine_only); - return EINA_TRUE; } EAPI Eina_Bool -elm_layout_part_cursor_engine_only_get(const Evas_Object *obj, - const char *part_name) +elm_layout_part_cursor_engine_only_get(const Evas_Object *obj, const char *part_name) { - ELM_LAYOUT_CHECK(obj) EINA_FALSE; - ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE); - - Elm_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name); + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE); + Part_Cursor *pc = _parts_cursors_find(wd, part_name); EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE); - return elm_object_cursor_theme_search_enabled_get(pc->obj); } - -EVAS_SMART_SUBCLASS_NEW - (LAYOUT_SMART_NAME, _elm_layout_widget, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); - -static const Elm_Layout_Part_Alias_Description _text_aliases[] = -{ - {"default", "elm.text"}, - {NULL, NULL} -}; - -/* the layout widget (not the base layout) has this extra bit */ -static void -_elm_layout_widget_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - sc->text_aliases = _text_aliases; -} - -/* And now the basic layout widget itself */ -EAPI Evas_Object * -elm_layout_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_layout_widget_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - return obj; -} diff --git a/src/lib/elm_layout.h b/src/lib/elm_layout.h index 3cb2c5e20..84ecbff90 100644 --- a/src/lib/elm_layout.h +++ b/src/lib/elm_layout.h @@ -188,71 +188,11 @@ EAPI Eina_Bool elm_layout_file_set(Evas_Object *obj, const ch * * @return (1 = success, 0 = error) * - * Note that @a style will be the new style of @a obj too, as in an - * elm_object_style_set() call. - * * @ingroup Layout */ EAPI Eina_Bool elm_layout_theme_set(Evas_Object *obj, const char *clas, const char *group, const char *style); /** - * Send a (Edje) signal to a given layout widget's underlying Edje - * object. - * - * @param obj The layout object handle - * @param emission The signal's name string - * @param source The signal's source string - * - * This function sends a signal to the underlying Edje object of @a - * obj. An Edje program on that Edje object's definition can respond - * to a signal by specifying matching 'signal' and 'source' fields. - * - * @ingroup Layout - */ -EAPI void elm_layout_signal_emit(Evas_Object *obj, const char *emission, const char *source); - -/** - * Add a callback for a (Edje) signal emitted by a layout widget's - * underlying Edje object. - * - * @param obj The layout object handle - * @param emission The signal's name string - * @param source The signal's source string - * @param func The callback function to be executed when the signal is - * emitted. - * @param data A pointer to data to pass in to the callback function. - * - * This function connects a callback function to a signal emitted by - * the underlying Edje object of @a obj. Globs are accepted in either - * the emission or source strings (see @c - * edje_object_signal_callback_add()). - * - * @ingroup Layout - */ -EAPI void elm_layout_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data); - -/** - * Remove a signal-triggered callback from a given layout widget. - * - * @param obj The layout object handle - * @param emission The signal's name string - * @param source The signal's source string - * @param func The callback function being executed when the signal - * was emitted. - * @return The data pointer of the signal callback (passed on - * elm_layout_signal_callback_add()) or @c NULL, on errors. - * - * This function removes the @b last callback attached to a signal - * emitted by the undelying Edje object of @a obj, with parameters @a - * emission, @a source and @c func matching exactly those passed to a - * previous call to elm_object_signal_callback_add(). The data pointer - * that was passed to this call will be returned. - * - * @ingroup Layout - */ -EAPI void *elm_layout_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func); - -/** * Append child to layout box part. * * @param obj the layout object @@ -638,71 +578,6 @@ EAPI Eina_Bool elm_layout_part_cursor_engine_only_set(Evas_Ob EAPI Eina_Bool elm_layout_part_cursor_engine_only_get(const Evas_Object *obj, const char *part_name); /** - * Set the layout content. - * - * @param obj The layout object - * @param swallow The swallow part name in the edje file - * @param content The child that will be added in this layout object - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise - * - * Once the content object is set, a previously set one will be deleted. - * If you want to keep that old content object, use the - * elm_object_part_content_unset() function. - * - * @note In an Edje theme, the part used as a content container is called @c - * SWALLOW. This is why the parameter name is called @p swallow, but it is - * expected to be a part name just like the second parameter of - * elm_layout_box_append(). - * - * @see elm_layout_box_append() - * @see elm_object_part_content_get() - * @see elm_object_part_content_unset() - * @see @ref secBox - */ -EAPI Eina_Bool elm_layout_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content); - -/** - * Get the child object in the given content part. - * - * @param obj The layout object - * @param swallow The SWALLOW part to get its content - * - * @return The swallowed object or NULL if none or an error occurred - */ -EAPI Evas_Object *elm_layout_content_get(const Evas_Object *obj, const char *swallow); - -/** - * Unset the layout content. - * - * @param obj The layout object - * @param swallow The swallow part name in the edje file - * @return The content that was being used - * - * Unparent and return the content object which was set for this part. - */ -EAPI Evas_Object *elm_layout_content_unset(Evas_Object *obj, const char *swallow); - -/** - * Set the text of the given part - * - * @param obj The layout object - * @param part The TEXT part where to set the text - * @param text The text to set - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise - */ -EAPI Eina_Bool elm_layout_text_set(Evas_Object *obj, const char *part, const char *text); - -/** - * Get the text set in the given part - * - * @param obj The layout object - * @param part The TEXT part to retrieve the text off - * - * @return The text set in @p part - */ -EAPI const char *elm_layout_text_get(const Evas_Object *obj, const char *part); - -/** * @def elm_layout_icon_set * Convenience macro to set the icon object in a layout that follows the * Elementary naming convention for its parts. @@ -754,6 +629,10 @@ EAPI const char *elm_layout_text_get(const Evas_Object *obj, co #define elm_layout_end_get(_ly) \ elm_object_part_content_get((_ly), "elm.swallow.end") +/* smart callbacks called: + * "theme,changed" - when elm theme is changed. + */ + /** * @} */ diff --git a/src/lib/elm_mapbuf.c b/src/lib/elm_mapbuf.c index 866b11a0f..4608872fa 100644 --- a/src/lib/elm_mapbuf.c +++ b/src/lib/elm_mapbuf.c @@ -1,371 +1,305 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_container.h" -static const char MAPBUF_SMART_NAME[] = "elm_mapbuf"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Mapbuf_Smart_Data Elm_Mapbuf_Smart_Data; - -struct _Elm_Mapbuf_Smart_Data +struct _Widget_Data { - Elm_Widget_Smart_Data base; + Evas_Object *content, *clip; + Eina_Bool enabled : 1; + Eina_Bool alpha : 1; + Eina_Bool smooth : 1; +}; - Evas_Object *content; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); - Eina_Bool enabled : 1; - Eina_Bool smooth : 1; - Eina_Bool alpha : 1; -}; +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} -#define ELM_MAPBUF_DATA_GET(o, sd) \ - Elm_Mapbuf_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_MAPBUF_DATA_GET_OR_RETURN(o, ptr) \ - ELM_MAPBUF_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_MAPBUF_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_MAPBUF_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_MAPBUF_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), MAPBUF_SMART_NAME, __func__)) \ - return - -EVAS_SMART_SUBCLASS_NEW - (MAPBUF_SMART_NAME, _elm_mapbuf, Elm_Container_Smart_Class, - Elm_Container_Smart_Class, elm_container_smart_class_get, NULL); +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _sizing_eval(obj); +} static void _sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; Evas_Coord maxw = -1, maxh = -1; - - ELM_MAPBUF_DATA_GET(obj, sd); - if (sd->content) + if (!wd) return; + if (wd->content) { - evas_object_size_hint_min_get(sd->content, &minw, &minh); - evas_object_size_hint_max_get(sd->content, &maxw, &maxh); + evas_object_size_hint_min_get(wd->content, &minw, &minh); + evas_object_size_hint_max_get(wd->content, &maxw, &maxh); } evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, maxw, maxh); } -static Eina_Bool -_elm_mapbuf_smart_theme(Evas_Object *obj) -{ - if (!ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->theme(obj)) return EINA_FALSE; - - _sizing_eval(obj); - - return EINA_TRUE; -} - static void -_changed_size_hints_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; _sizing_eval(data); } -static Eina_Bool -_elm_mapbuf_smart_sub_object_del(Evas_Object *obj, - Evas_Object *sobj) +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { - ELM_MAPBUF_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->sub_object_del(obj, sobj)) - return EINA_FALSE; - - if (sobj == sd->content) + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->content) { - evas_object_data_del(sobj, "_elm_leaveme"); - evas_object_smart_member_del(sobj); - evas_object_clip_unset(sobj); - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb, - obj); - sd->content = NULL; + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->content = NULL; _sizing_eval(obj); } - - return EINA_TRUE; } static void _mapbuf(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord x, y, w, h; - - ELM_MAPBUF_DATA_GET(obj, sd); - - evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, &h); - if (sd->enabled) + if (!wd) return; + evas_object_geometry_get(wd->clip, &x, &y, &w, &h); + if (wd->enabled) { Evas_Map *m; m = evas_map_new(4); evas_map_util_points_populate_from_geometry(m, x, y, w, h, 0); - evas_map_smooth_set(m, sd->smooth); - evas_map_alpha_set(m, sd->alpha); - evas_object_map_set(sd->content, m); - evas_object_map_enable_set(sd->content, EINA_TRUE); + evas_map_smooth_set(m, wd->smooth); + evas_map_alpha_set(m, wd->alpha); + evas_object_map_set(wd->content, m); + evas_object_map_enable_set(wd->content, EINA_TRUE); evas_map_free(m); } else { - evas_object_map_set(sd->content, NULL); - evas_object_map_enable_set(sd->content, EINA_FALSE); - evas_object_move(sd->content, x, y); - evas_object_resize(sd->content, w, h); + evas_object_map_set(wd->content, NULL); + evas_object_map_enable_set(wd->content, EINA_FALSE); + evas_object_move(wd->content, x, y); + evas_object_resize(wd->content, w, h); } } static void _configure(Evas_Object *obj) { - ELM_MAPBUF_DATA_GET(obj, sd); - - if (sd->content) + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content) { Evas_Coord x, y, w, h, x2, y2; - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, &x, &y, &w, &h); - evas_object_geometry_get(sd->content, &x2, &y2, NULL, NULL); + evas_object_geometry_get(wd->clip, &x, &y, &w, &h); + evas_object_geometry_get(wd->content, &x2, &y2, NULL, NULL); if ((x != x2) || (y != y2)) { - if (!sd->enabled) - evas_object_move(sd->content, x, y); + if (!wd->enabled) + evas_object_move(wd->content, x, y); else { + Evas *e = evas_object_evas_get(obj); evas_smart_objects_calculate(e); evas_nochange_push(e); - evas_object_move(sd->content, x, y); + evas_object_move(wd->content, x, y); evas_smart_objects_calculate(e); evas_nochange_pop(e); } } - evas_object_resize(sd->content, w, h); + evas_object_resize(wd->content, w, h); _mapbuf(obj); } } static void -_elm_mapbuf_smart_move(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.move(obj, x, y); - - _configure(obj); + _configure(data); } static void -_elm_mapbuf_smart_resize(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.resize(obj, x, y); - - _configure(obj); + _configure(data); } -static Eina_Bool -_elm_mapbuf_smart_content_set(Evas_Object *obj, - const char *part, - Evas_Object *content) +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - ELM_MAPBUF_DATA_GET(obj, sd); - - if (part && strcmp(part, "default")) return EINA_FALSE; - if (sd->content == content) return EINA_TRUE; - - if (sd->content) evas_object_del(sd->content); - sd->content = content; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + if (part && strcmp(part, "default")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; if (content) { evas_object_data_set(content, "_elm_leaveme", (void *)1); elm_widget_sub_object_add(obj, content); evas_object_smart_member_add(content, obj); - evas_object_clip_set(content, ELM_WIDGET_DATA(sd)->resize_obj); - evas_object_color_set - (ELM_WIDGET_DATA(sd)->resize_obj, 255, 255, 255, 255); - evas_object_event_callback_add - (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints_cb, obj); + evas_object_clip_set(content, wd->clip); + evas_object_color_set(wd->clip, 255, 255, 255, 255); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); } else - evas_object_color_set(ELM_WIDGET_DATA(sd)->resize_obj, 0, 0, 0, 0); - + evas_object_color_set(wd->clip, 0, 0, 0, 0); _sizing_eval(obj); _configure(obj); - - return EINA_TRUE; } static Evas_Object * -_elm_mapbuf_smart_content_get(const Evas_Object *obj, - const char *part) +_content_get_hook(const Evas_Object *obj, const char *part) { - ELM_MAPBUF_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; if (part && strcmp(part, "default")) return NULL; - return sd->content; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->content; } static Evas_Object * -_elm_mapbuf_smart_content_unset(Evas_Object *obj, - const char *part) +_content_unset_hook(Evas_Object *obj, const char *part) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; Evas_Object *content; - ELM_MAPBUF_DATA_GET(obj, sd); - if (part && strcmp(part, "default")) return NULL; - if (!sd->content) return NULL; - - content = sd->content; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->content) return NULL; + content = wd->content; elm_widget_sub_object_del(obj, content); evas_object_smart_member_del(content); + evas_object_color_set(wd->clip, 0, 0, 0, 0); evas_object_data_del(content, "_elm_leaveme"); - evas_object_color_set(ELM_WIDGET_DATA(sd)->resize_obj, 0, 0, 0, 0); return content; } -static void -_elm_mapbuf_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Mapbuf_Smart_Data); - - ELM_WIDGET_DATA(priv)->resize_obj = - evas_object_rectangle_add(evas_object_evas_get(obj)); - - ELM_WIDGET_CLASS(_elm_mapbuf_parent_sc)->base.add(obj); - - evas_object_static_clip_set(ELM_WIDGET_DATA(priv)->resize_obj, EINA_TRUE); - evas_object_pass_events_set(ELM_WIDGET_DATA(priv)->resize_obj, EINA_TRUE); - evas_object_color_set(ELM_WIDGET_DATA(priv)->resize_obj, 0, 0, 0, 0); - - priv->enabled = 0; - priv->alpha = 1; - priv->smooth = 1; - - elm_widget_can_focus_set(obj, EINA_FALSE); - - _sizing_eval(obj); -} - -static void -_elm_mapbuf_smart_set_user(Elm_Container_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_mapbuf_smart_add; - ELM_WIDGET_CLASS(sc)->base.resize = _elm_mapbuf_smart_resize; - ELM_WIDGET_CLASS(sc)->base.move = _elm_mapbuf_smart_move; - - ELM_WIDGET_CLASS(sc)->theme = _elm_mapbuf_smart_theme; - ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_mapbuf_smart_sub_object_del; - - sc->content_set = _elm_mapbuf_smart_content_set; - sc->content_get = _elm_mapbuf_smart_content_get; - sc->content_unset = _elm_mapbuf_smart_content_unset; -} - EAPI Evas_Object * elm_mapbuf_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "mapbuf"); + elm_widget_type_set(obj, "mapbuf"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd->clip = evas_object_rectangle_add(e); + evas_object_static_clip_set(wd->clip, EINA_TRUE); + evas_object_pass_events_set(wd->clip, EINA_TRUE); + evas_object_color_set(wd->clip, 0, 0, 0, 0); - e = evas_object_evas_get(parent); - if (!e) return NULL; + evas_object_event_callback_add(wd->clip, EVAS_CALLBACK_MOVE, _move, obj); + evas_object_event_callback_add(wd->clip, EVAS_CALLBACK_RESIZE, _resize, obj); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); - obj = evas_object_smart_add(e, _elm_mapbuf_smart_class_new()); + elm_widget_resize_object_set(obj, wd->clip); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + wd->enabled = 0; + wd->alpha = 1; + wd->smooth = 1; + _sizing_eval(obj); return obj; } EAPI void -elm_mapbuf_enabled_set(Evas_Object *obj, - Eina_Bool enabled) +elm_mapbuf_enabled_set(Evas_Object *obj, Eina_Bool enabled) { - ELM_MAPBUF_CHECK(obj); - ELM_MAPBUF_DATA_GET(obj, sd); - - if (sd->enabled == enabled) return; - sd->enabled = enabled; - - if (sd->content) evas_object_static_clip_set(sd->content, sd->enabled); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->enabled == enabled) return; + wd->enabled = enabled; + if (wd->content) evas_object_static_clip_set(wd->content, wd->enabled); _configure(obj); } EAPI Eina_Bool elm_mapbuf_enabled_get(const Evas_Object *obj) { - ELM_MAPBUF_CHECK(obj) EINA_FALSE; - ELM_MAPBUF_DATA_GET(obj, sd); - - return sd->enabled; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->enabled; } EAPI void -elm_mapbuf_smooth_set(Evas_Object *obj, - Eina_Bool smooth) +elm_mapbuf_smooth_set(Evas_Object *obj, Eina_Bool smooth) { - ELM_MAPBUF_CHECK(obj); - ELM_MAPBUF_DATA_GET(obj, sd); - - if (sd->smooth == smooth) return; - sd->smooth = smooth; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->smooth == smooth) return; + wd->smooth = smooth; _configure(obj); } EAPI Eina_Bool elm_mapbuf_smooth_get(const Evas_Object *obj) { - ELM_MAPBUF_CHECK(obj) EINA_FALSE; - ELM_MAPBUF_DATA_GET(obj, sd); - - return sd->smooth; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->smooth; } EAPI void -elm_mapbuf_alpha_set(Evas_Object *obj, - Eina_Bool alpha) +elm_mapbuf_alpha_set(Evas_Object *obj, Eina_Bool alpha) { - ELM_MAPBUF_CHECK(obj); - ELM_MAPBUF_DATA_GET(obj, sd); - - if (sd->alpha == alpha) return; - sd->alpha = alpha; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->alpha == alpha) return; + wd->alpha = alpha; _configure(obj); } EAPI Eina_Bool elm_mapbuf_alpha_get(const Evas_Object *obj) { - ELM_MAPBUF_CHECK(obj) EINA_FALSE; - ELM_MAPBUF_DATA_GET(obj, sd); - - return sd->alpha; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->alpha; } diff --git a/src/lib/elm_mapbuf.h b/src/lib/elm_mapbuf.h index 2e3b827d2..462d758ff 100644 --- a/src/lib/elm_mapbuf.h +++ b/src/lib/elm_mapbuf.h @@ -12,16 +12,14 @@ * need to resize or move it frequently (the content object and its * children). * - * This widget inherits from @ref elm-container-class, so that the - * functions meant to act on it will wor work for mapbuf objects: + * Default content parts of the mapbuf widget that you can use for are: + * @li "default" - A content of the mapbuf * + * Supported elm_object common APIs. * @li @ref elm_object_part_content_set * @li @ref elm_object_part_content_get * @li @ref elm_object_part_content_unset * - * Default content parts of the mapbuf widget that you can use are: - * @li "default" - The main content of the mapbuf - * * To enable map, elm_mapbuf_enabled_set() should be used. * * See how to use this widget in this example: diff --git a/src/lib/elm_notify.c b/src/lib/elm_notify.c index c6500db4f..1b683902f 100644 --- a/src/lib/elm_notify.c +++ b/src/lib/elm_notify.c @@ -1,62 +1,70 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_container.h" -static const char NOTIFY_SMART_NAME[] = "elm_notify"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Notify_Smart_Data Elm_Notify_Smart_Data; - -struct _Elm_Notify_Smart_Data +struct _Widget_Data { - Elm_Widget_Smart_Data base; - - Evas_Object *notify, *content, *parent; - Evas_Object *block_events; - - Elm_Notify_Orient orient; + Evas_Object *notify, *content, *parent; - double timeout; - Ecore_Timer *timer; + Elm_Notify_Orient orient; + Eina_Bool allow_events; + Evas_Object *block_events; - Eina_Bool allow_events : 1; + double timeout; + Ecore_Timer *timer; }; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _signal_block_clicked(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _calc(Evas_Object *obj); +static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _parent_hide(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _restack(void *data, Evas *e, Evas_Object *obj, void *event_info); + static const char SIG_BLOCK_CLICKED[] = "block,clicked"; static const char SIG_TIMEOUT[] = "timeout"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_BLOCK_CLICKED, ""}, - {SIG_TIMEOUT, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_BLOCK_CLICKED, ""}, + {SIG_TIMEOUT, ""}, + {NULL, NULL} }; -#define ELM_NOTIFY_DATA_GET(o, sd) \ - Elm_Notify_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_NOTIFY_DATA_GET_OR_RETURN(o, ptr) \ - ELM_NOTIFY_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_NOTIFY_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_NOTIFY_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_NOTIFY_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), NOTIFY_SMART_NAME, __func__)) \ - return - -EVAS_SMART_SUBCLASS_NEW - (NOTIFY_SMART_NAME, _elm_notify, Elm_Container_Smart_Class, - Elm_Container_Smart_Class, elm_container_smart_class_get, NULL); +static void +_del_pre_hook(Evas_Object *obj) +{ + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _resize, obj); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, _resize, obj); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, obj); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, obj); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESTACK, _restack, obj); +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_notify_parent_set(obj, NULL); + elm_notify_allow_events_set(obj, EINA_TRUE); + if (wd->timer) + { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + free(wd); +} /** * Return Notification orientation with RTL @@ -72,39 +80,32 @@ EVAS_SMART_SUBCLASS_NEW * @internal **/ static Elm_Notify_Orient -_notify_orientation_rtl_fix(Evas_Object *obj, - Elm_Notify_Orient orient) +_notify_orientation_with_rtl(Evas_Object *obj, Elm_Notify_Orient orient) { if (elm_widget_mirrored_get(obj)) { switch (orient) { case ELM_NOTIFY_ORIENT_LEFT: - orient = ELM_NOTIFY_ORIENT_RIGHT; - break; - + orient = ELM_NOTIFY_ORIENT_RIGHT; + break; case ELM_NOTIFY_ORIENT_RIGHT: - orient = ELM_NOTIFY_ORIENT_LEFT; - break; - + orient = ELM_NOTIFY_ORIENT_LEFT; + break; case ELM_NOTIFY_ORIENT_TOP_LEFT: - orient = ELM_NOTIFY_ORIENT_TOP_RIGHT; - break; - + orient = ELM_NOTIFY_ORIENT_TOP_RIGHT; + break; case ELM_NOTIFY_ORIENT_TOP_RIGHT: - orient = ELM_NOTIFY_ORIENT_TOP_LEFT; - break; - + orient = ELM_NOTIFY_ORIENT_TOP_LEFT; + break; case ELM_NOTIFY_ORIENT_BOTTOM_LEFT: - orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT; - break; - + orient = ELM_NOTIFY_ORIENT_BOTTOM_RIGHT; + break; case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT: - orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT; - break; - + orient = ELM_NOTIFY_ORIENT_BOTTOM_LEFT; + break; default: - break; + break; } } @@ -114,56 +115,40 @@ _notify_orientation_rtl_fix(Evas_Object *obj, static void _notify_theme_apply(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); const char *style = elm_widget_style_get(obj); - ELM_NOTIFY_DATA_GET(obj, sd); - - switch (sd->orient) + switch (wd->orient) { case ELM_NOTIFY_ORIENT_TOP: - elm_widget_theme_object_set(obj, sd->notify, "notify", "top", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "top", style); + break; case ELM_NOTIFY_ORIENT_CENTER: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "center", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "center", style); + break; case ELM_NOTIFY_ORIENT_BOTTOM: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "bottom", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "bottom", style); + break; case ELM_NOTIFY_ORIENT_LEFT: - elm_widget_theme_object_set(obj, sd->notify, "notify", "left", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "left", style); + break; case ELM_NOTIFY_ORIENT_RIGHT: - elm_widget_theme_object_set(obj, sd->notify, "notify", "right", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "right", style); + break; case ELM_NOTIFY_ORIENT_TOP_LEFT: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "top_left", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "top_left", style); + break; case ELM_NOTIFY_ORIENT_TOP_RIGHT: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "top_right", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "top_right", style); + break; case ELM_NOTIFY_ORIENT_BOTTOM_LEFT: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "bottom_left", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "bottom_left", style); + break; case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT: - elm_widget_theme_object_set - (obj, sd->notify, "notify", "bottom_right", style); - break; - + _elm_theme_object_set(obj, wd->notify, "notify", "bottom_right", style); + break; case ELM_NOTIFY_ORIENT_LAST: - break; + break; } } @@ -182,569 +167,460 @@ _notify_theme_apply(Evas_Object *obj) static void _notify_move_to_orientation(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); int offx; int offy; Evas_Coord minw = -1, minh = -1; Evas_Coord x, y, w, h; - ELM_NOTIFY_DATA_GET(obj, sd); - + if (!wd) return; evas_object_geometry_get(obj, &x, &y, &w, &h); - edje_object_size_min_get(sd->notify, &minw, &minh); - edje_object_size_min_restricted_calc(sd->notify, &minw, &minh, minw, minh); + edje_object_size_min_get(wd->notify, &minw, &minh); + edje_object_size_min_restricted_calc(wd->notify, &minw, &minh, minw, minh); offx = (w - minw) / 2; offy = (h - minh) / 2; - switch (_notify_orientation_rtl_fix(obj, sd->orient)) + switch (_notify_orientation_with_rtl(obj, wd->orient)) { case ELM_NOTIFY_ORIENT_TOP: - evas_object_move(sd->notify, x + offx, y); - break; - + evas_object_move(wd->notify, x + offx, y); + break; case ELM_NOTIFY_ORIENT_CENTER: - evas_object_move(sd->notify, x + offx, y + offy); - break; - + evas_object_move(wd->notify, x + offx, y + offy); + break; case ELM_NOTIFY_ORIENT_BOTTOM: - evas_object_move(sd->notify, x + offx, y + h - minh); - break; - + evas_object_move(wd->notify, x + offx, y + h - minh); + break; case ELM_NOTIFY_ORIENT_LEFT: - evas_object_move(sd->notify, x, y + offy); - break; - + evas_object_move(wd->notify, x, y + offy); + break; case ELM_NOTIFY_ORIENT_RIGHT: - evas_object_move(sd->notify, x + w - minw, y + offy); - break; - + evas_object_move(wd->notify, x + w - minw, y + offy); + break; case ELM_NOTIFY_ORIENT_TOP_LEFT: - evas_object_move(sd->notify, x, y); - break; - + evas_object_move(wd->notify, x, y); + break; case ELM_NOTIFY_ORIENT_TOP_RIGHT: - evas_object_move(sd->notify, x + w - minw, y); - break; - + evas_object_move(wd->notify, x + w - minw, y); + break; case ELM_NOTIFY_ORIENT_BOTTOM_LEFT: - evas_object_move(sd->notify, x, y + h - minh); - break; - + evas_object_move(wd->notify, x, y + h - minh); + break; case ELM_NOTIFY_ORIENT_BOTTOM_RIGHT: - evas_object_move(sd->notify, x + w - minw, y + h - minh); - break; - + evas_object_move(wd->notify, x + w - minw, y + h - minh); + break; case ELM_NOTIFY_ORIENT_LAST: - break; + break; } } static void _block_events_theme_apply(Evas_Object *obj) { - ELM_NOTIFY_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); const char *style = elm_widget_style_get(obj); - - elm_layout_theme_set(sd->block_events, "notify", "block_events", style); + _elm_theme_object_set(obj, wd->block_events, "notify", "block_events", style); } static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_NOTIFY_DATA_GET(obj, sd); - edje_object_mirrored_set(sd->notify, rtl); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->notify, rtl); _notify_move_to_orientation(obj); } static void -_sizing_eval(Evas_Object *obj) -{ - Evas_Coord x, y, w, h; - - ELM_NOTIFY_DATA_GET(obj, sd); - - if (!sd->parent) return; - evas_object_geometry_get(sd->parent, &x, &y, &w, &h); - evas_object_move(obj, x, y); - evas_object_resize(obj, w, h); -} - -static Eina_Bool -_elm_notify_smart_theme(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - ELM_NOTIFY_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_notify_parent_sc)->theme(obj)) return EINA_FALSE; - + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); _mirrored_set(obj, elm_widget_mirrored_get(obj)); - _notify_theme_apply(obj); - if (sd->block_events) _block_events_theme_apply(obj); - - edje_object_scale_set - (sd->notify, elm_widget_scale_get(obj) * elm_config_scale_get()); - + if (wd->block_events) _block_events_theme_apply(obj); + edje_object_scale_set(wd->notify, elm_widget_scale_get(obj) * + _elm_config->scale); _sizing_eval(obj); - - return EINA_TRUE; } static void -_calc(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { - Evas_Coord minw = -1, minh = -1; - Evas_Coord x, y, w, h; - - ELM_NOTIFY_DATA_GET(obj, sd); - - _sizing_eval(obj); - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - edje_object_size_min_get(sd->notify, &minw, &minh); - edje_object_size_min_restricted_calc(sd->notify, &minw, &minh, minw, minh); - - if (sd->content) - { - _notify_move_to_orientation(obj); - evas_object_resize(sd->notify, minw, minh); - } + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord x,y,w,h; + if (!wd) return; + if (!wd->parent) return; + evas_object_geometry_get(wd->parent, &x, &y, &w, &h); + evas_object_move(obj, x, y); + evas_object_resize(obj, w, h); } static void -_changed_size_hints_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { _calc(data); } static void -_content_resize_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - _calc(data); -} - -static Eina_Bool -_elm_notify_smart_sub_object_del(Evas_Object *obj, - Evas_Object *sobj) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { - ELM_NOTIFY_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; - if (!ELM_WIDGET_CLASS(_elm_notify_parent_sc)->sub_object_del(obj, sobj)) - return EINA_FALSE; - - if (sobj == sd->content) + if (sub == wd->content) { - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints_cb, obj); - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_RESIZE, _content_resize_cb, obj); - sd->content = NULL; + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_RESIZE, + _content_resize, obj); + wd->content = NULL; } - - return EINA_TRUE; } static void -_block_area_clicked_cb(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_signal_block_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL); } static void -_restack_cb(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_restack(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_NOTIFY_DATA_GET(obj, sd); - - evas_object_layer_set(sd->notify, evas_object_layer_get(obj)); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_layer_set(wd->notify, + evas_object_layer_get(obj)); } static void -_elm_notify_smart_resize(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +_resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.resize(obj, w, h); - _calc(obj); } static void -_elm_notify_smart_move(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +_content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.move(obj, x, y); + _calc(data); +} - _calc(obj); +static void +_calc(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; + Evas_Coord x, y, w, h; + + if (!wd) return; + _sizing_eval(obj); + + evas_object_geometry_get(obj, &x, &y, &w, &h); + edje_object_size_min_get(wd->notify, &minw, &minh); + edje_object_size_min_restricted_calc(wd->notify, &minw, &minh, minw, minh); + + if (wd->content) + { + _notify_move_to_orientation(obj); + evas_object_resize(wd->notify, minw, minh); + } } static Eina_Bool _timer_cb(void *data) { Evas_Object *obj = data; - - ELM_NOTIFY_DATA_GET(obj, sd); - - sd->timer = NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ECORE_CALLBACK_CANCEL; + wd->timer = NULL; evas_object_hide(obj); evas_object_smart_callback_call(obj, SIG_TIMEOUT, NULL); - return ECORE_CALLBACK_CANCEL; } static void -_timer_init(Evas_Object *obj, - Elm_Notify_Smart_Data *sd) +_timer_init(Evas_Object *obj, Widget_Data *wd) { - if (sd->timer) + if (wd->timer) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + ecore_timer_del(wd->timer); + wd->timer = NULL; } - if ((evas_object_visible_get(obj)) && (sd->timeout > 0.0)) - sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj); + if ((evas_object_visible_get(obj)) && (wd->timeout > 0.0)) + wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj); } static void -_elm_notify_smart_show(Evas_Object *obj) +_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_NOTIFY_DATA_GET(obj, sd); - - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.show(obj); - - evas_object_show(sd->notify); - if (!sd->allow_events) evas_object_show(sd->block_events); - _timer_init(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_show(wd->notify); + if (!wd->allow_events) evas_object_show(wd->block_events); + _timer_init(obj, wd); elm_object_focus_set(obj, EINA_TRUE); } static void -_elm_notify_smart_hide(Evas_Object *obj) +_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_NOTIFY_DATA_GET(obj, sd); - - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.hide(obj); - - evas_object_hide(sd->notify); - if (!sd->allow_events) evas_object_hide(sd->block_events); - if (sd->timer) + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_hide(wd->notify); + if (!wd->allow_events) evas_object_hide(wd->block_events); + if (wd->timer) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + ecore_timer_del(wd->timer); + wd->timer = NULL; } } static void -_parent_del_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_NOTIFY_DATA_GET(data, sd); - - sd->parent = NULL; + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + wd->parent = NULL; evas_object_hide(data); } static void -_parent_hide_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_parent_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; evas_object_hide(data); } static Eina_Bool -_elm_notify_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_notify_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Object *cur; - ELM_NOTIFY_DATA_GET(obj, sd); - - if (!sd->content) + if ((!wd) || (!wd->content)) return EINA_FALSE; - cur = sd->content; + cur = wd->content; - /* Try to cycle focus on content */ + /* Try Focus cycle in subitem */ return elm_widget_focus_next_get(cur, dir, next); } -static Eina_Bool -_elm_notify_smart_content_set(Evas_Object *obj, - const char *part, - Evas_Object *content) +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - ELM_NOTIFY_DATA_GET(obj, sd); - - if (part && strcmp(part, "default")) return EINA_FALSE; - if (sd->content == content) return EINA_TRUE; - if (sd->content) evas_object_del(sd->content); - sd->content = content; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + if (part && strcmp(part ,"default")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; if (content) { elm_widget_sub_object_add(obj, content); - evas_object_event_callback_add - (content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints_cb, obj); - evas_object_event_callback_add - (content, EVAS_CALLBACK_RESIZE, _content_resize_cb, obj); - edje_object_part_swallow(sd->notify, "elm.swallow.content", content); + evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE, + _content_resize, obj); + edje_object_part_swallow(wd->notify, "elm.swallow.content", content); } - _sizing_eval(obj); _calc(obj); - - return EINA_TRUE; } static Evas_Object * -_elm_notify_smart_content_get(const Evas_Object *obj, - const char *part) +_content_get_hook(const Evas_Object *obj, const char *part) { - ELM_NOTIFY_DATA_GET(obj, sd); - - if (part && strcmp(part, "default")) return NULL; - - return sd->content; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + if (part && strcmp(part ,"default")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->content; } static Evas_Object * -_elm_notify_smart_content_unset(Evas_Object *obj, - const char *part) +_content_unset_hook(Evas_Object *obj, const char *part) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; Evas_Object *content; - - ELM_NOTIFY_DATA_GET(obj, sd); - - if (part && strcmp(part, "default")) return NULL; - if (!sd->content) return NULL; - - content = sd->content; - elm_widget_sub_object_del(obj, sd->content); - edje_object_part_unswallow(sd->notify, content); - + if (part && strcmp(part ,"default")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->content) return NULL; + content = wd->content; + elm_widget_sub_object_del(obj, wd->content); + edje_object_part_unswallow(wd->notify, content); return content; } -static void -_elm_notify_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Notify_Smart_Data); - - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.add(obj); - - priv->allow_events = EINA_TRUE; - - priv->notify = edje_object_add(evas_object_evas_get(obj)); - priv->orient = -1; - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESTACK, _restack_cb, obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); -} - -static void -_elm_notify_smart_del(Evas_Object *obj) -{ - ELM_NOTIFY_DATA_GET(obj, sd); - - elm_notify_parent_set(obj, NULL); - elm_notify_allow_events_set(obj, EINA_FALSE); - if (sd->timer) - { - ecore_timer_del(sd->timer); - sd->timer = NULL; - } - - ELM_WIDGET_CLASS(_elm_notify_parent_sc)->base.del(obj); -} - -static void -_elm_notify_smart_set_user(Elm_Container_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_notify_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_notify_smart_del; - - ELM_WIDGET_CLASS(sc)->base.resize = _elm_notify_smart_resize; - ELM_WIDGET_CLASS(sc)->base.move = _elm_notify_smart_move; - ELM_WIDGET_CLASS(sc)->base.show = _elm_notify_smart_show; - ELM_WIDGET_CLASS(sc)->base.hide = _elm_notify_smart_hide; - - ELM_WIDGET_CLASS(sc)->theme = _elm_notify_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = _elm_notify_smart_focus_next; - - ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_notify_smart_sub_object_del; - - ELM_CONTAINER_CLASS(sc)->content_set = _elm_notify_smart_content_set; - ELM_CONTAINER_CLASS(sc)->content_get = _elm_notify_smart_content_get; - ELM_CONTAINER_CLASS(sc)->content_unset = _elm_notify_smart_content_unset; -} - EAPI Evas_Object * elm_notify_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - obj = evas_object_smart_add(e, _elm_notify_smart_class_new()); + ELM_SET_WIDTYPE(widtype, "notify"); + elm_widget_type_set(obj, "notify"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_focus_next_hook_set(obj, _elm_notify_focus_next_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + wd->allow_events = EINA_TRUE; + wd->notify = edje_object_add(e); + wd->orient = -1; elm_notify_orient_set(obj, ELM_NOTIFY_ORIENT_TOP); + elm_notify_parent_set(obj, parent); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _resize, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESTACK, _restack, obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); _sizing_eval(obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } EAPI void -elm_notify_parent_set(Evas_Object *obj, - Evas_Object *parent) +elm_notify_parent_set(Evas_Object *obj, Evas_Object *parent) { - ELM_NOTIFY_CHECK(obj); - ELM_NOTIFY_DATA_GET(obj, sd); - - if (sd->parent) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->parent) { - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_RESIZE, _changed_size_hints_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_MOVE, _changed_size_hints_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj); - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj); - sd->parent = NULL; + evas_object_event_callback_del_full(wd->parent, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, + _changed_size_hints, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE, + _changed_size_hints, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL, + _parent_del, obj); + evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE, + _parent_hide, obj); + wd->parent = NULL; } if (parent) { - sd->parent = parent; - evas_object_event_callback_add - (parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _changed_size_hints_cb, obj); - evas_object_event_callback_add - (parent, EVAS_CALLBACK_RESIZE, _changed_size_hints_cb, obj); - evas_object_event_callback_add - (parent, EVAS_CALLBACK_MOVE, _changed_size_hints_cb, obj); - evas_object_event_callback_add - (parent, EVAS_CALLBACK_DEL, _parent_del_cb, obj); - evas_object_event_callback_add - (parent, EVAS_CALLBACK_HIDE, _parent_hide_cb, obj); + wd->parent = parent; + evas_object_event_callback_add(parent, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, + _changed_size_hints, obj); + evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE, + _changed_size_hints, obj); + evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL, + _parent_del, obj); + evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE, + _parent_hide, obj); _sizing_eval(obj); } - _calc(obj); } EAPI Evas_Object * elm_notify_parent_get(const Evas_Object *obj) { - ELM_NOTIFY_CHECK(obj) NULL; - ELM_NOTIFY_DATA_GET(obj, sd); - - return sd->parent; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->parent; } EAPI void -elm_notify_orient_set(Evas_Object *obj, - Elm_Notify_Orient orient) +elm_notify_orient_set(Evas_Object *obj, Elm_Notify_Orient orient) { - ELM_NOTIFY_CHECK(obj); - ELM_NOTIFY_DATA_GET(obj, sd); - - if (sd->orient == orient) return; - sd->orient = orient; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->orient == orient) return; + wd->orient = orient; _notify_theme_apply(obj); - _calc(obj); + _resize(obj, NULL, obj, NULL); } EAPI Elm_Notify_Orient elm_notify_orient_get(const Evas_Object *obj) { - ELM_NOTIFY_CHECK(obj) - 1; - ELM_NOTIFY_DATA_GET(obj, sd); - - return sd->orient; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1; + return wd->orient; } EAPI void -elm_notify_timeout_set(Evas_Object *obj, - double timeout) +elm_notify_timeout_set(Evas_Object *obj, double timeout) { - ELM_NOTIFY_CHECK(obj); - ELM_NOTIFY_DATA_GET(obj, sd); - - sd->timeout = timeout; - _timer_init(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->timeout = timeout; + _timer_init(obj, wd); } EAPI double elm_notify_timeout_get(const Evas_Object *obj) { - ELM_NOTIFY_CHECK(obj) 0.0; - ELM_NOTIFY_DATA_GET(obj, sd); - - return sd->timeout; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->timeout; } EAPI void -elm_notify_allow_events_set(Evas_Object *obj, - Eina_Bool allow) +elm_notify_allow_events_set(Evas_Object *obj, Eina_Bool allow) { - ELM_NOTIFY_CHECK(obj); - ELM_NOTIFY_DATA_GET(obj, sd); - - if (allow == sd->allow_events) return; - sd->allow_events = allow; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (allow == wd->allow_events) return; + wd->allow_events = allow; if (!allow) { - sd->block_events = elm_layout_add(obj); + wd->block_events = edje_object_add(evas_object_evas_get(obj)); _block_events_theme_apply(obj); - elm_widget_resize_object_set(obj, sd->block_events); - elm_layout_signal_callback_add - (sd->block_events, "elm,action,click", "elm", - _block_area_clicked_cb, obj); + elm_widget_resize_object_set(obj, wd->block_events); + edje_object_signal_callback_add(wd->block_events, "elm,action,click", + "elm", _signal_block_clicked, obj); } else - evas_object_del(sd->block_events); + evas_object_del(wd->block_events); } EAPI Eina_Bool elm_notify_allow_events_get(const Evas_Object *obj) { - ELM_NOTIFY_CHECK(obj) EINA_FALSE; - ELM_NOTIFY_DATA_GET(obj, sd); - - return sd->allow_events; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->allow_events; } diff --git a/src/lib/elm_notify.h b/src/lib/elm_notify.h index e084615b0..0fab7425f 100644 --- a/src/lib/elm_notify.h +++ b/src/lib/elm_notify.h @@ -14,16 +14,14 @@ * @li "timeout" - when timeout happens on notify and it's hidden * @li "block,clicked" - when a click outside of the notify happens * - * This widget inherits from @ref elm-container-class, so that the - * functions meant to act on it will wor work for mapbuf objects: + * Default content parts of the notify widget that you can use for are: + * @li "default" - A content of the notify * + * Supported elm_object common APIs. * @li @ref elm_object_part_content_set * @li @ref elm_object_part_content_get * @li @ref elm_object_part_content_unset * - * Default content parts of the notify widget that you can use are: - * @li @c "default" - The main content of the notify - * * @ref tutorial_notify show usage of the API. * * @{ diff --git a/src/lib/elm_panes.c b/src/lib/elm_panes.c index 39799152e..249f9e215 100644 --- a/src/lib/elm_panes.c +++ b/src/lib/elm_panes.c @@ -1,6 +1,5 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" /** * TODO @@ -9,142 +8,131 @@ * Add events (move, start ...) */ -static const char PANES_SMART_NAME[] = "elm_panes"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Panes_Smart_Data Elm_Panes_Smart_Data; - -struct _Elm_Panes_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; + Evas_Object *panes; + + struct + { + Evas_Object *left; + Evas_Object *right; + } contents; struct - { - int x_diff; - int y_diff; - Eina_Bool move; - } move; - - Eina_Bool double_clicked : 1; - Eina_Bool horizontal : 1; - Eina_Bool fixed : 1; + { + int x_diff; + int y_diff; + Eina_Bool move; + } move; + + Eina_Bool clicked_double; + Eina_Bool horizontal; + Eina_Bool fixed; }; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); + static const char SIG_CLICKED[] = "clicked"; static const char SIG_PRESS[] = "press"; static const char SIG_UNPRESS[] = "unpress"; -static const char SIG_DOUBLE_CLICKED[] = "clicked,double"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; + +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CLICKED, ""}, {SIG_PRESS, ""}, {SIG_UNPRESS, ""}, - {SIG_DOUBLE_CLICKED, ""}, + {SIG_CLICKED_DOUBLE, ""}, {NULL, NULL} }; -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +static void +_del_hook(Evas_Object *obj) { - {"left", "elm.swallow.left"}, - {"right", "elm.swallow.right"}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} -#define ELM_PANES_DATA_GET(o, sd) \ - Elm_Panes_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_PANES_DATA_GET_OR_RETURN(o, ptr) \ - ELM_PANES_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_PANES_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_PANES_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_PANES_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), PANES_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (PANES_SMART_NAME, _elm_panes, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->panes, rtl); +} -static Eina_Bool -_elm_panes_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); + const char *style = elm_widget_style_get(obj); double size; - ELM_PANES_DATA_GET(obj, sd); - - if (sd->horizontal) - eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "horizontal"); - else - eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "vertical"); - - if (!ELM_WIDGET_CLASS(_elm_panes_parent_sc)->theme(obj)) return EINA_FALSE; - + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); size = elm_panes_content_left_size_get(obj); - if (sd->fixed) elm_layout_signal_emit(obj, "elm.panes.fixed", "elm"); - - elm_layout_sizing_eval(obj); - + if (wd->horizontal) + _elm_theme_object_set(obj, wd->panes, "panes", "horizontal", style); + else + _elm_theme_object_set(obj, wd->panes, "panes", "vertical", style); + + if (wd->contents.left) + edje_object_part_swallow(wd->panes, "elm.swallow.left", wd->contents.left); + if (wd->contents.right) + edje_object_part_swallow(wd->panes, "elm.swallow.right", wd->contents.right); + if (wd->fixed) + edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm"); + + edje_object_scale_set(wd->panes, elm_widget_scale_get(obj) * + _elm_config->scale); + _sizing_eval(obj); elm_panes_content_left_size_set(obj, size); - - return EINA_TRUE; } static Eina_Bool -_elm_panes_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_panes_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - double w, h; - unsigned char i; - Evas_Object *to_focus; - Evas_Object *chain[2]; - Evas_Object *left, *right; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - ELM_PANES_DATA_GET(obj, sd); - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", &w, &h); - - left = elm_layout_content_get(obj, "left"); - right = elm_layout_content_get(obj, "right"); + double w, h; + edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h); + if (((wd->horizontal) && ( h == 0.0 )) || ((!wd->horizontal) && ( w == 0.0 ))) + return elm_widget_focus_next_get(wd->contents.right, dir, next); - if (((sd->horizontal) && (h == 0.0)) || ((!sd->horizontal) && (w == 0.0))) - return elm_widget_focus_next_get(right, dir, next); + Evas_Object *chain[2]; /* Direction */ if (dir == ELM_FOCUS_PREVIOUS) { - chain[0] = right; - chain[1] = left; + chain[0] = wd->contents.right; + chain[1] = wd->contents.left; } else if (dir == ELM_FOCUS_NEXT) { - chain[0] = left; - chain[1] = right; + chain[0] = wd->contents.left; + chain[1] = wd->contents.right; } - else return EINA_FALSE; + else + return EINA_FALSE; - i = elm_widget_focus_get(chain[1]); + unsigned char i = elm_widget_focus_get(chain[1]); - if (elm_widget_focus_next_get(chain[i], dir, next)) return EINA_TRUE; + if (elm_widget_focus_next_get(chain[i], dir, next)) + return EINA_TRUE; i = !i; + Evas_Object *to_focus; if (elm_widget_focus_next_get(chain[i], dir, &to_focus)) { *next = to_focus; @@ -155,233 +143,328 @@ _elm_panes_smart_focus_next(const Evas_Object *obj, } static void -_on_clicked(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; +} + +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); +} + +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + + if (!wd) return; + if (sub == wd->contents.left) + { + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->panes, sub); + wd->contents.left = NULL; + _sizing_eval(obj); + } + else if (sub == wd->contents.right) + { + evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->panes, sub); + wd->contents.right= NULL; + _sizing_eval(obj); + } +} + +static void +_clicked(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__) { evas_object_smart_callback_call(data, SIG_CLICKED, NULL); } static void -_double_clicked(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_clicked_double(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_PANES_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); - sd->double_clicked = EINA_TRUE; + wd->clicked_double = EINA_TRUE; } static void -_on_pressed(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_press(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__) { evas_object_smart_callback_call(data, SIG_PRESS, NULL); } static void -_on_unpressed(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_unpress(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_PANES_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); evas_object_smart_callback_call(data, SIG_UNPRESS, NULL); - if (sd->double_clicked) + if (wd->clicked_double) { - evas_object_smart_callback_call(data, SIG_DOUBLE_CLICKED, NULL); - sd->double_clicked = EINA_FALSE; + evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL); + wd->clicked_double = EINA_FALSE; } } static void -_elm_panes_smart_add(Evas_Object *obj) +_content_left_set(Evas_Object *obj, Evas_Object *content) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Panes_Smart_Data); - - ELM_WIDGET_CLASS(_elm_panes_parent_sc)->base.add(obj); - - elm_layout_theme_set(obj, "panes", "vertical", elm_widget_style_get(obj)); - - elm_panes_content_left_size_set(obj, 0.5); + Widget_Data *wd = elm_widget_data_get(obj); + if (wd->contents.left == content) return; + if (wd->contents.left) + evas_object_del(wd->contents.left); + wd->contents.left = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + edje_object_part_swallow(wd->panes, "elm.swallow.left", content); + } +} - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click", "", - _on_clicked, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,click,double", "", - _double_clicked, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,press", "", - _on_pressed, obj); - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,unpress", "", - _on_unpressed, obj); +static void +_content_right_set(Evas_Object *obj, Evas_Object *content) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (wd->contents.right == content) return; + if (wd->contents.right) + evas_object_del(wd->contents.right); + wd->contents.right = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + edje_object_part_swallow(wd->panes, "elm.swallow.right", content); + } +} - elm_widget_can_focus_set(obj, EINA_FALSE); +static Evas_Object * +_content_left_unset(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd->contents.left) return NULL; + Evas_Object *content = wd->contents.left; + elm_widget_sub_object_del(obj, content); + return content; +} - elm_layout_sizing_eval(obj); +static Evas_Object * +_content_right_unset(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd->contents.right) return NULL; + Evas_Object *content = wd->contents.right; + elm_widget_sub_object_del(obj, content); + return content; } static void -_elm_panes_smart_set_user(Elm_Layout_Smart_Class *sc) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_panes_smart_add; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12; + if (!part || !strcmp(part, "left")) + _content_left_set(obj, content); + else if (!strcmp(part, "right")) + _content_right_set(obj, content); +} - ELM_WIDGET_CLASS(sc)->theme = _elm_panes_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = _elm_panes_smart_focus_next; +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12; + if (!part || !strcmp(part, "left")) + return wd->contents.left; + else if (!strcmp(part, "right")) + return wd->contents.right; + return NULL; +} - sc->content_aliases = _content_aliases; +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12; + if (!part || !strcmp(part, "left")) + return _content_left_unset(obj); + else if (!strcmp(part, "right")) + return _content_right_unset(obj); + return NULL; } EAPI Evas_Object * elm_panes_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "panes"); + elm_widget_type_set(obj, "panes"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_focus_next_hook_set(obj, _elm_panes_focus_next_hook); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd->panes = edje_object_add(e); + _elm_theme_object_set(obj, wd->panes, "panes", "vertical", "default"); + elm_widget_resize_object_set(obj, wd->panes); + evas_object_show(wd->panes); - e = evas_object_evas_get(parent); - if (!e) return NULL; + elm_panes_content_left_size_set(obj, 0.5); + + edje_object_signal_callback_add(wd->panes, "elm,action,click", "", + _clicked, obj); + edje_object_signal_callback_add(wd->panes, "elm,action,click,double", "", + _clicked_double, obj); + edje_object_signal_callback_add(wd->panes, "elm,action,press", "", + _press, obj); + edje_object_signal_callback_add(wd->panes, "elm,action,unpress", "", + _unpress, obj); - obj = evas_object_smart_add(e, _elm_panes_smart_class_new()); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EINA_DEPRECATED EAPI void -elm_panes_content_left_set(Evas_Object *obj, - Evas_Object *content) +elm_panes_content_left_set(Evas_Object *obj, Evas_Object *content) { - elm_layout_content_set(obj, "left", content); + _content_set_hook(obj, "left", content); } EINA_DEPRECATED EAPI void -elm_panes_content_right_set(Evas_Object *obj, - Evas_Object *content) +elm_panes_content_right_set(Evas_Object *obj, Evas_Object *content) { - elm_layout_content_set(obj, "right", content); + _content_set_hook(obj, "right", content); } EINA_DEPRECATED EAPI Evas_Object * elm_panes_content_left_get(const Evas_Object *obj) { - return elm_layout_content_get(obj, "left"); + return _content_get_hook(obj, "left"); } EINA_DEPRECATED EAPI Evas_Object * elm_panes_content_right_get(const Evas_Object *obj) { - return elm_layout_content_get(obj, "right"); + return _content_get_hook(obj, "right"); } EINA_DEPRECATED EAPI Evas_Object * elm_panes_content_left_unset(Evas_Object *obj) { - return elm_layout_content_unset(obj, "left"); + return _content_unset_hook(obj, "left"); } EINA_DEPRECATED EAPI Evas_Object * elm_panes_content_right_unset(Evas_Object *obj) { - return elm_layout_content_unset(obj, "right"); + return _content_unset_hook(obj, "right"); } EAPI double elm_panes_content_left_size_get(const Evas_Object *obj) { + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); double w, h; - ELM_PANES_CHECK(obj) 0.0; - ELM_PANES_DATA_GET(obj, sd); - - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", &w, &h); - - if (sd->horizontal) return h; + if (!wd) return 0; + edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h); + if (wd->horizontal) return h; else return w; } EAPI void -elm_panes_content_left_size_set(Evas_Object *obj, - double size) +elm_panes_content_left_size_set(Evas_Object *obj, double size) { - ELM_PANES_CHECK(obj); - ELM_PANES_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (size < 0.0) size = 0.0; - else if (size > 1.0) - size = 1.0; - if (sd->horizontal) - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", 0.0, size); + else if (size > 1.0) size = 1.0; + if (wd->horizontal) + edje_object_part_drag_value_set(wd->panes, "elm.bar", 0.0, size); else - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.bar", size, 0.0); + edje_object_part_drag_value_set(wd->panes, "elm.bar", size, 0.0); } EAPI double elm_panes_content_right_size_get(const Evas_Object *obj) { - return 1.0 - elm_panes_content_left_size_get(obj); + return (1.0 - elm_panes_content_left_size_get(obj)); } EAPI void -elm_panes_content_right_size_set(Evas_Object *obj, - double size) +elm_panes_content_right_size_set(Evas_Object *obj, double size) { elm_panes_content_left_size_set(obj, (1.0 - size)); } EAPI void -elm_panes_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_panes_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_PANES_CHECK(obj); - ELM_PANES_DATA_GET(obj, sd); - - sd->horizontal = horizontal; - _elm_panes_smart_theme(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->horizontal = horizontal; + _theme_hook(obj); elm_panes_content_left_size_set(obj, 0.5); } EAPI Eina_Bool elm_panes_horizontal_get(const Evas_Object *obj) { - ELM_PANES_CHECK(obj) EINA_FALSE; - ELM_PANES_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } EAPI void elm_panes_fixed_set(Evas_Object *obj, Eina_Bool fixed) { - ELM_PANES_CHECK(obj); - ELM_PANES_DATA_GET(obj, sd); - - sd->fixed = !!fixed; - if (sd->fixed == EINA_TRUE) - elm_layout_signal_emit(obj, "elm.panes.fixed", "elm"); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->fixed = !!fixed; + if (wd->fixed == EINA_TRUE) + edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm"); else - elm_layout_signal_emit(obj, "elm.panes.unfixed", "elm"); + edje_object_signal_emit(wd->panes, "elm.panes.unfixed", "elm"); } EAPI Eina_Bool elm_panes_fixed_get(const Evas_Object *obj) { - ELM_PANES_CHECK(obj) EINA_FALSE; - ELM_PANES_DATA_GET(obj, sd); - - return sd->fixed; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->fixed; } diff --git a/src/lib/elm_panes.h b/src/lib/elm_panes.h index b004725e7..f0fa00491 100644 --- a/src/lib/elm_panes.h +++ b/src/lib/elm_panes.h @@ -14,15 +14,11 @@ * Panes can be displayed vertically or horizontally, and contents * size proportion can be customized (homogeneous by default). * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for panes objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "press" - The panes has been pressed (button wasn't released yet). - * - @c "unpressed" - The panes was released after being pressed. - * - @c "clicked" - The panes has been clicked> - * - @c "clicked,double" - The panes has been double clicked + * Smart callbacks one can listen to: + * - "press" - The panes has been pressed (button wasn't released yet). + * - "unpressed" - The panes was released after being pressed. + * - "clicked" - The panes has been clicked> + * - "clicked,double" - The panes has been double clicked * * Available styles for it: * - @c "default" diff --git a/src/lib/elm_progressbar.c b/src/lib/elm_progressbar.c index 0f60b66d6..c67c5e684 100644 --- a/src/lib/elm_progressbar.c +++ b/src/lib/elm_progressbar.c @@ -1,297 +1,350 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" - -static const char PROGRESSBAR_SMART_NAME[] = "elm_progressbar"; #define MIN_RATIO_LVL 0.0 #define MAX_RATIO_LVL 1.0 -typedef struct _Elm_Progressbar_Smart_Data Elm_Progressbar_Smart_Data; +typedef struct _Widget_Data Widget_Data; -struct _Elm_Progressbar_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *spacer; - const char *units; - - Evas_Coord size; - double val; - - Eina_Bool horizontal : 1; - Eina_Bool inverted : 1; - Eina_Bool pulse : 1; - Eina_Bool pulse_state : 1; + Evas_Object *progressbar; + Evas_Object *spacer; + Evas_Object *icon; + Evas_Coord size; + Eina_Bool horizontal : 1; + Eina_Bool inverted : 1; + Eina_Bool pulse : 1; + Eina_Bool pulse_state : 1; + const char *units; + const char *label; + double val; }; -#define ELM_PROGRESSBAR_DATA_GET(o, sd) \ - Elm_Progressbar_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_PROGRESSBAR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_PROGRESSBAR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_PROGRESSBAR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_PROGRESSBAR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_PROGRESSBAR_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), PROGRESSBAR_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (PROGRESSBAR_SMART_NAME, _elm_progressbar, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"icon", "elm.swallow.icon"}, - {NULL, NULL} -}; - -static const Elm_Layout_Part_Alias_Description _text_aliases[] = -{ - {"default", "elm.text"}, - {NULL, NULL} -}; +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _units_set(Evas_Object *obj); +static void _val_set(Evas_Object *obj); static void -_units_set(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - if (sd->units) - { - char buf[1024]; - - snprintf(buf, sizeof(buf), sd->units, 100 * sd->val); - elm_layout_text_set(obj, "elm.text.status", buf); - } - else elm_layout_text_set(obj, "elm.text.status", NULL); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + if (wd->units) eina_stringshare_del(wd->units); + free(wd); } static void -_val_set(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Eina_Bool rtl; - double pos; - - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - pos = sd->val; - rtl = elm_widget_mirrored_get(obj); - - if ((!rtl && sd->inverted) || - (rtl && ((!sd->horizontal && sd->inverted) || - (sd->horizontal && !sd->inverted)))) - pos = MAX_RATIO_LVL - pos; - - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.cur.progressbar", pos, pos); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->progressbar, rtl); } -static Eina_Bool -_elm_progressbar_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - if (sd->horizontal) - eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "horizontal"); - else eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "vertical"); - - if (!ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->theme(obj)) - return EINA_FALSE; - - if (sd->pulse) - elm_layout_signal_emit(obj, "elm,state,pulse", "elm"); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + if (wd->horizontal) + _elm_theme_object_set(obj, wd->progressbar, "progressbar", "horizontal", elm_widget_style_get(obj)); else - elm_layout_signal_emit(obj, "elm,state,fraction", "elm"); + _elm_theme_object_set(obj, wd->progressbar, "progressbar", "vertical", elm_widget_style_get(obj)); - if (sd->pulse_state) - elm_layout_signal_emit(obj, "elm,state,pulse,start", "elm"); + if (wd->icon) + { + edje_object_part_swallow(wd->progressbar, "elm.swallow.content", wd->icon); + edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm"); + } + if (wd->label) + { + edje_object_part_text_escaped_set(wd->progressbar, "elm.text", wd->label); + edje_object_signal_emit(wd->progressbar, "elm,state,text,visible", "elm"); + } + if (wd->pulse) + edje_object_signal_emit(wd->progressbar, "elm,state,pulse", "elm"); + else + edje_object_signal_emit(wd->progressbar, "elm,state,fraction", "elm"); + if (wd->pulse_state) + edje_object_signal_emit(wd->progressbar, "elm,state,pulse,start", "elm"); - if ((sd->units) && (!sd->pulse)) - elm_layout_signal_emit(obj, "elm,state,units,visible", "elm"); + if ((wd->units) && (!wd->pulse)) + edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm"); - if (sd->horizontal) - evas_object_size_hint_min_set - (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get(), 1); + if (wd->horizontal) + evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1); else - evas_object_size_hint_min_set - (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get()); + evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale); - if (sd->inverted) - elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm"); + edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer); + + if (wd->inverted) + edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm"); _units_set(obj); + edje_object_message_signal_process(wd->progressbar); + edje_object_scale_set(wd->progressbar, elm_widget_scale_get(obj) * _elm_config->scale); _val_set(obj); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); - - return EINA_TRUE; + _sizing_eval(obj); } static void -_elm_progressbar_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; - - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); + if (!wd) return; + edje_object_size_min_restricted_calc(wd->progressbar, &minw, &minh, minw, minh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, -1, -1); } static void -_elm_progressbar_smart_add(Evas_Object *obj) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Progressbar_Smart_Data); - - ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->base.add(obj); - - priv->horizontal = EINA_TRUE; - priv->inverted = EINA_FALSE; - priv->pulse = EINA_FALSE; - priv->pulse_state = EINA_FALSE; - priv->units = eina_stringshare_add("%.0f %%"); - priv->val = MIN_RATIO_LVL; - - elm_layout_theme_set - (obj, "progressbar", "horizontal", elm_widget_style_get(obj)); - - priv->spacer = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_color_set(priv->spacer, 0, 0, 0, 0); - evas_object_pass_events_set(priv->spacer, EINA_TRUE); - - elm_layout_content_set(obj, "elm.swallow.bar", priv->spacer); - - _units_set(obj); - _val_set(obj); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (obj != wd->icon) return; + _sizing_eval(data); +} - elm_widget_can_focus_set(obj, EINA_FALSE); +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->icon) + { + edje_object_signal_emit(wd->progressbar, "elm,state,icon,hidden", "elm"); + evas_object_event_callback_del_full + (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + wd->icon = NULL; + edje_object_message_signal_process(wd->progressbar); + _sizing_eval(obj); + } +} - elm_layout_sizing_eval(obj); +static void +_val_set(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Eina_Bool rtl; + double pos; + if (!wd) return; + pos = wd->val; + rtl = elm_widget_mirrored_get(obj); + if ((!rtl && wd->inverted) || (rtl && + ((!wd->horizontal && wd->inverted) || + (wd->horizontal && !wd->inverted)))) pos = MAX_RATIO_LVL - pos; + edje_object_part_drag_value_set(wd->progressbar, "elm.cur.progressbar", pos, pos); } static void -_elm_progressbar_smart_del(Evas_Object *obj) +_units_set(Evas_Object *obj) { - ELM_PROGRESSBAR_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->units) + { + char buf[1024]; + snprintf(buf, sizeof(buf), wd->units, 100 * wd->val); + edje_object_part_text_escaped_set(wd->progressbar, "elm.text.status", buf); + } + else + edje_object_part_text_escaped_set(wd->progressbar, "elm.text.status", NULL); +} - if (sd->units) eina_stringshare_del(sd->units); +static void +_elm_progressbar_label_set(Evas_Object *obj, const char *item, const char *label) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return; + if (!wd) return; + eina_stringshare_replace(&wd->label, label); + if (label) + { + edje_object_signal_emit(wd->progressbar, "elm,state,text,visible", "elm"); + edje_object_message_signal_process(wd->progressbar); + } + else + { + edje_object_signal_emit(wd->progressbar, "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(wd->progressbar); + } + edje_object_part_text_escaped_set(wd->progressbar, "elm.text", label); + _sizing_eval(obj); +} - ELM_WIDGET_CLASS(_elm_progressbar_parent_sc)->base.del(obj); +static const char * +_elm_progressbar_label_get(const Evas_Object *obj, const char *item) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if (!wd) return NULL; + return wd->label; } static void -_elm_progressbar_smart_set_user(Elm_Layout_Smart_Class *sc) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_progressbar_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_progressbar_smart_del; - - ELM_WIDGET_CLASS(sc)->theme = _elm_progressbar_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + if (part && strcmp(part, "icon")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->icon == content) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->progressbar, "elm.swallow.content", content); + edje_object_signal_emit(wd->progressbar, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->progressbar); + } + _sizing_eval(obj); +} - sc->sizing_eval = _elm_progressbar_smart_sizing_eval; +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->icon; +} - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + Evas_Object *icon; + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->icon) return NULL; + icon = wd->icon; + elm_widget_sub_object_del(obj, wd->icon); + evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->progressbar, wd->icon); + wd->icon = NULL; + return icon; } + EAPI Evas_Object * elm_progressbar_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_progressbar_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "progressbar"); + elm_widget_type_set(obj, "progressbar"); + elm_widget_sub_object_add(parent, obj); + 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, EINA_FALSE); + elm_widget_text_set_hook_set(obj, _elm_progressbar_label_set); + elm_widget_text_get_hook_set(obj, _elm_progressbar_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->horizontal = EINA_TRUE; + wd->inverted = EINA_FALSE; + wd->pulse = EINA_FALSE; + wd->pulse_state = EINA_FALSE; + wd->units = eina_stringshare_add("%.0f %%"); + wd->val = MIN_RATIO_LVL; + + wd->progressbar = edje_object_add(e); + _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); + evas_object_color_set(wd->spacer, 0, 0, 0, 0); + evas_object_pass_events_set(wd->spacer, EINA_TRUE); + elm_widget_sub_object_add(obj, wd->spacer); + edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + _units_set(obj); + _val_set(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_progressbar_pulse_set(Evas_Object *obj, - Eina_Bool pulse) +elm_progressbar_pulse_set(Evas_Object *obj, Eina_Bool pulse) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; pulse = !!pulse; - if (sd->pulse == pulse) return; - - sd->pulse = pulse; - - _elm_progressbar_smart_theme(obj); + if (wd->pulse == pulse) return; + wd->pulse = pulse; + _theme_hook(obj); } EAPI Eina_Bool elm_progressbar_pulse_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->pulse; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->pulse; } EAPI void -elm_progressbar_pulse(Evas_Object *obj, - Eina_Bool state) +elm_progressbar_pulse(Evas_Object *obj, Eina_Bool state) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; state = !!state; - if ((!sd->pulse) && (sd->pulse_state == state)) return; - - sd->pulse_state = state; - - if (sd->pulse_state) - elm_layout_signal_emit(obj, "elm,state,pulse,start", "elm"); + if ((!wd->pulse) && (wd->pulse_state == state)) return; + wd->pulse_state = state; + if (wd->pulse_state) + edje_object_signal_emit(wd->progressbar, "elm,state,pulse,start", "elm"); else - elm_layout_signal_emit(obj, "elm,state,pulse,stop", "elm"); + edje_object_signal_emit(wd->progressbar, "elm,state,pulse,stop", "elm"); } EAPI void -elm_progressbar_value_set(Evas_Object *obj, - double val) +elm_progressbar_value_set(Evas_Object *obj, double val) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - if (sd->val == val) return; - - sd->val = val; - if (sd->val < MIN_RATIO_LVL) sd->val = MIN_RATIO_LVL; - if (sd->val > MAX_RATIO_LVL) sd->val = MAX_RATIO_LVL; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->val == val) return; + wd->val = val; + if (wd->val < MIN_RATIO_LVL) wd->val = MIN_RATIO_LVL; + if (wd->val > MAX_RATIO_LVL) wd->val = MAX_RATIO_LVL; _val_set(obj); _units_set(obj); } @@ -299,117 +352,102 @@ elm_progressbar_value_set(Evas_Object *obj, EAPI double elm_progressbar_value_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) 0.0; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->val; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->val; } EAPI void -elm_progressbar_span_size_set(Evas_Object *obj, - Evas_Coord size) +elm_progressbar_span_size_set(Evas_Object *obj, Evas_Coord size) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - if (sd->size == size) return; - - sd->size = size; - - if (sd->horizontal) - evas_object_size_hint_min_set - (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get(), 1); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->size == size) return; + wd->size = size; + if (wd->horizontal) + evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1); else - evas_object_size_hint_min_set - (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get()); - - elm_layout_sizing_eval(obj); + evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale); + edje_object_part_swallow(wd->progressbar, "elm.swallow.bar", wd->spacer); + _sizing_eval(obj); } EAPI Evas_Coord elm_progressbar_span_size_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) 0; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->size; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->size; } EAPI void -elm_progressbar_unit_format_set(Evas_Object *obj, - const char *units) +elm_progressbar_unit_format_set(Evas_Object *obj, const char *units) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - eina_stringshare_replace(&sd->units, units); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + eina_stringshare_replace(&wd->units, units); if (units) { - elm_layout_signal_emit(obj, "elm,state,units,visible", "elm"); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + edje_object_signal_emit(wd->progressbar, "elm,state,units,visible", "elm"); + edje_object_message_signal_process(wd->progressbar); } else { - elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm"); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + edje_object_signal_emit(wd->progressbar, "elm,state,units,hidden", "elm"); + edje_object_message_signal_process(wd->progressbar); } - _units_set(obj); - elm_layout_sizing_eval(obj); + _sizing_eval(obj); } EAPI const char * elm_progressbar_unit_format_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) NULL; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->units; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->units; } EAPI void -elm_progressbar_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_progressbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; horizontal = !!horizontal; - if (sd->horizontal == horizontal) return; - - sd->horizontal = horizontal; - _elm_progressbar_smart_theme(obj); + if (wd->horizontal == horizontal) return; + wd->horizontal = horizontal; + _theme_hook(obj); } EAPI Eina_Bool elm_progressbar_horizontal_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } EAPI void -elm_progressbar_inverted_set(Evas_Object *obj, - Eina_Bool inverted) +elm_progressbar_inverted_set(Evas_Object *obj, Eina_Bool inverted) { - ELM_PROGRESSBAR_CHECK(obj); - ELM_PROGRESSBAR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; inverted = !!inverted; - if (sd->inverted == inverted) return; - - sd->inverted = inverted; - if (sd->inverted) - elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm"); + if (wd->inverted == inverted) return; + wd->inverted = inverted; + if (wd->inverted) + edje_object_signal_emit(wd->progressbar, "elm,state,inverted,on", "elm"); else - elm_layout_signal_emit(obj, "elm,state,inverted,off", "elm"); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - + edje_object_signal_emit(wd->progressbar, "elm,state,inverted,off", "elm"); + edje_object_message_signal_process(wd->progressbar); _val_set(obj); _units_set(obj); } @@ -417,8 +455,8 @@ elm_progressbar_inverted_set(Evas_Object *obj, EAPI Eina_Bool elm_progressbar_inverted_get(const Evas_Object *obj) { - ELM_PROGRESSBAR_CHECK(obj) EINA_FALSE; - ELM_PROGRESSBAR_DATA_GET(obj, sd); - - return sd->inverted; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->inverted; } diff --git a/src/lib/elm_progressbar.h b/src/lib/elm_progressbar.h index 38af4e086..5b08d724e 100644 --- a/src/lib/elm_progressbar.h +++ b/src/lib/elm_progressbar.h @@ -27,11 +27,7 @@ * Applications can query the progress bar for its value with * elm_progressbar_value_get(). * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for progress bar objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * Available widget styles for progress bars: * - @c "default" * - @c "wheel" (simple style, no text, no progression, only * "pulse" effect is available) diff --git a/src/lib/elm_radio.c b/src/lib/elm_radio.c index 6d477bdbd..0f6c0f633 100644 --- a/src/lib/elm_radio.c +++ b/src/lib/elm_radio.c @@ -1,410 +1,502 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char RADIO_SMART_NAME[] = "elm_radio"; - -typedef struct _Elm_Radio_Smart_Data Elm_Radio_Smart_Data; -typedef struct _Group Group; +typedef struct _Widget_Data Widget_Data; +typedef struct _Group Group; struct _Group { - int value; - int *valuep; + int value; + int *valuep; Eina_List *radios; }; -struct _Elm_Radio_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; + Evas_Object *radio; + Evas_Object *icon; + int value; + const char *label; + Eina_Bool state; + Group *group; +}; - int value; - Eina_Bool state; +static const char *widtype = NULL; +static void _state_set(Evas_Object *obj, Eina_Bool state); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _signal_radio_on(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _activate(Evas_Object *obj); +static void _activate_hook(Evas_Object *obj); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); - Group *group; +static const char SIG_CHANGED[] = "changed"; +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHANGED, ""}, + {NULL, NULL} }; -#define ELM_RADIO_DATA_GET(o, sd) \ - Elm_Radio_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_RADIO_DATA_GET_OR_RETURN(o, ptr) \ - ELM_RADIO_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_RADIO_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_RADIO_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_RADIO_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), RADIO_SMART_NAME, __func__)) \ - return - -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +static Eina_Bool +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - {"icon", "elm.swallow.icon"}, - {NULL, NULL} -}; + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (elm_widget_disabled_get(obj)) return EINA_FALSE; -static const Elm_Layout_Part_Alias_Description _text_aliases[] = + if ((strcmp(ev->keyname, "Return")) && + (strcmp(ev->keyname, "KP_Enter")) && + (strcmp(ev->keyname, "space"))) + return EINA_FALSE; + _activate(obj); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; +} + +static void +_del_hook(Evas_Object *obj) { - {"default", "elm.text"}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->label) eina_stringshare_del(wd->label); + wd->group->radios = eina_list_remove(wd->group->radios, obj); + if (!wd->group->radios) free(wd->group); + wd->group = NULL; + free(wd); +} -static const char SIG_CHANGED[] = "changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHANGED, ""}, - {NULL, NULL} -}; +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->radio, "elm,action,focus", "elm"); + evas_object_focus_set(wd->radio, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->radio, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->radio, EINA_FALSE); + } +} -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (RADIO_SMART_NAME, _elm_radio, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->radio, rtl); +} static void -_state_set(Evas_Object *obj, Eina_Bool state) +_theme_hook(Evas_Object *obj) { - ELM_RADIO_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->radio, "radio", "base", elm_widget_style_get(obj)); + if (wd->icon) + edje_object_signal_emit(wd->radio, "elm,state,icon,visible", "elm"); + else + edje_object_signal_emit(wd->radio, "elm,state,icon,hidden", "elm"); + if (wd->state) + edje_object_signal_emit(wd->radio, "elm,state,radio,on", "elm"); + else + edje_object_signal_emit(wd->radio, "elm,state,radio,off", "elm"); + if (wd->label) + edje_object_signal_emit(wd->radio, "elm,state,text,visible", "elm"); + else + edje_object_signal_emit(wd->radio, "elm,state,text,hidden", "elm"); + edje_object_part_text_escaped_set(wd->radio, "elm.text", wd->label); + if (elm_widget_disabled_get(obj)) + { + edje_object_signal_emit(wd->radio, "elm,state,disabled", "elm"); + if (wd->state) _state_set(obj, 0); + } + edje_object_message_signal_process(wd->radio); + edje_object_scale_set(wd->radio, elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); +} - if ((state != sd->state) && (!elm_widget_disabled_get(obj))) +static void +_disable_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_disabled_get(obj)) { - sd->state = state; - if (sd->state) - elm_layout_signal_emit(obj, "elm,state,radio,on", "elm"); + edje_object_signal_emit(wd->radio, "elm,state,disabled", "elm"); + if (wd->state) _state_set(obj, 0); + } + else + edje_object_signal_emit(wd->radio, "elm,state,enabled", "elm"); +} + +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; + if (!wd) return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->radio, &minw, &minh, minw, minh); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); +} + +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if (obj != wd->icon) return; + _sizing_eval(data); +} + +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->icon) + { + edje_object_signal_emit(wd->radio, "elm,state,icon,hidden", "elm"); + evas_object_event_callback_del_full + (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + wd->icon = NULL; + _sizing_eval(obj); + } +} + +static void +_state_set(Evas_Object *obj, Eina_Bool state) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if ((state != wd->state) && (!elm_widget_disabled_get(obj))) + { + wd->state = state; + if (wd->state) + edje_object_signal_emit(wd->radio, "elm,state,radio,on", "elm"); else - elm_layout_signal_emit(obj, "elm,state,radio,off", "elm"); + edje_object_signal_emit(wd->radio, "elm,state,radio,off", "elm"); } } static void -_state_set_all(Elm_Radio_Smart_Data *sd) +_state_set_all(Widget_Data *wd) { const Eina_List *l; - Eina_Bool disabled = EINA_FALSE; Evas_Object *child, *selected = NULL; - - EINA_LIST_FOREACH (sd->group->radios, l, child) + Eina_Bool disabled = EINA_FALSE; + EINA_LIST_FOREACH(wd->group->radios, l, child) { - ELM_RADIO_DATA_GET(child, sdc); - - if (sdc->state) selected = child; - if (sdc->value == sd->group->value) + Widget_Data *wd2 = elm_widget_data_get(child); + if (wd2->state) selected = child; + if (wd2->value == wd->group->value) { - _state_set(child, EINA_TRUE); - if (!sdc->state) disabled = EINA_TRUE; + _state_set(child, 1); + if (!wd2->state) disabled = EINA_TRUE; } - else _state_set(child, EINA_FALSE); + else _state_set(child, 0); } - if ((disabled) && (selected)) _state_set(selected, 1); } static void _activate(Evas_Object *obj) { - ELM_RADIO_DATA_GET(obj, sd); - - if (sd->group->value == sd->value) return; - + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->group->value == wd->value) return; if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) || (_elm_access_2nd_click_timeout(obj))) { - sd->group->value = sd->value; - if (sd->group->valuep) *(sd->group->valuep) = sd->group->value; - - _state_set_all(sd); - + wd->group->value = wd->value; + if (wd->group->valuep) *(wd->group->valuep) = wd->group->value; + _state_set_all(wd); if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) _elm_access_say(E_("State: On")); evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); } } -static Eina_Bool -_elm_radio_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +static void +_activate_hook(Evas_Object *obj) { - Evas_Event_Key_Down *ev; - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; - ev = event_info; - - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - - if ((strcmp(ev->keyname, "Return")) && - (strcmp(ev->keyname, "KP_Enter")) && - (strcmp(ev->keyname, "space"))) - return EINA_FALSE; - _activate(obj); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - - return EINA_TRUE; } -static Eina_Bool -_elm_radio_smart_theme(Evas_Object *obj) -{ - ELM_RADIO_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_radio_parent_sc)->theme(obj)) return EINA_FALSE; - - if (sd->state) elm_layout_signal_emit(obj, "elm,state,radio,on", "elm"); - else elm_layout_signal_emit(obj, "elm,state,radio,off", "elm"); - - if (elm_widget_disabled_get(obj) && sd->state) _state_set(obj, EINA_FALSE); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - elm_layout_sizing_eval(obj); - - return EINA_TRUE; -} - -static Eina_Bool -_elm_radio_smart_disable(Evas_Object *obj) +static void +_signal_radio_on(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_RADIO_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_radio_parent_sc)->disable(obj)) return EINA_FALSE; - - if (elm_widget_disabled_get(obj) && sd->state) _state_set(obj, EINA_FALSE); - - return EINA_TRUE; + _activate(data); } static void -_elm_radio_smart_sizing_eval(Evas_Object *obj) +_elm_radio_label_set(Evas_Object *obj, const char *item, const char *label) { - Evas_Coord minw = -1, minh = -1; - - ELM_RADIO_DATA_GET(obj, sd); - - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, -1, -1); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return; + if (!wd) return; + eina_stringshare_replace(&wd->label, label); + if (label) + { + edje_object_signal_emit(wd->radio, "elm,state,text,visible", "elm"); + edje_object_message_signal_process(wd->radio); + } + else + { + edje_object_signal_emit(wd->radio, "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(wd->radio); + } + edje_object_part_text_escaped_set(wd->radio, "elm.text", label); + _sizing_eval(obj); } -static void -_radio_on_cb(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +static const char * +_elm_radio_label_get(const Evas_Object *obj, const char *item) { - _activate(data); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (item && strcmp(item, "default")) return NULL; + if (!wd) return NULL; + return wd->label; } static char * -_access_info_cb(void *data __UNUSED__, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +_access_info_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) { const char *txt = elm_widget_access_info_get(obj); - - if (!txt) txt = elm_layout_text_get(obj, NULL); + if (!txt) txt = _elm_radio_label_get(obj, NULL); if (txt) return strdup(txt); - return NULL; } static char * -_access_state_cb(void *data __UNUSED__, - Evas_Object *obj, - Elm_Widget_Item *item __UNUSED__) +_access_state_cb(void *data __UNUSED__, Evas_Object *obj, Elm_Widget_Item *item __UNUSED__) { - ELM_RADIO_DATA_GET(obj, sd); - - if (elm_widget_disabled_get(obj)) return strdup(E_("State: Disabled")); - if (sd->state) return strdup(E_("State: On")); - + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (elm_widget_disabled_get(obj)) + return strdup(E_("State: Disabled")); + if (wd->state) + return strdup(E_("State: On")); return strdup(E_("State: Off")); } static void -_elm_radio_smart_add(Evas_Object *obj) +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Radio_Smart_Data); - - ELM_WIDGET_CLASS(_elm_radio_parent_sc)->base.add(obj); - - elm_layout_theme_set(obj, "radio", "base", elm_widget_style_get(obj)); - - elm_layout_signal_callback_add - (obj, "elm,action,radio,on", "", _radio_on_cb, obj); - elm_layout_signal_callback_add - (obj, "elm,action,radio,toggle", "", _radio_on_cb, obj); - - priv->group = calloc(1, sizeof(Group)); - priv->group->radios = eina_list_append(priv->group->radios, obj); - priv->state = EINA_FALSE; - - elm_widget_can_focus_set(obj, EINA_TRUE); - - elm_layout_sizing_eval(obj); - - _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj); - _elm_access_text_set - (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Radio")); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, obj); - _elm_access_callback_set - (_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd; + + if (part && strcmp(part, "icon")) return; + wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->icon == content) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->radio, "elm.swallow.content", content); + edje_object_signal_emit(wd->radio, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->radio); + } + _sizing_eval(obj); } -static void -_elm_radio_smart_del(Evas_Object *obj) +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) { - ELM_RADIO_DATA_GET(obj, sd); - - sd->group->radios = eina_list_remove(sd->group->radios, obj); - if (!sd->group->radios) free(sd->group); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; - ELM_WIDGET_CLASS(_elm_radio_parent_sc)->base.del(obj); + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->icon; } -static void -_elm_radio_smart_set_user(Elm_Layout_Smart_Class *sc) +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_radio_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_radio_smart_del; - - ELM_WIDGET_CLASS(sc)->disable = _elm_radio_smart_disable; - ELM_WIDGET_CLASS(sc)->theme = _elm_radio_smart_theme; - ELM_WIDGET_CLASS(sc)->event = _elm_radio_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_radio_smart_sizing_eval; - - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + Evas_Object *icon; + if (part && strcmp(part, "icon")) return NULL; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->icon) return NULL; + icon = wd->icon; + elm_widget_sub_object_del(obj, wd->icon); + evas_object_event_callback_del_full(wd->icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->radio, wd->icon); + wd->icon = NULL; + return icon; } EAPI Evas_Object * elm_radio_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_radio_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "radio"); + elm_widget_type_set(obj, "radio"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_activate_hook_set(obj, _activate_hook); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_text_set_hook_set(obj, _elm_radio_label_set); + elm_widget_text_get_hook_set(obj, _elm_radio_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->radio = edje_object_add(e); + _elm_theme_object_set(obj, wd->radio, "radio", "base", "default"); + edje_object_signal_callback_add(wd->radio, "elm,action,radio,on", "", _signal_radio_on, obj); + edje_object_signal_callback_add(wd->radio, "elm,action,radio,toggle", "", _signal_radio_on, obj); + elm_widget_resize_object_set(obj, wd->radio); + + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + + wd->group = calloc(1, sizeof(Group)); + wd->group->radios = eina_list_append(wd->group->radios, obj); + wd->state = 0; + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + + // TODO: convert Elementary to subclassing of Evas_Smart_Class + // TODO: and save some bytes, making descriptions per-class and not instance! + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _elm_access_object_register(obj, wd->radio); + _elm_access_text_set(_elm_access_object_get(obj), + ELM_ACCESS_TYPE, E_("Radio")); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_INFO, _access_info_cb, obj); + _elm_access_callback_set(_elm_access_object_get(obj), + ELM_ACCESS_STATE, _access_state_cb, obj); return obj; } EAPI void -elm_radio_group_add(Evas_Object *obj, - Evas_Object *group) +elm_radio_group_add(Evas_Object *obj, Evas_Object *group) { - ELM_RADIO_CHECK(obj); - ELM_RADIO_DATA_GET(obj, sd); - ELM_RADIO_DATA_GET(group, sdg); - - if (!sdg) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + Widget_Data *wd2 = elm_widget_data_get(group); + if (!wd) return; + if (!wd2) { - if (eina_list_count(sd->group->radios) == 1) return; - sd->group->radios = eina_list_remove(sd->group->radios, obj); - sd->group = calloc(1, sizeof(Group)); - sd->group->radios = eina_list_append(sd->group->radios, obj); + if (eina_list_count(wd->group->radios) == 1) + return; + wd->group->radios = eina_list_remove(wd->group->radios, obj); + wd->group = calloc(1, sizeof(Group)); + wd->group->radios = eina_list_append(wd->group->radios, obj); } - else if (sd->group == sdg->group) - return; + else if (wd->group == wd2->group) return; else { - sd->group->radios = eina_list_remove(sd->group->radios, obj); - if (!sd->group->radios) free(sd->group); - sd->group = sdg->group; - sd->group->radios = eina_list_append(sd->group->radios, obj); + wd->group->radios = eina_list_remove(wd->group->radios, obj); + if (!wd->group->radios) free(wd->group); + wd->group = wd2->group; + wd->group->radios = eina_list_append(wd->group->radios, obj); } - if (sd->value == sd->group->value) _state_set(obj, EINA_TRUE); - else _state_set(obj, EINA_FALSE); + if (wd->value == wd->group->value) _state_set(obj, 1); + else _state_set(obj, 0); } EAPI void -elm_radio_state_value_set(Evas_Object *obj, - int value) +elm_radio_state_value_set(Evas_Object *obj, int value) { - ELM_RADIO_CHECK(obj); - ELM_RADIO_DATA_GET(obj, sd); - - sd->value = value; - if (sd->value == sd->group->value) _state_set(obj, EINA_TRUE); - else _state_set(obj, EINA_FALSE); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->value = value; + if (wd->value == wd->group->value) _state_set(obj, 1); + else _state_set(obj, 0); } EAPI int elm_radio_state_value_get(const Evas_Object *obj) { - ELM_RADIO_CHECK(obj) 0; - ELM_RADIO_DATA_GET(obj, sd); - - return sd->value; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->value; } EAPI void -elm_radio_value_set(Evas_Object *obj, - int value) +elm_radio_value_set(Evas_Object *obj, int value) { - ELM_RADIO_CHECK(obj); - ELM_RADIO_DATA_GET(obj, sd); - - if (value == sd->group->value) return; - sd->group->value = value; - if (sd->group->valuep) *(sd->group->valuep) = sd->group->value; - _state_set_all(sd); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (value == wd->group->value) return; + wd->group->value = value; + if (wd->group->valuep) *(wd->group->valuep) = wd->group->value; + _state_set_all(wd); } EAPI int elm_radio_value_get(const Evas_Object *obj) { - ELM_RADIO_CHECK(obj) 0; - ELM_RADIO_DATA_GET(obj, sd); - - return sd->group->value; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->group->value; } EAPI void -elm_radio_value_pointer_set(Evas_Object *obj, - int *valuep) +elm_radio_value_pointer_set(Evas_Object *obj, int *valuep) { - ELM_RADIO_CHECK(obj); - ELM_RADIO_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (valuep) { - sd->group->valuep = valuep; - if (*(sd->group->valuep) != sd->group->value) + wd->group->valuep = valuep; + if (*(wd->group->valuep) != wd->group->value) { - sd->group->value = *(sd->group->valuep); - _state_set_all(sd); + wd->group->value = *(wd->group->valuep); + _state_set_all(wd); } } - else sd->group->valuep = NULL; + else + { + wd->group->valuep = NULL; + } } EAPI Evas_Object * @@ -412,16 +504,17 @@ elm_radio_selected_object_get(Evas_Object *obj) { Eina_List *l; Evas_Object *child; + Widget_Data *wd2; - ELM_RADIO_CHECK(obj) NULL; - ELM_RADIO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; - EINA_LIST_FOREACH (sd->group->radios, l, child) + EINA_LIST_FOREACH(wd->group->radios, l, child) { - ELM_RADIO_DATA_GET(child, sdc); - - if (sdc->value == sd->group->value) return child; + wd2 = elm_widget_data_get(child); + if (wd2->value == wd->group->value) + return child; } - return NULL; } diff --git a/src/lib/elm_radio.h b/src/lib/elm_radio.h index 559761d37..388e720a2 100644 --- a/src/lib/elm_radio.h +++ b/src/lib/elm_radio.h @@ -30,11 +30,7 @@ * The radio objects will modify this directly. That implies the pointer must * point to valid memory for as long as the radio objects exist. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for radio objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: + * Signals that you can add callbacks for are: * @li changed - This is called whenever the user changes the state of one of * the radio objects within the group of radio objects that work together. * diff --git a/src/lib/elm_segment_control.c b/src/lib/elm_segment_control.c index b049ae35a..6ff6411ff 100644 --- a/src/lib/elm_segment_control.c +++ b/src/lib/elm_segment_control.c @@ -1,298 +1,138 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char SEGMENT_CONTROL_SMART_NAME[] = "elm_segment_control"; +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Segment_Item Elm_Segment_Item; -typedef struct _Elm_Segment_Control_Smart_Data Elm_Segment_Control_Smart_Data; -typedef struct _Elm_Segment_Item Elm_Segment_Item; - -struct _Elm_Segment_Control_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Eina_List *items; - Elm_Segment_Item *selected_item; - - int item_width; + Evas_Object *obj; + Evas_Object *base; + Eina_List *seg_items; + int item_count; + Elm_Segment_Item *selected_item; + int item_width; }; struct _Elm_Segment_Item { ELM_WIDGET_ITEM; - Evas_Object *icon; - const char *label; - int seg_index; + const char *label; + int seg_index; }; -#define ELM_SEGMENT_CONTROL_DATA_GET(o, sd) \ - Elm_Segment_Control_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_SEGMENT_CONTROL_DATA_GET_OR_RETURN(o, ptr) \ - ELM_SEGMENT_CONTROL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_SEGMENT_CONTROL_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_SEGMENT_CONTROL_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_SEGMENT_CONTROL_CHECK(obj) \ - if (!obj || !elm_widget_type_check \ - ((obj), SEGMENT_CONTROL_SMART_NAME, __func__)) \ - return - -#define ELM_SEGMENT_CONTROL_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_SEGMENT_CONTROL_CHECK(it->base.widget); - -#define ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_SEGMENT_CONTROL_CHECK(it->base.widget) __VA_ARGS__; +static const char *widtype = NULL; +static void _sizing_eval(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _item_free(Elm_Segment_Item *it); +static void _segment_off(Elm_Segment_Item *it); +static void _segment_on(Elm_Segment_Item *it); +static void _position_items(Widget_Data *wd); +static void _on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj + __UNUSED__, void *event_info __UNUSED__); +static void _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj + __UNUSED__, void *event_info __UNUSED__); +static void _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj + __UNUSED__, void *event_info __UNUSED__); +static void _swallow_item_objects(Elm_Segment_Item *it); +static void _update_list(Widget_Data *wd); +static Elm_Segment_Item * _item_find(const Evas_Object *obj, int index); +static Elm_Segment_Item* _item_new(Evas_Object *obj, Evas_Object *icon, + const char *label); static const char SIG_CHANGED[] = "changed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { + +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {NULL, NULL} }; -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (SEGMENT_CONTROL_SMART_NAME, _elm_segment_control, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static void -_elm_segment_control_smart_sizing_eval(Evas_Object *obj) +_sizing_eval(Evas_Object *obj) { + Widget_Data *wd; Evas_Coord minw = -1, minh = -1; Evas_Coord w, h; - int item_count; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return; - item_count = eina_list_count(sd->items); - - elm_coords_finger_size_adjust(item_count, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); - elm_coords_finger_size_adjust(item_count, &minw, 1, &minh); + elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh); + elm_coords_finger_size_adjust(wd->item_count, &minw, 1, &minh); evas_object_size_hint_min_get(obj, &w, &h); - if (w > minw) minw = w; if (h > minh) minh = h; - evas_object_size_hint_min_set(obj, minw, minh); } static void -_item_free(Elm_Segment_Item *it) -{ - Elm_Segment_Control_Smart_Data *sd; - - if (!it) return; - - sd = elm_widget_item_data_get(it); - if (!sd) return; - - if (sd->selected_item == it) sd->selected_item = NULL; - if (sd->items) sd->items = eina_list_remove(sd->items, it); - - if (it->icon) evas_object_del(it->icon); - if (it->label) eina_stringshare_del(it->label); -} - -static void -_position_items(Elm_Segment_Control_Smart_Data *sd) +_del_hook(Evas_Object *obj) { - Eina_List *l; - Eina_Bool rtl; - int item_count; Elm_Segment_Item *it; - int bx, by, bw, bh, pos; - - item_count = eina_list_count(sd->items); - if (item_count <= 0) return; - - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, &bx, &by, &bw, &bh); - sd->item_width = bw / item_count; - rtl = elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj); + Widget_Data *wd; - if (rtl) pos = bx + bw - sd->item_width; - else pos = bx; + wd = elm_widget_data_get(obj); + if (!wd) return; - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FREE(wd->seg_items, it) { - evas_object_move(VIEW(it), pos, by); - evas_object_resize(VIEW(it), sd->item_width, bh); - if (rtl) pos -= sd->item_width; - else pos += sd->item_width; - } - - elm_layout_sizing_eval(ELM_WIDGET_DATA(sd)->obj); -} - -static void -_swallow_item_objects(Elm_Segment_Item *it) -{ - if (!it) return; - - if (it->icon) - { - edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon); - edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm"); - } - else edje_object_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm"); - - if (it->label) - { - edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label); - edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm"); + _item_free(it); + elm_widget_item_free(it); } - else - edje_object_signal_emit(VIEW(it), "elm,state,text,hidden", "elm"); - edje_object_message_signal_process(VIEW(it)); + free(wd); } static void -_update_list(Elm_Segment_Control_Smart_Data *sd) -{ - int idx = 0; - Eina_List *l; - Eina_Bool rtl; - int item_count; - Elm_Segment_Item *it; - - _position_items(sd); - - item_count = eina_list_count(sd->items); - - if (item_count == 1) - { - it = eina_list_nth(sd->items, 0); - it->seg_index = 0; - - //Set the segment type - edje_object_signal_emit(VIEW(it), "elm,type,segment,single", "elm"); - - //Set the segment state - if (sd->selected_item == it) - edje_object_signal_emit - (VIEW(it), "elm,state,segment,selected", "elm"); - else - edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm"); - - if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) - edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); - else - edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm"); - - _swallow_item_objects(it); - return; - } - - rtl = elm_widget_mirrored_get(ELM_WIDGET_DATA(sd)->obj); - EINA_LIST_FOREACH (sd->items, l, it) - { - it->seg_index = idx; - - //Set the segment type - if (idx == 0) - { - if (rtl) - edje_object_signal_emit - (VIEW(it), "elm,type,segment,right", "elm"); - else - edje_object_signal_emit - (VIEW(it), "elm,type,segment,left", "elm"); - } - else if (idx == (item_count - 1)) - { - if (rtl) - edje_object_signal_emit - (VIEW(it), "elm,type,segment,left", "elm"); - else - edje_object_signal_emit - (VIEW(it), "elm,type,segment,right", "elm"); - } - else - edje_object_signal_emit(VIEW(it), "elm,type,segment,middle", "elm"); - - //Set the segment state - if (sd->selected_item == it) - edje_object_signal_emit - (VIEW(it), "elm,state,segment,selected", "elm"); - else - edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm"); - - if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) - edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); - else - edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm"); - - _swallow_item_objects(it); - idx++; - } -} - -static Eina_Bool -_elm_segment_control_smart_theme(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { Eina_List *l; Eina_Bool rtl; Elm_Segment_Item *it; + Widget_Data *wd; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->theme(obj)) - return EINA_FALSE; + wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); rtl = elm_widget_mirrored_get(obj); + edje_object_mirrored_set(wd->base, rtl); + + _elm_theme_object_set(obj, wd->base, "segment_control", "base", + elm_widget_style_get(obj)); + edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base) + *_elm_config->scale); - EINA_LIST_FOREACH (sd->items, l, it) + EINA_LIST_FOREACH(wd->seg_items, l, it) { - elm_widget_theme_object_set - (obj, VIEW(it), "segment_control", "item", - elm_widget_style_get(obj)); - edje_object_scale_set(VIEW(it), elm_widget_scale_get(VIEW(it)) * - elm_config_scale_get()); + _elm_theme_object_set(obj, VIEW(it), "segment_control", + "item", elm_widget_style_get(obj)); + edje_object_scale_set(VIEW(it), elm_widget_scale_get(VIEW(it)) + *_elm_config->scale); edje_object_mirrored_set(VIEW(it), rtl); } - _update_list(sd); - - return EINA_TRUE; + _update_list(wd); } -static Eina_Bool -_elm_segment_control_smart_disable(Evas_Object *obj) +static void +_disable_hook(Evas_Object *obj) { - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); - - if (!ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->disable(obj)) - return EINA_FALSE; - - _update_list(sd); + Widget_Data *wd; - return EINA_TRUE; + wd = elm_widget_data_get(obj); + if (!wd) return; + _update_list(wd); } -// TODO: elm_widget_focus_list_next_get supports only Elm_widget list, -// not the Elm_Widget_item. Focus switching within widget not -// supported until it is supported in elm_widget +// TODO: Elm_widget elm_widget_focus_list_next_get supports only Elm_widget list, +// Not the Elm_Widget_item. Focus switching with in widget not supported until +// it is supported in elm_widget #if 0 static void * _elm_list_data_get(const Eina_List *list) @@ -302,88 +142,136 @@ _elm_list_data_get(const Eina_List *list) if (it) return NULL; edje_object_signal_emit(VIEW(it), "elm,state,segment,selected", "elm"); - return VIEW(it); } static Eina_Bool -_elm_segment_control_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, + Evas_Object **next) { - static int count = 0; + static int count=0; + Widget_Data *; const Eina_List *items; - void *(*list_data_get)(const Eina_List *list); + void *(*list_data_get) (const Eina_List *list); - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if ((!wd)) return EINA_FALSE; /* Focus chain */ + /* TODO: Change this to use other chain */ if ((items = elm_widget_focus_custom_chain_get(obj))) list_data_get = eina_list_data_get; else { - items = sd->items; + items = wd->seg_items; list_data_get = _elm_list_data_get; if (!items) return EINA_FALSE; } - return elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next); } - #endif static void +_item_free(Elm_Segment_Item *it) +{ + Widget_Data *wd; + + if (!it) return; + + wd = elm_widget_item_data_get(it); + if (!wd) return; + + if (wd->selected_item == it) wd->selected_item = NULL; + if (wd->seg_items) wd->seg_items = eina_list_remove(wd->seg_items, it); + + if (it->icon) evas_object_del(it->icon); + if (it->label) eina_stringshare_del(it->label); +} + +static void _segment_off(Elm_Segment_Item *it) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; if (!it) return; - sd = elm_widget_item_data_get(it); - if (!sd) return; + wd = elm_widget_item_data_get(it); + if (!wd) return; edje_object_signal_emit(VIEW(it), "elm,state,segment,normal", "elm"); - if (sd->selected_item == it) sd->selected_item = NULL; + if (wd->selected_item == it) wd->selected_item = NULL; } static void _segment_on(Elm_Segment_Item *it) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; if (!it) return; - sd = elm_widget_item_data_get(it); - if (!sd) return; + wd = elm_widget_item_data_get(it); + if (!wd) return; + if (it == wd->selected_item) return; - if (it == sd->selected_item) return; - - if (sd->selected_item) _segment_off(sd->selected_item); + if (wd->selected_item) _segment_off(wd->selected_item); edje_object_signal_emit(VIEW(it), "elm,state,segment,selected", "elm"); - sd->selected_item = it; - evas_object_smart_callback_call(ELM_WIDGET_DATA(sd)->obj, SIG_CHANGED, it); + wd->selected_item = it; + evas_object_smart_callback_call(wd->obj, SIG_CHANGED, it); +} + +static void +_position_items(Widget_Data *wd) +{ + Eina_List *l; + Elm_Segment_Item *it; + Eina_Bool rtl; + int bx, by, bw, bh, pos; + + wd->item_count = eina_list_count(wd->seg_items); + if (wd->item_count <= 0) return; + + evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh); + wd->item_width = bw / wd->item_count; + rtl = elm_widget_mirrored_get(wd->obj); + + if (rtl) + pos = bx + bw - wd->item_width; + else + pos = bx; + + EINA_LIST_FOREACH(wd->seg_items, l, it) + { + evas_object_move(VIEW(it), pos, by); + evas_object_resize(VIEW(it), wd->item_width, bh); + if (rtl) + pos -= wd->item_width; + else + pos += wd->item_width; + } + _sizing_eval(wd->obj); } static void -_on_move_resize(void *data, Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, +_on_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_SEGMENT_CONTROL_DATA_GET(data, sd); + Widget_Data *wd; + + wd = elm_widget_data_get(data); + if (!wd) return; + + _position_items(wd); - _position_items(sd); } static void -_on_mouse_up(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) +_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, + void *event_info) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; Elm_Segment_Item *it; Evas_Event_Mouse_Up *ev; Evas_Coord x, y, w, h; @@ -391,12 +279,12 @@ _on_mouse_up(void *data, it = data; if (!it) return; - sd = elm_widget_item_data_get(it); - if (!sd) return; + wd = elm_widget_item_data_get(it); + if (!wd) return; - if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) return; + if (elm_widget_disabled_get(wd->obj)) return; - if (it == sd->selected_item) return; + if (it == wd->selected_item) return; ev = event_info; evas_object_geometry_get(VIEW(it), &x, &y, &w, &h); @@ -409,52 +297,154 @@ _on_mouse_up(void *data, } static void -_on_mouse_down(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; Elm_Segment_Item *it; it = data; if (!it) return; - sd = elm_widget_item_data_get(it); - if (!sd) return; + wd = elm_widget_item_data_get(it); + if (!wd) return; - if (elm_widget_disabled_get(ELM_WIDGET_DATA(sd)->obj)) return; + if (elm_widget_disabled_get(wd->obj)) return; - if (it == sd->selected_item) return; + if (it == wd->selected_item) return; edje_object_signal_emit(VIEW(it), "elm,state,segment,pressed", "elm"); } +static void +_swallow_item_objects(Elm_Segment_Item *it) +{ + if (!it) return; + + if (it->icon) + { + edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon); + edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm"); + } + else + edje_object_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm"); + + if (it->label) + { + edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label); + edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm"); + } + else + edje_object_signal_emit(VIEW(it), "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(VIEW(it)); +} + +static void +_update_list(Widget_Data *wd) +{ + Eina_List *l; + Elm_Segment_Item *it; + Eina_Bool rtl; + int idx = 0; + + _position_items(wd); + + if (wd->item_count == 1) + { + it = eina_list_nth(wd->seg_items, 0); + it->seg_index = 0; + + //Set the segment type + edje_object_signal_emit(VIEW(it), + "elm,type,segment,single", "elm"); + + //Set the segment state + if (wd->selected_item == it) + edje_object_signal_emit(VIEW(it), + "elm,state,segment,selected", "elm"); + else + edje_object_signal_emit(VIEW(it), + "elm,state,segment,normal", "elm"); + + if (elm_widget_disabled_get(wd->obj)) + edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); + else + edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm"); + + _swallow_item_objects(it); + return; + } + + rtl = elm_widget_mirrored_get(wd->obj); + EINA_LIST_FOREACH(wd->seg_items, l, it) + { + it->seg_index = idx; + + //Set the segment type + if (idx == 0) + { + if (rtl) + edje_object_signal_emit(VIEW(it), + "elm,type,segment,right", "elm"); + else + edje_object_signal_emit(VIEW(it), + "elm,type,segment,left", "elm"); + } + else if (idx == (wd->item_count - 1)) + { + if (rtl) + edje_object_signal_emit(VIEW(it), + "elm,type,segment,left", "elm"); + else + edje_object_signal_emit(VIEW(it), + "elm,type,segment,right", "elm"); + } + else + edje_object_signal_emit(VIEW(it), + "elm,type,segment,middle", "elm"); + + //Set the segment state + if (wd->selected_item == it) + edje_object_signal_emit(VIEW(it), + "elm,state,segment,selected", "elm"); + else + edje_object_signal_emit(VIEW(it), + "elm,state,segment,normal", "elm"); + + if (elm_widget_disabled_get(wd->obj)) + edje_object_signal_emit(VIEW(it), "elm,state,disabled", "elm"); + else + edje_object_signal_emit(VIEW(it), "elm,state,enabled", "elm"); + + _swallow_item_objects(it); + idx++; + } +} + static Elm_Segment_Item * -_item_find(const Evas_Object *obj, - int idx) +_item_find(const Evas_Object *obj, int idx) { + Widget_Data *wd; Elm_Segment_Item *it; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; - it = eina_list_nth(sd->items, idx); + it = eina_list_nth(wd->seg_items, idx); return it; } static void -_item_text_set_hook(Elm_Object_Item *it, - const char *part, - const char *label) +_item_text_set_hook(Elm_Object_Item *it, const char *part, const char *label) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; Elm_Segment_Item *item; if (part && strcmp(part, "default")) return; item = (Elm_Segment_Item *)it; - sd = elm_widget_item_data_get(item); - if (!sd) return; + wd = elm_widget_item_data_get(item); + if (!wd) return; eina_stringshare_replace(&item->label, label); if (item->label) @@ -462,14 +452,12 @@ _item_text_set_hook(Elm_Object_Item *it, else edje_object_signal_emit(VIEW(item), "elm,state,text,hidden", "elm"); edje_object_message_signal_process(VIEW(item)); - //label can be NULL also. edje_object_part_text_escaped_set(VIEW(item), "elm.text", item->label); } static const char * -_item_text_get_hook(const Elm_Object_Item *it, - const char *part) +_item_text_get_hook(const Elm_Object_Item *it, const char *part) { if (part && strcmp(part, "default")) return NULL; return ((Elm_Segment_Item *)it)->label; @@ -481,7 +469,6 @@ _item_content_set_hook(Elm_Object_Item *it, Evas_Object *content) { Elm_Segment_Item *item; - if (part && strcmp(part, "icon")) return; item = (Elm_Segment_Item *)it; @@ -501,42 +488,39 @@ _item_content_set_hook(Elm_Object_Item *it, } static Evas_Object * -_item_content_get_hook(const Elm_Object_Item *it, - const char *part) +_item_content_get_hook(const Elm_Object_Item *it, const char *part) { if (part && strcmp(part, "icon")) return NULL; - return ((Elm_Segment_Item *)it)->icon; } static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it) { - Elm_Segment_Control_Smart_Data *sd; + Widget_Data *wd; Elm_Segment_Item *item = (Elm_Segment_Item *)it; - sd = elm_widget_item_data_get(item); - if (!sd) return EINA_FALSE; + wd = elm_widget_item_data_get(item); + if (!wd) return EINA_FALSE; _item_free(item); - _update_list(sd); + _update_list(wd); return EINA_TRUE; } -static Elm_Segment_Item * -_item_new(Evas_Object *obj, - Evas_Object *icon, - const char *label) +static Elm_Segment_Item* +_item_new(Evas_Object *obj, Evas_Object *icon, const char *label) { Elm_Segment_Item *it; + Widget_Data *wd; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; it = elm_widget_item_new(obj, Elm_Segment_Item); if (!it) return NULL; - - elm_widget_item_data_set(it, sd); + elm_widget_item_data_set(it, wd); elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); elm_widget_item_text_set_hook_set(it, _item_text_set_hook); elm_widget_item_text_get_hook_set(it, _item_text_get_hook); @@ -544,16 +528,17 @@ _item_new(Evas_Object *obj, elm_widget_item_content_get_hook_set(it, _item_content_get_hook); VIEW(it) = edje_object_add(evas_object_evas_get(obj)); - edje_object_scale_set - (VIEW(it), elm_widget_scale_get(VIEW(it)) * elm_config_scale_get()); + edje_object_scale_set(VIEW(it), elm_widget_scale_get(VIEW(it)) + *_elm_config->scale); evas_object_smart_member_add(VIEW(it), obj); - elm_widget_sub_object_add(obj, VIEW(it)); - elm_widget_theme_object_set - (obj, VIEW(it), "segment_control", "item", elm_object_style_get(obj)); - edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(WIDGET(it))); + _elm_theme_object_set(obj, VIEW(it), "segment_control", "item", + elm_object_style_get(obj)); + edje_object_mirrored_set(VIEW(it), + elm_widget_mirrored_get(WIDGET(it))); - if (label) eina_stringshare_replace(&it->label, label); + if (label) + eina_stringshare_replace(&it->label, label); if (it->label) edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm"); else @@ -563,209 +548,172 @@ _item_new(Evas_Object *obj, it->icon = icon; if (it->icon) elm_widget_sub_object_add(VIEW(it), it->icon); - evas_object_event_callback_add - (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down, it); - evas_object_event_callback_add - (VIEW(it), EVAS_CALLBACK_MOUSE_UP, _on_mouse_up, it); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, + _mouse_down, it); + evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP, + _mouse_up, it); evas_object_show(VIEW(it)); return it; } -static void -_elm_segment_control_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Segment_Control_Smart_Data); - - ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->base.add(obj); - - elm_layout_theme_set - (obj, "segment_control", "base", elm_widget_style_get(obj)); - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESIZE, _on_move_resize, obj); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_MOVE, _on_move_resize, obj); -} - -static void -_elm_segment_control_smart_del(Evas_Object *obj) +EAPI Evas_Object * +elm_segment_control_add(Evas_Object *parent) { - Elm_Segment_Item *it; - - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); - - EINA_LIST_FREE (sd->items, it) - { - _item_free(it); - elm_widget_item_free(it); - } - - ELM_WIDGET_CLASS(_elm_segment_control_parent_sc)->base.del(obj); -} + Evas_Object *obj; + Evas *e; + Widget_Data *wd; -static void -_elm_segment_control_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_segment_control_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_segment_control_smart_del; + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - ELM_WIDGET_CLASS(sc)->theme = _elm_segment_control_smart_theme; - ELM_WIDGET_CLASS(sc)->disable = _elm_segment_control_smart_disable; + ELM_SET_WIDTYPE(widtype, "segment_control"); + elm_widget_type_set(obj, "segment_control"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + // TODO: Focus switch support to Elm_widget_Item not supported yet. #if 0 - ELM_WIDGET_CLASS(sc)->focus_next = _elm_segment_control_smart_focus_next; -#else - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + elm_widget_focus_next_hook_set(obj, _focus_next_hook); #endif - sc->sizing_eval = _elm_segment_control_smart_sizing_eval; -} - -EAPI Evas_Object * -elm_segment_control_add(Evas_Object *parent) -{ - Evas *e; - Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; + wd->obj = obj; - obj = evas_object_smart_add(e, _elm_segment_control_smart_class_new()); + wd->base = edje_object_add(e); + edje_object_scale_set(wd->base, elm_widget_scale_get(wd->base) + *_elm_config->scale); + _elm_theme_object_set(obj, wd->base, "segment_control", "base", "default"); + elm_widget_resize_object_set(obj, wd->base); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, + _on_move_resize, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, + _on_move_resize, obj); - elm_layout_sizing_eval(obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } EAPI Elm_Object_Item * -elm_segment_control_item_add(Evas_Object *obj, - Evas_Object *icon, +elm_segment_control_item_add(Evas_Object *obj, Evas_Object *icon, const char *label) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Elm_Segment_Item *it; + Widget_Data *wd; - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + wd = elm_widget_data_get(obj); + if (!wd) return NULL; it = _item_new(obj, icon, label); if (!it) return NULL; - sd->items = eina_list_append(sd->items, it); - _update_list(sd); + wd->seg_items = eina_list_append(wd->seg_items, it); + _update_list(wd); return (Elm_Object_Item *)it; } EAPI Elm_Object_Item * -elm_segment_control_item_insert_at(Evas_Object *obj, - Evas_Object *icon, - const char *label, - int idx) +elm_segment_control_item_insert_at(Evas_Object *obj, Evas_Object *icon, + const char *label, int idx) { + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Elm_Segment_Item *it, *it_rel; + Widget_Data *wd; - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); - + wd = elm_widget_data_get(obj); + if (!wd) return NULL; if (idx < 0) idx = 0; it = _item_new(obj, icon, label); if (!it) return NULL; it_rel = _item_find(obj, idx); - if (it_rel) sd->items = eina_list_prepend_relative(sd->items, it, it_rel); - else sd->items = eina_list_append(sd->items, it); - - _update_list(sd); + if (it_rel) + wd->seg_items = eina_list_prepend_relative(wd->seg_items, it, it_rel); + else + wd->seg_items = eina_list_append(wd->seg_items, it); + _update_list(wd); return (Elm_Object_Item *)it; } EAPI void -elm_segment_control_item_del_at(Evas_Object *obj, - int idx) +elm_segment_control_item_del_at(Evas_Object *obj, int idx) { + ELM_CHECK_WIDTYPE(obj, widtype); Elm_Segment_Item *it; + Widget_Data *wd; - ELM_SEGMENT_CONTROL_CHECK(obj); + wd = elm_widget_data_get(obj); + if (!wd) return; it = _item_find(obj, idx); if (!it) return; - elm_object_item_del((Elm_Object_Item *)it); } -EAPI const char * -elm_segment_control_item_label_get(const Evas_Object *obj, - int idx) +EAPI const char* +elm_segment_control_item_label_get(const Evas_Object *obj, int idx) { - Elm_Segment_Item *it; - - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - - it = _item_find(obj, idx); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Elm_Segment_Item *it = _item_find(obj, idx); if (it) return it->label; - return NULL; } EAPI Evas_Object * -elm_segment_control_item_icon_get(const Evas_Object *obj, - int idx) +elm_segment_control_item_icon_get(const Evas_Object *obj, int idx) { - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; Elm_Segment_Item *it = _item_find(obj, idx); if (it) return it->icon; - return NULL; } EAPI int elm_segment_control_item_count_get(const Evas_Object *obj) { - ELM_SEGMENT_CONTROL_CHECK(obj) 0; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd; + + wd = elm_widget_data_get(obj); + if (!wd) return 0; - return eina_list_count(sd->items); + return eina_list_count(wd->seg_items); } -EAPI Evas_Object * +EAPI Evas_Object* elm_segment_control_item_object_get(const Elm_Object_Item *it) { - ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, NULL); - + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); return VIEW(it); } -EAPI Elm_Object_Item * +EAPI Elm_Object_Item* elm_segment_control_item_selected_get(const Evas_Object *obj) { - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - ELM_SEGMENT_CONTROL_DATA_GET(obj, sd); - - return (Elm_Object_Item *)sd->selected_item; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return (Elm_Object_Item *) wd->selected_item; } EAPI void -elm_segment_control_item_selected_set(Elm_Object_Item *it, - Eina_Bool selected) +elm_segment_control_item_selected_set(Elm_Object_Item *it, Eina_Bool selected) { - Elm_Segment_Control_Smart_Data *sd; + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + Widget_Data *wd; Elm_Segment_Item *item = (Elm_Segment_Item *)it; - ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it); + wd = elm_widget_item_data_get(item); + if (!wd) return; - sd = elm_widget_item_data_get(item); - if (!sd) return; - - if (item == sd->selected_item) + if (item == wd->selected_item) { //already in selected state. if (selected) return; @@ -775,21 +723,20 @@ elm_segment_control_item_selected_set(Elm_Object_Item *it, } else if (selected) _segment_on(item); + + return; } EAPI Elm_Object_Item * -elm_segment_control_item_get(const Evas_Object *obj, - int idx) +elm_segment_control_item_get(const Evas_Object *obj, int idx) { - ELM_SEGMENT_CONTROL_CHECK(obj) NULL; - - return (Elm_Object_Item *)_item_find(obj, idx); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + return (Elm_Object_Item *) _item_find(obj, idx); } EAPI int elm_segment_control_item_index_get(const Elm_Object_Item *it) { - ELM_SEGMENT_CONTROL_ITEM_CHECK_OR_RETURN(it, -1); - + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, -1); return ((Elm_Segment_Item *)it)->seg_index; } diff --git a/src/lib/elm_segment_control.h b/src/lib/elm_segment_control.h index 57f5dc704..02cb7ed47 100644 --- a/src/lib/elm_segment_control.h +++ b/src/lib/elm_segment_control.h @@ -18,12 +18,8 @@ * Only one segment item can be at selected state. A segment item can display * combination of Text and any Evas_Object like Images or other widget. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for segment control objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "changed" - When the user clicks on a segment item which is not + * Smart callbacks one can listen to: + * - "changed" - When the user clicks on a segment item which is not * previously selected and get selected. The event_info parameter is the * segment item pointer. * diff --git a/src/lib/elm_separator.c b/src/lib/elm_separator.c index 5b0c6f181..e852d5e32 100644 --- a/src/lib/elm_separator.c +++ b/src/lib/elm_separator.c @@ -1,144 +1,106 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char SEPARATOR_SMART_NAME[] = "elm_separator"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Separator_Smart_Data Elm_Separator_Smart_Data; - -struct _Elm_Separator_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Eina_Bool horizontal : 1; + Evas_Object *sep; + Eina_Bool horizontal; }; -#define ELM_SEPARATOR_DATA_GET(o, sd) \ - Elm_Separator_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_SEPARATOR_DATA_GET_OR_RETURN(o, ptr) \ - ELM_SEPARATOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_SEPARATOR_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_SEPARATOR_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_SEPARATOR_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), SEPARATOR_SMART_NAME, __func__)) \ - return +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (SEPARATOR_SMART_NAME, _elm_separator, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); - -static Eina_Bool -_elm_separator_smart_theme(Evas_Object *obj) +static void +_del_hook(Evas_Object *obj) { - ELM_SEPARATOR_DATA_GET(obj, sd); - - if (sd->horizontal) - eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "horizontal"); - else - eina_stringshare_replace(&(ELM_LAYOUT_DATA(sd)->group), "vertical"); - - if (!ELM_WIDGET_CLASS(_elm_separator_parent_sc)->theme(obj)) return EINA_FALSE; - - return EINA_TRUE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); } static void -_elm_separator_smart_sizing_eval(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; - - ELM_SEPARATOR_DATA_GET(obj, sd); - - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, maxw, maxh); - evas_object_size_hint_align_set(obj, maxw, maxh); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->sep, rtl); } static void -_elm_separator_smart_add(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Separator_Smart_Data); - - ELM_WIDGET_CLASS(_elm_separator_parent_sc)->base.add(obj); - - priv->horizontal = EINA_FALSE; - - elm_widget_can_focus_set(obj, EINA_FALSE); - - elm_layout_theme_set - (obj, "separator", "vertical", elm_widget_style_get(obj)); - - elm_layout_sizing_eval(obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + if (wd->horizontal) + _elm_theme_object_set(obj, wd->sep, "separator", "horizontal", elm_widget_style_get(obj)); + else + _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); } static void -_elm_separator_smart_set_user(Elm_Layout_Smart_Class *sc) +_sizing_eval(Evas_Object *obj) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_separator_smart_add; - - ELM_WIDGET_CLASS(sc)->theme = _elm_separator_smart_theme; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_separator_smart_sizing_eval; + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + if (!wd) return; + edje_object_size_min_calc(wd->sep, &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); + evas_object_size_hint_align_set(obj, maxw, maxh); } EAPI Evas_Object * elm_separator_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_separator_smart_class_new()); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + ELM_SET_WIDTYPE(widtype, "separator"); + wd->horizontal = EINA_FALSE; + elm_widget_type_set(obj, "separator"); + elm_widget_sub_object_add(parent, obj); + 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, EINA_FALSE); + wd->sep = edje_object_add(e); + _elm_theme_object_set(obj, wd->sep, "separator", "vertical", "default"); + elm_widget_resize_object_set(obj, wd->sep); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } EAPI void -elm_separator_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_SEPARATOR_CHECK(obj); - ELM_SEPARATOR_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; horizontal = !!horizontal; - if (sd->horizontal == horizontal) return; - - sd->horizontal = horizontal; - - _elm_separator_smart_theme(obj); + if (wd->horizontal == horizontal) return; + wd->horizontal = horizontal; + _theme_hook(obj); } EAPI Eina_Bool elm_separator_horizontal_get(const Evas_Object *obj) { - ELM_SEPARATOR_CHECK(obj) EINA_FALSE; - ELM_SEPARATOR_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } diff --git a/src/lib/elm_separator.h b/src/lib/elm_separator.h index a5e473f00..1bc02d9b9 100644 --- a/src/lib/elm_separator.h +++ b/src/lib/elm_separator.h @@ -6,15 +6,9 @@ * * A separator can be vertical or horizontal. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for separator objects. - * - * This widget emits the signals coming from @ref Layout. - * * @ref tutorial_separator is a good example of how to use a separator. * @{ */ - /** * @brief Add a separator object to @p parent * @@ -25,7 +19,6 @@ * @ingroup Separator */ EAPI Evas_Object *elm_separator_add(Evas_Object *parent); - /** * @brief Set the horizontal mode of a separator object * @@ -35,7 +28,6 @@ EAPI Evas_Object *elm_separator_add(Evas_Object *parent); * @ingroup Separator */ EAPI void elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizontal); - /** * @brief Get the horizontal mode of a separator object * @@ -47,7 +39,6 @@ EAPI void elm_separator_horizontal_set(Evas_Object *obj, Eina_Bool horizont * @ingroup Separator */ EAPI Eina_Bool elm_separator_horizontal_get(const Evas_Object *obj); - /** * @} */ diff --git a/src/lib/elm_slider.c b/src/lib/elm_slider.c index 3e193ee89..7221ea086 100644 --- a/src/lib/elm_slider.c +++ b/src/lib/elm_slider.c @@ -1,443 +1,471 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char SLIDER_SMART_NAME[] = "elm_slider"; +typedef struct _Widget_Data Widget_Data; -typedef struct _Elm_Slider_Smart_Data Elm_Slider_Smart_Data; - -struct _Elm_Slider_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; - - Evas_Object *spacer; - Ecore_Timer *delay; + Evas_Object *slider; + Evas_Object *icon; + Evas_Object *end; + Evas_Object *spacer; - const char *units; - const char *indicator; + Ecore_Timer *delay; - char *(*indicator_format_func)(double val); - void (*indicator_format_free)(char *str); + Eina_Hash *labels; + const char *units; + const char *indicator; - char *(*units_format_func)(double val); - void (*units_format_free)(char *str); + char *(*indicator_format_func)(double val); + void (*indicator_format_free)(char *str); - double val, val_min, val_max, val2; - Evas_Coord size; - Evas_Coord downx, downy; + char *(*units_format_func)(double val); + void (*units_format_free)(char *str); - Eina_Bool horizontal : 1; - Eina_Bool inverted : 1; - Eina_Bool indicator_show : 1; - Eina_Bool spacer_down : 1; - Eina_Bool frozen : 1; -}; + double val, val_min, val_max, val2; + Evas_Coord size; + Evas_Coord downx, downy; -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"icon", "elm.swallow.icon"}, - {"end", "elm.swallow.end"}, - {NULL, NULL} + Eina_Bool horizontal : 1; + Eina_Bool inverted : 1; + Eina_Bool indicator_show : 1; + Eina_Bool spacer_down : 1; + Eina_Bool frozen : 1; }; -static const Elm_Layout_Part_Alias_Description _text_aliases[] = -{ - {"default", "elm.text"}, - {NULL, NULL} -}; +#define ELM_SLIDER_INVERTED_FACTOR (-1.0) + +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _disable_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _units_set(Evas_Object *obj); +static void _val_set(Evas_Object *obj); +static void _indicator_set(Evas_Object *obj); +static void _on_focus_hook(void *data, Evas_Object *obj); +static void _drag_up(void *data, Evas_Object *obj, + const char *emission, const char *source); +static void _drag_down(void *data, Evas_Object *obj, + const char *emission, const char *source); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); +static void _spacer_down_cb(void *data, Evas * e, Evas_Object * obj, void *event_info); +static void _spacer_move_cb(void *data, Evas * e, Evas_Object * obj, void *event_info); +static void _spacer_up_cb(void *data, Evas * e, Evas_Object * obj, void *event_info); static const char SIG_CHANGED[] = "changed"; static const char SIG_DELAY_CHANGED[] = "delay,changed"; static const char SIG_DRAG_START[] = "slider,drag,start"; static const char SIG_DRAG_STOP[] = "slider,drag,stop"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHANGED, ""}, - {SIG_DELAY_CHANGED, ""}, - {SIG_DRAG_START, ""}, - {SIG_DRAG_STOP, ""}, - {NULL, NULL} +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_CHANGED, ""}, + {SIG_DELAY_CHANGED, ""}, + {SIG_DRAG_START, ""}, + {SIG_DRAG_STOP, ""}, + {NULL, NULL} }; -#define ELM_SLIDER_DATA_GET(o, sd) \ - Elm_Slider_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_SLIDER_DATA_GET_OR_RETURN(o, ptr) \ - ELM_SLIDER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_SLIDER_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_SLIDER_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_SLIDER_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), SLIDER_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (SLIDER_SMART_NAME, _elm_slider, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static Eina_Bool -_delay_change(void *data) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - ELM_SLIDER_DATA_GET(data, sd); - - sd->delay = NULL; - evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, NULL); - - return ECORE_CALLBACK_CANCEL; -} + Evas_Event_Mouse_Wheel *mev; + Evas_Event_Key_Down *ev; + Widget_Data *wd; -static void -_val_fetch(Evas_Object *obj) -{ - Eina_Bool rtl; - double posx = 0.0, posy = 0.0, pos = 0.0, val; + wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; - ELM_SLIDER_DATA_GET(obj, sd); + if (type == EVAS_CALLBACK_KEY_DOWN) goto key_down; + else if (type != EVAS_CALLBACK_MOUSE_WHEEL) return EINA_FALSE; - edje_object_part_drag_value_get - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", &posx, &posy); - if (sd->horizontal) pos = posx; - else pos = posy; + mev = event_info; + if (mev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (elm_widget_disabled_get(obj)) return EINA_FALSE; - rtl = elm_widget_mirrored_get(obj); - if ((!rtl && sd->inverted) || - (rtl && ((!sd->horizontal && sd->inverted) || - (sd->horizontal && !sd->inverted)))) - pos = 1.0 - pos; + if (mev->z < 0) _drag_up(obj, NULL, NULL, NULL); + else _drag_down(obj, NULL, NULL, NULL); + mev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; - val = (pos * (sd->val_max - sd->val_min)) + sd->val_min; - if (val != sd->val) + key_down: + ev = event_info; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + if (elm_widget_disabled_get(obj)) return EINA_FALSE; + if ((!strcmp(ev->keyname, "Left")) || + ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { - sd->val = val; - evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); - if (sd->delay) ecore_timer_del(sd->delay); - sd->delay = ecore_timer_add(0.2, _delay_change, obj); + if (!wd->horizontal) return EINA_FALSE; + if (!wd->inverted) _drag_down(obj, NULL, NULL, NULL); + else _drag_up(obj, NULL, NULL, NULL); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } + else if ((!strcmp(ev->keyname, "Right")) || + ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) + { + if (!wd->horizontal) return EINA_FALSE; + if (!wd->inverted) _drag_up(obj, NULL, NULL, NULL); + else _drag_down(obj, NULL, NULL, NULL); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; } + else if ((!strcmp(ev->keyname, "Up")) || + ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) + { + if (wd->horizontal) return EINA_FALSE; + if (wd->inverted) _drag_up(obj, NULL, NULL, NULL); + else _drag_down(obj, NULL, NULL, NULL); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } + else if ((!strcmp(ev->keyname, "Down")) || + ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) + { + if (wd->horizontal) return EINA_FALSE; + if (wd->inverted) _drag_down(obj, NULL, NULL, NULL); + else _drag_up(obj, NULL, NULL, NULL); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } + else return EINA_FALSE; } static void -_val_set(Evas_Object *obj) +_del_hook(Evas_Object *obj) { - Eina_Bool rtl; - double pos; - - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->val_max > sd->val_min) - pos = (sd->val - sd->val_min) / (sd->val_max - sd->val_min); - else pos = 0.0; - - if (pos < 0.0) pos = 0.0; - else if (pos > 1.0) - pos = 1.0; - - rtl = elm_widget_mirrored_get(obj); - if ((!rtl && sd->inverted) || - (rtl && ((!sd->horizontal && sd->inverted) || - (sd->horizontal && !sd->inverted)))) - pos = 1.0 - pos; - - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", pos, pos); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->labels) eina_hash_free(wd->labels); + if (wd->indicator) eina_stringshare_del(wd->units); + if (wd->delay) ecore_timer_del(wd->delay); + free(wd); } static void -_units_set(Evas_Object *obj) +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->units_format_func) + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) { - char *buf; - - buf = sd->units_format_func(sd->val); - elm_layout_text_set(obj, "elm.units", buf); - - if (sd->units_format_free) sd->units_format_free(buf); + edje_object_signal_emit(wd->slider, "elm,action,focus", "elm"); + evas_object_focus_set(wd->slider, EINA_TRUE); } - else if (sd->units) + else { - char buf[1024]; - - snprintf(buf, sizeof(buf), sd->units, sd->val); - elm_layout_text_set(obj, "elm.units", buf); + edje_object_signal_emit(wd->slider, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->slider, EINA_FALSE); } - else elm_layout_text_set(obj, "elm.units", NULL); } static void -_indicator_set(Evas_Object *obj) +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->indicator_format_func) - { - char *buf; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->slider, rtl); +} - buf = sd->indicator_format_func(sd->val); - elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf); +static Eina_Bool +_labels_foreach_text_set(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata) +{ + Widget_Data *wd = fdata; - if (sd->indicator_format_free) sd->indicator_format_free(buf); - } - else if (sd->indicator) - { - char buf[1024]; + edje_object_part_text_escaped_set(wd->slider, key, data); - snprintf(buf, sizeof(buf), sd->indicator, sd->val); - elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", buf); - } - else elm_layout_text_set(obj, "elm.dragable.slider:elm.indicator", NULL); + return 1; } static void -_slider_update(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - _val_fetch(obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + if (wd->horizontal) + _elm_theme_object_set(obj, wd->slider, "slider", "horizontal", elm_widget_style_get(obj)); + else + _elm_theme_object_set(obj, wd->slider, "slider", "vertical", elm_widget_style_get(obj)); + if (wd->icon) + { + edje_object_part_swallow(wd->slider, "elm.swallow.content", wd->icon); + edje_object_signal_emit(wd->slider, "elm,state,icon,visible", "elm"); + } + if (wd->end) + edje_object_signal_emit(wd->slider, "elm,state,end,visible", "elm"); + else + edje_object_signal_emit(wd->slider, "elm,state,end,hidden", "elm"); + if (wd->labels) + { + eina_hash_foreach(wd->labels, _labels_foreach_text_set, wd); + edje_object_signal_emit(wd->slider, "elm,state,text,visible", "elm"); + } + + if (wd->units) + edje_object_signal_emit(wd->slider, "elm,state,units,visible", "elm"); + + if (wd->horizontal) + evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1); + else + evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale); + + if (wd->inverted) + edje_object_signal_emit(wd->slider, "elm,state,inverted,on", "elm"); + + edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer); _units_set(obj); _indicator_set(obj); + edje_object_message_signal_process(wd->slider); + edje_object_scale_set(wd->slider, elm_widget_scale_get(obj) * _elm_config->scale); + _val_set(obj); + _sizing_eval(obj); } static void -_drag(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_disable_hook(Evas_Object *obj) { - _slider_update(data); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_disabled_get(obj)) + edje_object_signal_emit(wd->slider, "elm,state,disabled", "elm"); + else + edje_object_signal_emit(wd->slider, "elm,state,enabled", "elm"); } static void -_drag_start(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_sizing_eval(Evas_Object *obj) { - _slider_update(data); - evas_object_smart_callback_call(data, SIG_DRAG_START, NULL); - elm_widget_scroll_freeze_push(data); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + if (!wd) return; + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->slider, &minw, &minh, minw, minh); + elm_coords_finger_size_adjust(1, &minw, 1, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); } static void -_drag_stop(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - _slider_update(data); - evas_object_smart_callback_call(data, SIG_DRAG_STOP, NULL); - elm_widget_scroll_freeze_pop(data); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + if ((obj != wd->icon) && (obj != wd->end)) return; + _sizing_eval(data); } static void -_drag_step(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) { - return; + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (!wd) return; + if (sub == wd->icon) + { + edje_object_signal_emit(wd->slider, "elm,state,icon,hidden", "elm"); + evas_object_event_callback_del_full + (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + wd->icon = NULL; + edje_object_message_signal_process(wd->slider); + _sizing_eval(obj); + } + if (sub == wd->end) + { + edje_object_signal_emit(wd->slider, "elm,state,end,hidden", "elm"); + evas_object_event_callback_del_full(sub, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + wd->end = NULL; + edje_object_message_signal_process(wd->slider); + _sizing_eval(obj); + } +} - _slider_update(data); +static Eina_Bool +_delay_change(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; + wd->delay = NULL; + evas_object_smart_callback_call(data, SIG_DELAY_CHANGED, NULL); + return ECORE_CALLBACK_CANCEL; } static void -_drag_up(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_val_fetch(Evas_Object *obj) { - double step; - - ELM_SLIDER_DATA_GET(data, sd); - step = 0.05; - - if (sd->inverted) step *= -1.0; + Eina_Bool rtl; + Widget_Data *wd = elm_widget_data_get(obj); + double posx = 0.0, posy = 0.0, pos = 0.0, val; + if (!wd) return; + edje_object_part_drag_value_get(wd->slider, "elm.dragable.slider", + &posx, &posy); + if (wd->horizontal) pos = posx; + else pos = posy; - edje_object_part_drag_step - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", step, step); + rtl = elm_widget_mirrored_get(obj); + if ((!rtl && wd->inverted) || (rtl && + ((!wd->horizontal && wd->inverted) || + (wd->horizontal && !wd->inverted)))) pos = 1.0 - pos; + val = (pos * (wd->val_max - wd->val_min)) + wd->val_min; + if (val != wd->val) + { + wd->val = val; + evas_object_smart_callback_call(obj, SIG_CHANGED, NULL); + if (wd->delay) ecore_timer_del(wd->delay); + wd->delay = ecore_timer_add(0.2, _delay_change, obj); + } } static void -_drag_down(void *data, - Evas_Object *obj __UNUSED__, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_val_set(Evas_Object *obj) { - double step; - - ELM_SLIDER_DATA_GET(data, sd); - step = -0.05; - - if (sd->inverted) step *= -1.0; + Eina_Bool rtl; + Widget_Data *wd = elm_widget_data_get(obj); + double pos; + if (!wd) return; + if (wd->val_max > wd->val_min) + pos = (wd->val - wd->val_min) / (wd->val_max - wd->val_min); + else + pos = 0.0; + if (pos < 0.0) pos = 0.0; + else if (pos > 1.0) pos = 1.0; - edje_object_part_drag_step - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", step, step); + rtl = elm_widget_mirrored_get(obj); + if ((!rtl && wd->inverted) || (rtl && + ((!wd->horizontal && wd->inverted) || + (wd->horizontal && !wd->inverted)))) pos = 1.0 - pos; + edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", pos, pos); } -static Eina_Bool -_elm_slider_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +static void +_units_set(Evas_Object *obj) { - Evas_Event_Mouse_Wheel *mev; - Evas_Event_Key_Down *ev; - - ELM_SLIDER_DATA_GET(obj, sd); - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - - if (type == EVAS_CALLBACK_KEY_DOWN) goto key_down; - else if (type != EVAS_CALLBACK_MOUSE_WHEEL) - return EINA_FALSE; - - mev = event_info; - if (mev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - - if (mev->z < 0) _drag_up(obj, NULL, NULL, NULL); - else _drag_down(obj, NULL, NULL, NULL); - mev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - - goto success; - -key_down: - ev = event_info; - if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - if ((!strcmp(ev->keyname, "Left")) || - ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->units_format_func) { - if (!sd->horizontal) return EINA_FALSE; - if (!sd->inverted) _drag_down(obj, NULL, NULL, NULL); - else _drag_up(obj, NULL, NULL, NULL); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - goto success; + char *buf; + buf = wd->units_format_func(wd->val); + edje_object_part_text_escaped_set(wd->slider, "elm.units", buf); + if (wd->units_format_free) wd->units_format_free(buf); } - else if ((!strcmp(ev->keyname, "Right")) || - ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) + else if (wd->units) { - if (!sd->horizontal) return EINA_FALSE; - if (!sd->inverted) _drag_up(obj, NULL, NULL, NULL); - else _drag_down(obj, NULL, NULL, NULL); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - goto success; + char buf[1024]; + + snprintf(buf, sizeof(buf), wd->units, wd->val); + edje_object_part_text_escaped_set(wd->slider, "elm.units", buf); } - else if ((!strcmp(ev->keyname, "Up")) || - ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) + else + edje_object_part_text_escaped_set(wd->slider, "elm.units", NULL); +} + +static void +_indicator_set(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->indicator_format_func) { - if (sd->horizontal) return EINA_FALSE; - if (sd->inverted) _drag_up(obj, NULL, NULL, NULL); - else _drag_down(obj, NULL, NULL, NULL); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - goto success; + char *buf; + buf = wd->indicator_format_func(wd->val); + edje_object_part_text_escaped_set(wd->slider, "elm.dragable.slider:elm.indicator", buf); + if (wd->indicator_format_free) wd->indicator_format_free(buf); } - else if ((!strcmp(ev->keyname, "Down")) || - ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) + else if (wd->indicator) { - if (sd->horizontal) return EINA_FALSE; - if (sd->inverted) _drag_down(obj, NULL, NULL, NULL); - else _drag_up(obj, NULL, NULL, NULL); - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - goto success; + char buf[1024]; + snprintf(buf, sizeof(buf), wd->indicator, wd->val); + edje_object_part_text_escaped_set(wd->slider, "elm.dragable.slider:elm.indicator", buf); } - else return EINA_FALSE; - -success: - _slider_update(obj); - - return EINA_TRUE; + else + edje_object_part_text_escaped_set(wd->slider, "elm.dragable.slider:elm.indicator", NULL); } static void -_visuals_refresh(Evas_Object *obj) +_drag(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - _val_set(obj); - _units_set(obj); - _indicator_set(obj); + _val_fetch(data); + _units_set(data); + _indicator_set(data); } -static Eina_Bool -_elm_slider_smart_theme(Evas_Object *obj) +static void +_drag_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->horizontal) - eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "horizontal"); - else - eina_stringshare_replace(&ELM_LAYOUT_DATA(sd)->group, "vertical"); - - if (!ELM_WIDGET_CLASS(_elm_slider_parent_sc)->theme(obj)) return EINA_FALSE; - - if (sd->units) - elm_layout_signal_emit(obj, "elm,state,units,visible", "elm"); + _val_fetch(data); + evas_object_smart_callback_call(data, SIG_DRAG_START, NULL); + _units_set(data); + _indicator_set(data); + elm_widget_scroll_freeze_push(data); +} - if (sd->horizontal) - evas_object_size_hint_min_set - (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get(), 1); - else - evas_object_size_hint_min_set - (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get()); +static void +_drag_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + _val_fetch(data); + evas_object_smart_callback_call(data, SIG_DRAG_STOP, NULL); + _units_set(data); + _indicator_set(data); + elm_widget_scroll_freeze_pop(data); +} - if (sd->inverted) - elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm"); +static void +_drag_step(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + _val_fetch(data); + _units_set(data); + _indicator_set(data); +} - _visuals_refresh(obj); +static void +_drag_up(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + double step; + Widget_Data *wd; - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + wd = elm_widget_data_get(data); + step = 0.05; - elm_layout_sizing_eval(obj); + if (wd->inverted) step *= ELM_SLIDER_INVERTED_FACTOR; - return EINA_TRUE; + edje_object_part_drag_step(wd->slider, "elm.dragable.slider", step, step); } static void -_elm_slider_smart_sizing_eval(Evas_Object *obj) +_drag_down(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) { - ELM_SLIDER_DATA_GET(obj, sd); + double step; + Widget_Data *wd; - Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; + wd = elm_widget_data_get(data); + step = -0.05; - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh); - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, maxw, maxh); + if (wd->inverted) step *= ELM_SLIDER_INVERTED_FACTOR; + + edje_object_part_drag_step(wd->slider, "elm.dragable.slider", step, step); } static void -_spacer_down_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) +_spacer_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { - ELM_SLIDER_DATA_GET(data, sd); - + Widget_Data *wd = elm_widget_data_get(data); Evas_Event_Mouse_Down *ev = event_info; Evas_Coord x, y, w, h; double button_x = 0.0, button_y = 0.0; - sd->spacer_down = EINA_TRUE; - sd->val2 = sd->val; - evas_object_geometry_get(sd->spacer, &x, &y, &w, &h); - sd->downx = ev->canvas.x - x; - sd->downy = ev->canvas.y - y; - if (sd->horizontal) + wd->spacer_down = EINA_TRUE; + wd->val2 = wd->val; + evas_object_geometry_get(wd->spacer, &x, &y, &w, &h); + wd->downx = ev->canvas.x - x; + wd->downy = ev->canvas.y - y; + if (wd->horizontal) { button_x = ((double)ev->canvas.x - (double)x) / (double)w; if (button_x > 1) button_x = 1; @@ -449,59 +477,56 @@ _spacer_down_cb(void *data, if (button_y > 1) button_y = 1; if (button_y < 0) button_y = 0; } - - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", - button_x, button_y); - _slider_update(data); + edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", button_x, button_y); + _val_fetch(data); evas_object_smart_callback_call(data, SIG_DRAG_START, NULL); - elm_layout_signal_emit(data, "elm,state,indicator,show", "elm"); + _units_set(data); + _indicator_set(data); + edje_object_signal_emit(wd->slider, "elm,state,indicator,show", "elm"); } static void -_spacer_move_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info) +_spacer_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { - ELM_SLIDER_DATA_GET(data, sd); - + Widget_Data *wd = elm_widget_data_get(data); + Evas_Event_Mouse_Move *ev = event_info; Evas_Coord x, y, w, h; double button_x = 0.0, button_y = 0.0; - Evas_Event_Mouse_Move *ev = event_info; - if (sd->spacer_down) + if (wd->spacer_down) { Evas_Coord d = 0; - evas_object_geometry_get(sd->spacer, &x, &y, &w, &h); - if (sd->horizontal) d = abs(ev->cur.canvas.x - x - sd->downx); - else d = abs(ev->cur.canvas.y - y - sd->downy); + evas_object_geometry_get(wd->spacer, &x, &y, &w, &h); + if (wd->horizontal) d = abs(ev->cur.canvas.x - x - wd->downx); + else d = abs(ev->cur.canvas.y - y - wd->downy); if (d > (_elm_config->thumbscroll_threshold - 1)) { - if (!sd->frozen) + if (!wd->frozen) { elm_widget_scroll_freeze_push(data); - sd->frozen = 1; + wd->frozen = 1; } ev->event_flags &= ~EVAS_EVENT_FLAG_ON_HOLD; } if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) { - if (sd->spacer_down) sd->spacer_down = EINA_FALSE; - _slider_update(data); + if (wd->spacer_down) wd->spacer_down = EINA_FALSE; + _val_fetch(data); evas_object_smart_callback_call(data, SIG_DRAG_STOP, NULL); - if (sd->frozen) + _units_set(data); + _indicator_set(data); + if (wd->frozen) { elm_widget_scroll_freeze_pop(data); - sd->frozen = 0; + wd->frozen = 0; } - elm_layout_signal_emit(data, "elm,state,indicator,hide", "elm"); - elm_slider_value_set(data, sd->val2); + edje_object_signal_emit(wd->slider, "elm,state,indicator,hide", "elm"); + elm_slider_value_set(data, wd->val2); return; } - if (sd->horizontal) + if (wd->horizontal) { button_x = ((double)ev->cur.canvas.x - (double)x) / (double)w; if (button_x > 1) button_x = 1; @@ -513,413 +538,536 @@ _spacer_move_cb(void *data, if (button_y > 1) button_y = 1; if (button_y < 0) button_y = 0; } - - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(sd)->resize_obj, "elm.dragable.slider", - button_x, button_y); - - _slider_update(data); + edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", button_x, button_y); + _val_fetch(data); + _units_set(data); + _indicator_set(data); } } static void -_spacer_up_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_spacer_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_SLIDER_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); - if (!sd->spacer_down) return; - if (sd->spacer_down) sd->spacer_down = EINA_FALSE; - - _slider_update(data); + if (!wd->spacer_down) return; + if (wd->spacer_down) wd->spacer_down = EINA_FALSE; + _val_fetch(data); evas_object_smart_callback_call(data, SIG_DRAG_STOP, NULL); - - if (sd->frozen) + _units_set(data); + _indicator_set(data); + if (wd->frozen) { elm_widget_scroll_freeze_pop(data); - sd->frozen = 0; + wd->frozen = 0; } - elm_layout_signal_emit(data, "elm,state,indicator,hide", "elm"); + edje_object_signal_emit(wd->slider, "elm,state,indicator,hide", "elm"); } static void -_min_max_set(Evas_Object *obj) +_elm_slider_label_set(Evas_Object *obj, const char *part, const char *label) { - char *buf_min = NULL; - char *buf_max = NULL; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + const char* default_part = "elm.text"; + const char* real_part; - ELM_SLIDER_DATA_GET(obj, sd); + if (!wd) return; - if (sd->units_format_func) + if (!part) + real_part = default_part; + else + real_part = part; + + if (wd->labels) + { + const char* old_label; + + old_label = eina_hash_find(wd->labels, real_part); + if (!old_label) + eina_hash_add(wd->labels, real_part, eina_stringshare_add(label)); + else + { + eina_stringshare_ref(old_label); + eina_hash_modify(wd->labels, real_part, eina_stringshare_add(label)); + eina_stringshare_del(old_label); + } + } + + if (label) { - buf_min = sd->units_format_func(sd->val_min); - buf_max = sd->units_format_func(sd->val_max); + edje_object_signal_emit(wd->slider, "elm,state,text,visible", "elm"); + edje_object_message_signal_process(wd->slider); } - else if (sd->units) + else { - int length = strlen(sd->units); + edje_object_signal_emit(wd->slider, "elm,state,text,hidden", "elm"); + edje_object_message_signal_process(wd->slider); + } - buf_min = alloca(length + 128); - buf_max = alloca(length + 128); + edje_object_part_text_escaped_set(wd->slider, real_part, label); + _sizing_eval(obj); +} - snprintf((char *)buf_min, length + 128, sd->units, sd->val_min); - snprintf((char *)buf_max, length + 128, sd->units, sd->val_max); - } +static const char * +_elm_slider_label_get(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->labels) return NULL; + + if (!part) + return eina_hash_find(wd->labels, "elm.text"); + return eina_hash_find(wd->labels, part); +} - elm_layout_text_set(obj, "elm.units.min", buf_min); - elm_layout_text_set(obj, "elm.units.max", buf_max); +static void +_icon_set(Evas_Object *obj, Evas_Object *icon) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->icon == icon) return; + if (wd->icon) evas_object_del(wd->icon); + wd->icon = icon; + if (icon) + { + elm_widget_sub_object_add(obj, icon); + evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->slider, "elm.swallow.icon", icon); + edje_object_signal_emit(wd->slider, "elm,state,icon,visible", "elm"); + edje_object_message_signal_process(wd->slider); + } + _sizing_eval(obj); +} - if (sd->units_format_func && sd->units_format_free) +static Evas_Object * +_icon_unset(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *ret = NULL; + if (!wd) return NULL; + if (wd->icon) { - sd->units_format_free(buf_min); - sd->units_format_free(buf_max); + elm_widget_sub_object_del(obj, wd->icon); + evas_object_event_callback_del_full(wd->icon, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + ret = wd->icon; + edje_object_part_unswallow(wd->slider, wd->icon); + edje_object_signal_emit(wd->slider, "elm,state,icon,hidden", "elm"); + wd->icon = NULL; + _sizing_eval(obj); } + return ret; } static void -_elm_slider_smart_add(Evas_Object *obj) +_end_set(Evas_Object *obj, Evas_Object *end) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Slider_Smart_Data); - - ELM_WIDGET_CLASS(_elm_slider_parent_sc)->base.add(obj); - - priv->horizontal = EINA_TRUE; - priv->indicator_show = EINA_TRUE; - priv->val = 0.0; - priv->val_min = 0.0; - priv->val_max = 1.0; - - elm_layout_theme_set - (obj, "slider", "horizontal", elm_widget_style_get(obj)); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->end == end) return; + if (wd->end) evas_object_del(wd->end); + wd->end = end; + if (end) + { + elm_widget_sub_object_add(obj, end); + evas_object_event_callback_add(end, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->slider, "elm.swallow.end", end); + edje_object_signal_emit(wd->slider, "elm,state,end,visible", "elm"); + edje_object_message_signal_process(wd->slider); + } + _sizing_eval(obj); +} - elm_layout_signal_callback_add(obj, "drag", "*", _drag, obj); - elm_layout_signal_callback_add(obj, "drag,start", "*", _drag_start, obj); - elm_layout_signal_callback_add(obj, "drag,stop", "*", _drag_stop, obj); - elm_layout_signal_callback_add(obj, "drag,step", "*", _drag_step, obj); - elm_layout_signal_callback_add(obj, "drag,page", "*", _drag_stop, obj); - edje_object_part_drag_value_set - (ELM_WIDGET_DATA(priv)->resize_obj, "elm.dragable.slider", 0.0, 0.0); +static Evas_Object * +_end_unset(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *ret = NULL; + if (!wd) return NULL; + if (wd->end) + { + elm_widget_sub_object_del(obj, wd->end); + evas_object_event_callback_del_full(wd->end, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + ret = wd->end; + edje_object_part_unswallow(wd->slider, wd->end); + edje_object_signal_emit(wd->slider, "elm,state,end,hidden", "elm"); + wd->end = NULL; + _sizing_eval(obj); + } + return ret; +} - priv->spacer = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_color_set(priv->spacer, 0, 0, 0, 0); - evas_object_pass_events_set(priv->spacer, EINA_TRUE); - elm_layout_content_set(obj, "elm.swallow.bar", priv->spacer); +static void +_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + if (!part || !strcmp(part, "icon")) + _icon_set(obj, content); + else if (!strcmp(part, "end")) + _end_set(obj, content); +} - evas_object_event_callback_add - (priv->spacer, EVAS_CALLBACK_MOUSE_DOWN, _spacer_down_cb, obj); - evas_object_event_callback_add - (priv->spacer, EVAS_CALLBACK_MOUSE_MOVE, _spacer_move_cb, obj); - evas_object_event_callback_add - (priv->spacer, EVAS_CALLBACK_MOUSE_UP, _spacer_up_cb, obj); +static Evas_Object * +_content_get_hook(const Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd; + wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!part || !strcmp(part, "icon")) + return wd->icon; + else if (!strcmp(part, "end")) + return wd->end; + return NULL; +} - elm_widget_can_focus_set(obj, EINA_TRUE); +static Evas_Object * +_content_unset_hook(Evas_Object *obj, const char *part) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + if (!part || !strcmp(part, "icon")) + return _icon_unset(obj); + else if (!strcmp(part, "end")) + return _end_unset(obj); + return NULL; } static void -_elm_slider_smart_del(Evas_Object *obj) +_hash_labels_free_cb(void* label) { - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->indicator) eina_stringshare_del(sd->indicator); - if (sd->units) eina_stringshare_del(sd->units); - if (sd->delay) ecore_timer_del(sd->delay); - - ELM_WIDGET_CLASS(_elm_slider_parent_sc)->base.del(obj); + if (label) + eina_stringshare_del(label); } static void -_elm_slider_smart_set_user(Elm_Layout_Smart_Class *sc) +_min_max_set(Evas_Object *obj) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_slider_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_slider_smart_del; + char *buf_min = NULL; + char *buf_max = NULL; - ELM_WIDGET_CLASS(sc)->theme = _elm_slider_smart_theme; - ELM_WIDGET_CLASS(sc)->event = _elm_slider_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->units_format_func) + { + buf_min = wd->units_format_func(wd->val_min); + buf_max = wd->units_format_func(wd->val_max); + } + else if (wd->units) + { + int length = strlen(wd->units); + + buf_min = alloca(length + 128); + buf_max = alloca(length + 128); + + snprintf((char*) buf_min, length + 128, wd->units, wd->val_min); + snprintf((char*) buf_max, length + 128, wd->units, wd->val_max); + } - sc->sizing_eval = _elm_slider_smart_sizing_eval; + edje_object_part_text_escaped_set(wd->slider, "elm.units.min", buf_min); + edje_object_part_text_escaped_set(wd->slider, "elm.units.max", buf_max); - sc->content_aliases = _content_aliases; - sc->text_aliases = _text_aliases; + if (wd->units_format_func && wd->units_format_free) + { + wd->units_format_free(buf_min); + wd->units_format_free(buf_max); + } } + EAPI Evas_Object * elm_slider_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; - - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_slider_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - elm_layout_sizing_eval(obj); - + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "slider"); + elm_widget_type_set(obj, "slider"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_disable_hook_set(obj, _disable_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_text_set_hook_set(obj, _elm_slider_label_set); + elm_widget_text_get_hook_set(obj, _elm_slider_label_get); + elm_widget_content_set_hook_set(obj, _content_set_hook); + elm_widget_content_get_hook_set(obj, _content_get_hook); + elm_widget_content_unset_hook_set(obj, _content_unset_hook); + + wd->horizontal = EINA_TRUE; + wd->indicator_show = EINA_TRUE; + wd->val = 0.0; + wd->val_min = 0.0; + wd->val_max = 1.0; + wd->labels = eina_hash_string_superfast_new(_hash_labels_free_cb); + + wd->slider = edje_object_add(e); + _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); + edje_object_signal_callback_add(wd->slider, "drag,stop", "*", _drag_stop, obj); + edje_object_signal_callback_add(wd->slider, "drag,step", "*", _drag_step, obj); + edje_object_signal_callback_add(wd->slider, "drag,page", "*", _drag_stop, obj); + // edje_object_signal_callback_add(wd->slider, "drag,set", "*", _drag_stop, obj); + edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", 0.0, 0.0); + + wd->spacer = evas_object_rectangle_add(e); + evas_object_color_set(wd->spacer, 0, 0, 0, 0); + evas_object_pass_events_set(wd->spacer, EINA_TRUE); + elm_widget_sub_object_add(obj, wd->spacer); + edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer); + evas_object_event_callback_add(wd->spacer, EVAS_CALLBACK_MOUSE_DOWN, _spacer_down_cb, obj); + evas_object_event_callback_add(wd->spacer, EVAS_CALLBACK_MOUSE_MOVE, _spacer_move_cb, obj); + evas_object_event_callback_add(wd->spacer, EVAS_CALLBACK_MOUSE_UP, _spacer_up_cb, obj); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + + // TODO: convert Elementary to subclassing of Evas_Smart_Class + // TODO: and save some bytes, making descriptions per-class and not instance! + evas_object_smart_callbacks_descriptions_set(obj, _signals); return obj; } EAPI void -elm_slider_span_size_set(Evas_Object *obj, - Evas_Coord size) -{ - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->size == size) return; - sd->size = size; - if (sd->horizontal) - evas_object_size_hint_min_set - (sd->spacer, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get(), 1); +elm_slider_span_size_set(Evas_Object *obj, Evas_Coord size) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->size == size) return; + wd->size = size; + if (wd->horizontal) + evas_object_size_hint_min_set(wd->spacer, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale, 1); else - evas_object_size_hint_min_set - (sd->spacer, 1, (double)sd->size * elm_widget_scale_get(obj) * - elm_config_scale_get()); - - if (sd->indicator_show) - elm_layout_signal_emit(obj, "elm,state,val,show", "elm"); + evas_object_size_hint_min_set(wd->spacer, 1, (double)wd->size * elm_widget_scale_get(obj) * _elm_config->scale); + if (wd->indicator_show) + edje_object_signal_emit(wd->slider, "elm,state,val,show", "elm"); else - elm_layout_signal_emit(obj, "elm,state,val,hide", "elm"); - - elm_layout_sizing_eval(obj); + edje_object_signal_emit(wd->slider, "elm,state,val,hide", "elm"); + edje_object_part_swallow(wd->slider, "elm.swallow.bar", wd->spacer); + _sizing_eval(obj); } EAPI Evas_Coord elm_slider_span_size_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) 0; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->size; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return wd->size; } EAPI void -elm_slider_unit_format_set(Evas_Object *obj, - const char *units) +elm_slider_unit_format_set(Evas_Object *obj, const char *units) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - eina_stringshare_replace(&sd->units, units); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + eina_stringshare_replace(&wd->units, units); if (units) { - elm_layout_signal_emit(obj, "elm,state,units,visible", "elm"); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + edje_object_signal_emit(wd->slider, "elm,state,units,visible", "elm"); + edje_object_message_signal_process(wd->slider); } else { - elm_layout_signal_emit(obj, "elm,state,units,hidden", "elm"); - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); + edje_object_signal_emit(wd->slider, "elm,state,units,hidden", "elm"); + edje_object_message_signal_process(wd->slider); } - _min_max_set(obj); _units_set(obj); - - elm_layout_sizing_eval(obj); + _sizing_eval(obj); } EAPI const char * elm_slider_unit_format_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) NULL; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->units; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->units; } EAPI void -elm_slider_indicator_format_set(Evas_Object *obj, - const char *indicator) +elm_slider_indicator_format_set(Evas_Object *obj, const char *indicator) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - eina_stringshare_replace(&sd->indicator, indicator); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + eina_stringshare_replace(&wd->indicator, indicator); _indicator_set(obj); } EAPI const char * elm_slider_indicator_format_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) NULL; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->indicator; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->indicator; } EAPI void -elm_slider_horizontal_set(Evas_Object *obj, - Eina_Bool horizontal) +elm_slider_horizontal_set(Evas_Object *obj, Eina_Bool horizontal) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; horizontal = !!horizontal; - if (sd->horizontal == horizontal) return; - sd->horizontal = horizontal; - - ELM_WIDGET_DATA(sd)->api->theme(obj); + if (wd->horizontal == horizontal) return; + wd->horizontal = horizontal; + _theme_hook(obj); } EAPI Eina_Bool elm_slider_horizontal_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) EINA_FALSE; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->horizontal; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->horizontal; } EAPI void -elm_slider_min_max_set(Evas_Object *obj, - double min, - double max) +elm_slider_min_max_set(Evas_Object *obj, double min, double max) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - if ((sd->val_min == min) && (sd->val_max == max)) return; - sd->val_min = min; - sd->val_max = max; - if (sd->val < sd->val_min) sd->val = sd->val_min; - if (sd->val > sd->val_max) sd->val = sd->val_max; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if ((wd->val_min == min) && (wd->val_max == max)) return; + wd->val_min = min; + wd->val_max = max; + if (wd->val < wd->val_min) wd->val = wd->val_min; + if (wd->val > wd->val_max) wd->val = wd->val_max; _min_max_set(obj); - - _visuals_refresh(obj); + _val_set(obj); + _units_set(obj); + _indicator_set(obj); } EAPI void -elm_slider_min_max_get(const Evas_Object *obj, - double *min, - double *max) +elm_slider_min_max_get(const Evas_Object *obj, double *min, double *max) { if (min) *min = 0.0; if (max) *max = 0.0; - - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - if (min) *min = sd->val_min; - if (max) *max = sd->val_max; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (min) *min = wd->val_min; + if (max) *max = wd->val_max; } EAPI void -elm_slider_value_set(Evas_Object *obj, - double val) +elm_slider_value_set(Evas_Object *obj, double val) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - if (sd->val == val) return; - sd->val = val; - - if (sd->val < sd->val_min) sd->val = sd->val_min; - if (sd->val > sd->val_max) sd->val = sd->val_max; - - _visuals_refresh(obj); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->val == val) return; + wd->val = val; + if (wd->val < wd->val_min) wd->val = wd->val_min; + if (wd->val > wd->val_max) wd->val = wd->val_max; + _val_set(obj); + _units_set(obj); + _indicator_set(obj); } EAPI double elm_slider_value_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) 0.0; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->val; + ELM_CHECK_WIDTYPE(obj, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0.0; + return wd->val; } EAPI void -elm_slider_inverted_set(Evas_Object *obj, - Eina_Bool inverted) +elm_slider_inverted_set(Evas_Object *obj, Eina_Bool inverted) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; inverted = !!inverted; - if (sd->inverted == inverted) return; - sd->inverted = inverted; - - if (sd->inverted) - elm_layout_signal_emit(obj, "elm,state,inverted,on", "elm"); + if (wd->inverted == inverted) return; + wd->inverted = inverted; + if (wd->inverted) + edje_object_signal_emit(wd->slider, "elm,state,inverted,on", "elm"); else - elm_layout_signal_emit(obj, "elm,state,inverted,off", "elm"); - - edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj); - - _visuals_refresh(obj); + edje_object_signal_emit(wd->slider, "elm,state,inverted,off", "elm"); + edje_object_message_signal_process(wd->slider); + _val_set(obj); + _units_set(obj); + _indicator_set(obj); } EAPI Eina_Bool elm_slider_inverted_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) EINA_FALSE; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->inverted; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->inverted; } EAPI void -elm_slider_indicator_format_function_set(Evas_Object *obj, - char *(*func)(double), - void (*free_func)(char *)) +elm_slider_indicator_format_function_set(Evas_Object *obj, char *(*func)(double val), void (*free_func)(char *str)) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - sd->indicator_format_func = func; - sd->indicator_format_free = free_func; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->indicator_format_func = func; + wd->indicator_format_free = free_func; _indicator_set(obj); } EAPI void -elm_slider_units_format_function_set(Evas_Object *obj, - char *(*func)(double), - void (*free_func)(char *)) +elm_slider_units_format_function_set(Evas_Object *obj, char *(*func)(double val), void (*free_func)(char *str)) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - sd->units_format_func = func; - sd->units_format_free = free_func; - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->units_format_func = func; + wd->units_format_free = free_func; _min_max_set(obj); _units_set(obj); } EAPI void -elm_slider_indicator_show_set(Evas_Object *obj, - Eina_Bool show) +elm_slider_indicator_show_set(Evas_Object *obj, Eina_Bool show) { - ELM_SLIDER_CHECK(obj); - ELM_SLIDER_DATA_GET(obj, sd); - - if (show) - { - sd->indicator_show = EINA_TRUE; - elm_layout_signal_emit(obj, "elm,state,val,show", "elm"); - } + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (show) { + wd->indicator_show = EINA_TRUE; + edje_object_signal_emit(wd->slider, "elm,state,val,show", "elm"); + } else { - sd->indicator_show = EINA_FALSE; - elm_layout_signal_emit(obj, "elm,state,val,hide", "elm"); - } - - elm_layout_sizing_eval(obj); + wd->indicator_show = EINA_FALSE; + edje_object_signal_emit(wd->slider, "elm,state,val,hide", "elm"); + } } EAPI Eina_Bool elm_slider_indicator_show_get(const Evas_Object *obj) { - ELM_SLIDER_CHECK(obj) EINA_FALSE; - ELM_SLIDER_DATA_GET(obj, sd); - - return sd->indicator_show; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->indicator_show; } + diff --git a/src/lib/elm_slider.h b/src/lib/elm_slider.h index 56d4e7113..5375aafe4 100644 --- a/src/lib/elm_slider.h +++ b/src/lib/elm_slider.h @@ -26,15 +26,11 @@ * the object or applications scaling factor. At any point code can query the * slider for its value with elm_slider_value_get(). * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for slider objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: - * - @c "changed" - Whenever the slider value is changed by the user. - * - @c "slider,drag,start" - dragging the slider indicator around has started. - * - @c "slider,drag,stop" - dragging the slider indicator around has stopped. - * - @c "delay,changed" - A short time after the value is changed by the user. + * Smart callbacks one can listen to: + * - "changed" - Whenever the slider value is changed by the user. + * - "slider,drag,start" - dragging the slider indicator around has started. + * - "slider,drag,stop" - dragging the slider indicator around has stopped. + * - "delay,changed" - A short time after the value is changed by the user. * This will be called only when the user stops dragging for * a very short period or when they release their * finger/mouse, so it avoids possibly expensive reactions to diff --git a/src/lib/elm_slideshow.c b/src/lib/elm_slideshow.c index 49a696be1..08aa142bf 100644 --- a/src/lib/elm_slideshow.c +++ b/src/lib/elm_slideshow.c @@ -1,193 +1,210 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" -static const char SLIDESHOW_SMART_NAME[] = "elm_slideshow"; - -typedef struct _Elm_Slideshow_Smart_Data Elm_Slideshow_Smart_Data; -typedef struct _Elm_Slideshow_Item Elm_Slideshow_Item; +typedef struct _Widget_Data Widget_Data; +typedef struct _Elm_Slideshow_Item Elm_Slideshow_Item; struct _Elm_Slideshow_Item { ELM_WIDGET_ITEM; - Eina_List *l, *l_built; + Eina_List *l, *l_built; const Elm_Slideshow_Item_Class *itc; }; -struct _Elm_Slideshow_Smart_Data +struct _Widget_Data { - Elm_Layout_Smart_Data base; + Evas_Object *slideshow; // list of Elm_Slideshow_Item* - Eina_List *items; - Eina_List *items_built; + Eina_List *items; + Eina_List *items_built; - Elm_Slideshow_Item *current; - Elm_Slideshow_Item *previous; + Elm_Slideshow_Item *current; + Elm_Slideshow_Item *previous; - Eina_List *transitions; - const char *transition; + Eina_List *transitions; + const char *transition; - int count_item_pre_before; - int count_item_pre_after; - Ecore_Timer *timer; - double timeout; - Eina_Bool loop : 1; + int count_item_pre_before; + int count_item_pre_after; + Ecore_Timer *timer; + double timeout; + Eina_Bool loop:1; struct - { - const char *current; - Eina_List *list; //list of const char * - } layout; + { + const char *current; + Eina_List *list; //list of const char * + } layout; }; +static const char *widtype = NULL; +static void _del_pre_hook(Evas_Object *obj); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static Eina_Bool _timer_cb(void *data); +static void _on_focus_hook(void *data, Evas_Object *obj); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); + static const char SIG_CHANGED[] = "changed"; static const char SIG_TRANSITION_END[] = "transition,end"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {SIG_TRANSITION_END, ""}, {NULL, NULL} }; -#define ELM_SLIDESHOW_DATA_GET(o, sd) \ - Elm_Slideshow_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_SLIDESHOW_DATA_GET_OR_RETURN(o, ptr) \ - ELM_SLIDESHOW_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_SLIDESHOW_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_SLIDESHOW_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_SLIDESHOW_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), SLIDESHOW_SMART_NAME, __func__)) \ - return - -#define ELM_SLIDESHOW_ITEM_CHECK(it) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, ); \ - ELM_SLIDESHOW_CHECK(it->base.widget); - -#define ELM_SLIDESHOW_ITEM_CHECK_OR_RETURN(it, ...) \ - ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \ - ELM_SLIDESHOW_CHECK(it->base.widget) __VA_ARGS__; - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (SLIDESHOW_SMART_NAME, _elm_slideshow, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks); - static Eina_Bool -_elm_slideshow_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - Evas_Event_Key_Down *ev = event_info; - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; - - ELM_SLIDESHOW_DATA_GET(obj, sd); - + if (elm_widget_disabled_get(obj)) return EINA_FALSE; if ((!strcmp(ev->keyname, "Left")) || ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { elm_slideshow_previous(obj); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } - if ((!strcmp(ev->keyname, "Right")) || ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) { elm_slideshow_next(obj); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } - if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")) || (!strcmp(ev->keyname, "space"))) { - if (sd->timeout) + if (wd->timeout) { - if (sd->timer) + if (wd->timer) { - ecore_timer_del(sd->timer); - sd->timer = NULL; + ecore_timer_del(wd->timer); + wd->timer = NULL; } else - elm_slideshow_timeout_set(obj, sd->timeout); + elm_slideshow_timeout_set(obj, wd->timeout); } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } - return EINA_FALSE; } static void -_elm_slideshow_smart_sizing_eval(Evas_Object *obj) +_del_pre_hook(Evas_Object *obj) { - ELM_SLIDESHOW_DATA_GET(obj, sd); - Evas_Coord minw = -1, minh = -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); +} - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, minw, minh); +static void +_del_hook(Evas_Object *obj) +{ + const char *layout; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_slideshow_clear(obj); + elm_widget_stringlist_free(wd->transitions); + if (wd->timer) ecore_timer_del(wd->timer); + EINA_LIST_FREE(wd->layout.list, layout) + eina_stringshare_del(layout); + free(wd); } -static Elm_Slideshow_Item * -_item_prev_get(Elm_Slideshow_Item *item) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd); - Elm_Slideshow_Item *prev = eina_list_data_get(eina_list_prev(item->l)); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->slideshow, "elm,action,focus", "elm"); + evas_object_focus_set(wd->slideshow, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->slideshow, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->slideshow, EINA_FALSE); + } +} - if ((!prev) && (sd->loop)) - prev = eina_list_data_get(eina_list_last(item->l)); +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->slideshow, rtl); +} - return prev; +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", elm_widget_style_get(obj)); + edje_object_scale_set(wd->slideshow, elm_widget_scale_get(obj) * + _elm_config->scale); + _sizing_eval(obj); } -static Elm_Slideshow_Item * -_item_next_get(Elm_Slideshow_Item *item) +static void +_sizing_eval(Evas_Object *obj) { - ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd); - Elm_Slideshow_Item *next = eina_list_data_get(eina_list_next(item->l)); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; + if (!wd) return; + edje_object_size_min_calc(wd->slideshow, &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, minw, minh); +} - if ((!next) && (sd->loop)) - next = eina_list_data_get(sd->items); +static Elm_Slideshow_Item* _item_prev_get(Elm_Slideshow_Item* item) +{ + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + Elm_Slideshow_Item* prev = eina_list_data_get(eina_list_prev(item->l)); + if ((!prev) && (wd->loop)) + prev = eina_list_data_get(eina_list_last(item->l)); + return prev; +} + +static Elm_Slideshow_Item* _item_next_get(Elm_Slideshow_Item* item) +{ + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + Elm_Slideshow_Item* next = eina_list_data_get(eina_list_next(item->l)); + if ((!next) && (wd->loop)) + next = eina_list_data_get(wd->items); return next; } static void -_on_size_hints_changed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_sizing_eval(data); + _sizing_eval(data); +} + +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + ; } static void @@ -195,28 +212,29 @@ _item_realize(Elm_Slideshow_Item *item) { Elm_Slideshow_Item *_item_prev, *_item_next; Evas_Object *obj = WIDGET(item); + Widget_Data *wd = elm_widget_data_get(obj); int ac, bc, lc, ic = 0; - ELM_SLIDESHOW_DATA_GET_OR_RETURN(obj, sd); - + if (!wd) return; if ((!VIEW(item)) && (item->itc->func.get)) { - VIEW(item) = item->itc->func.get(elm_widget_item_data_get(item), obj); + VIEW(item) = item->itc->func.get(elm_widget_item_data_get(item), + obj); + evas_object_smart_member_add(VIEW(item), obj); item->l_built = eina_list_append(NULL, item); - sd->items_built = eina_list_merge(sd->items_built, item->l_built); - //FIXME: item could be shown by obj + wd->items_built = eina_list_merge(wd->items_built, item->l_built); + //FIXME: item could be showed by obj evas_object_hide(VIEW(item)); } else if (item->l_built) - sd->items_built = eina_list_demote_list(sd->items_built, item->l_built); + wd->items_built = eina_list_demote_list(wd->items_built, item->l_built); //pre-create previous and next item - ac = sd->count_item_pre_after; + ac = wd->count_item_pre_after; _item_next = item; - bc = sd->count_item_pre_before; + bc = wd->count_item_pre_before; _item_prev = item; - lc = eina_list_count(sd->items) - 1; - + lc = eina_list_count(wd->items) - 1; while (lc > 0 && ((ac > 0) || (bc > 0))) { if (lc > 0 && ac > 0) @@ -232,21 +250,21 @@ _item_realize(Elm_Slideshow_Item *item) { ic++; VIEW(_item_next) = - _item_next->itc->func.get( - elm_widget_item_data_get(_item_next), obj); - _item_next->l_built = - eina_list_append(NULL, _item_next); - sd->items_built = eina_list_merge - (sd->items_built, _item_next->l_built); - //FIXME: _item_next could be shown by obj later + _item_next->itc->func.get( + elm_widget_item_data_get(_item_next), obj); + evas_object_smart_member_add(VIEW(_item_next), obj); + _item_next->l_built = eina_list_append(NULL, _item_next); + wd->items_built = eina_list_merge(wd->items_built, + _item_next->l_built); + //FIXME: _item_next could be showed by obj later evas_object_hide(VIEW(_item_next)); } else if (_item_next && _item_next->l_built) { ic++; - sd->items_built = - eina_list_demote_list - (sd->items_built, _item_next->l_built); + wd->items_built = + eina_list_demote_list(wd->items_built, + _item_next->l_built); } } } @@ -264,21 +282,21 @@ _item_realize(Elm_Slideshow_Item *item) { ic++; VIEW(_item_prev) = - _item_prev->itc->func.get( - elm_widget_item_data_get(_item_prev), obj); - _item_prev->l_built = - eina_list_append(NULL, _item_prev); - sd->items_built = eina_list_merge - (sd->items_built, _item_prev->l_built); - //FIXME: _item_prev could be shown by obj later + _item_prev->itc->func.get( + elm_widget_item_data_get(_item_prev), obj); + evas_object_smart_member_add(VIEW(_item_prev), obj); + _item_prev->l_built = eina_list_append(NULL, _item_prev); + wd->items_built = eina_list_merge(wd->items_built, + _item_prev->l_built); + //FIXME: _item_prev could be showed by obj later evas_object_hide(VIEW(_item_prev)); } else if (_item_prev && _item_prev->l_built) { ic++; - sd->items_built = - eina_list_demote_list - (sd->items_built, _item_prev->l_built); + wd->items_built = + eina_list_demote_list(wd->items_built, + _item_prev->l_built); } } } @@ -286,12 +304,11 @@ _item_realize(Elm_Slideshow_Item *item) //delete unused items lc = ic + 1; - - while ((int)eina_list_count(sd->items_built) > lc) + while ((int)eina_list_count(wd->items_built) > lc) { - item = eina_list_data_get(sd->items_built); - sd->items_built = eina_list_remove_list - (sd->items_built, sd->items_built); + item = eina_list_data_get(wd->items_built); + wd->items_built = eina_list_remove_list(wd->items_built, + wd->items_built); if (item->itc->func.del) item->itc->func.del(elm_widget_item_data_get(item), VIEW(item)); evas_object_del(VIEW(item)); @@ -300,44 +317,40 @@ _item_realize(Elm_Slideshow_Item *item) } static void -_on_slideshow_end(void *data, - Evas_Object *obj __UNUSED__, - const char *emission, - const char *source __UNUSED__) +_end(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__) { Elm_Slideshow_Item *item; - ELM_SLIDESHOW_DATA_GET(data, sd); + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; - item = sd->previous; + item = wd->previous; if (item) { - elm_layout_content_unset(data, "elm.swallow.1"); + edje_object_part_unswallow(wd->slideshow, VIEW(item)); evas_object_hide(VIEW(item)); - sd->previous = NULL; + wd->previous = NULL; } - item = sd->current; + item = wd->current; if ((!item) || (!VIEW(item))) return; _item_realize(item); - elm_layout_content_unset(data, "elm.swallow.2"); - - elm_layout_content_set(data, "elm.swallow.1", VIEW(item)); - elm_layout_signal_emit(data, "anim,end", "slideshow"); + edje_object_part_unswallow(wd->slideshow, VIEW(item)); + edje_object_part_swallow(wd->slideshow, "elm.swallow.1", VIEW(item)); + edje_object_signal_emit(wd->slideshow, "anim,end", "slideshow"); if (emission != NULL) - evas_object_smart_callback_call(data, SIG_TRANSITION_END, sd->current); + evas_object_smart_callback_call(data, SIG_TRANSITION_END, wd->current); } static Eina_Bool _timer_cb(void *data) { Evas_Object *obj = data; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - sd->timer = NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ECORE_CALLBACK_CANCEL; + wd->timer = NULL; elm_slideshow_next(obj); - return ECORE_CALLBACK_CANCEL; } @@ -345,26 +358,28 @@ static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it) { Elm_Slideshow_Item *item = (Elm_Slideshow_Item *)it; - ELM_SLIDESHOW_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE); + Widget_Data *wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return EINA_FALSE; - if (sd->previous == item) sd->previous = NULL; - if (sd->current == item) + if (wd->previous == item) wd->previous = NULL; + if (wd->current == item) { - Eina_List *l = eina_list_data_find_list(sd->items, item); + Eina_List *l = eina_list_data_find_list(wd->items, item); Eina_List *l2 = eina_list_next(l); - sd->current = NULL; + wd->current = NULL; if (!l2) { l2 = eina_list_prev(l); if (l2) elm_slideshow_item_show(eina_list_data_get(l2)); + } else elm_slideshow_item_show(eina_list_data_get(l2)); } - sd->items = eina_list_remove_list(sd->items, item->l); - sd->items_built = eina_list_remove_list(sd->items_built, item->l_built); + wd->items = eina_list_remove_list(wd->items, item->l); + wd->items_built = eina_list_remove_list(wd->items_built, item->l_built); if ((VIEW(item)) && (item->itc->func.del)) item->itc->func.del(elm_widget_item_data_get(item), VIEW(item)); @@ -372,140 +387,95 @@ _item_del_pre_hook(Elm_Object_Item *it) return EINA_TRUE; } -static void -_elm_slideshow_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Slideshow_Smart_Data); - - ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.add(obj); - - priv->current = NULL; - priv->previous = NULL; - - priv->count_item_pre_before = 2; - priv->count_item_pre_after = 2; - - elm_layout_theme_set(obj, "slideshow", "base", elm_widget_style_get(obj)); - - priv->transitions = elm_widget_stringlist_get - (edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj, - "transitions")); - if (eina_list_count(priv->transitions) > 0) - priv->transition = - eina_stringshare_add(eina_list_data_get(priv->transitions)); - - priv->layout.list = elm_widget_stringlist_get - (edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj, "layouts")); - - if (eina_list_count(priv->layout.list) > 0) - priv->layout.current = eina_list_data_get(priv->layout.list); - - edje_object_signal_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "end", "slideshow", _on_slideshow_end, - obj); - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj); - - elm_widget_can_focus_set(obj, EINA_TRUE); -} - -static void -_elm_slideshow_smart_del(Evas_Object *obj) -{ - ELM_SLIDESHOW_DATA_GET(obj, sd); - const char *layout; - - elm_slideshow_clear(obj); - elm_widget_stringlist_free(sd->transitions); - if (sd->timer) ecore_timer_del(sd->timer); - - EINA_LIST_FREE (sd->layout.list, layout) - eina_stringshare_del(layout); - - ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.del(obj); -} - -static void -_elm_slideshow_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_slideshow_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_slideshow_smart_del; - - ELM_WIDGET_CLASS(sc)->event = _elm_slideshow_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_slideshow_smart_sizing_eval; -} - EAPI Evas_Object * elm_slideshow_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "slideshow"); + elm_widget_type_set(obj, "slideshow"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_data_set(obj, wd); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_can_focus_set(obj, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + + wd->current = NULL; + wd->previous = NULL; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd->slideshow = edje_object_add(e); + _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default"); + wd->count_item_pre_before = 2; + wd->count_item_pre_after = 2; + elm_widget_resize_object_set(obj, wd->slideshow); - e = evas_object_evas_get(parent); - if (!e) return NULL; + wd->transitions = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "transitions")); + if (eina_list_count(wd->transitions) > 0) + wd->transition = eina_stringshare_add(eina_list_data_get(wd->transitions)); - obj = evas_object_smart_add(e, _elm_slideshow_smart_class_new()); + wd->layout.list = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "layouts")); + if (eina_list_count(wd->layout.list) > 0) + wd->layout.current = eina_list_data_get(wd->layout.list); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + edje_object_signal_callback_add(wd->slideshow, "end", "slideshow", _end, obj); - elm_layout_sizing_eval(obj); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); return obj; } -EAPI Elm_Object_Item * -elm_slideshow_item_add(Evas_Object *obj, - const Elm_Slideshow_Item_Class *itc, - const void *data) +EAPI Elm_Object_Item* +elm_slideshow_item_add(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data) { Elm_Slideshow_Item *item; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - + if (!wd) return NULL; item = elm_widget_item_new(obj, Elm_Slideshow_Item); if (!item) return NULL; - elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook); item->itc = itc; item->l = eina_list_append(item->l, item); elm_widget_item_data_set(item, data); - sd->items = eina_list_merge(sd->items, item->l); + wd->items = eina_list_merge(wd->items, item->l); - if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item); + if (!wd->current) elm_slideshow_item_show((Elm_Object_Item *)item); return (Elm_Object_Item *)item; } -EAPI Elm_Object_Item * -elm_slideshow_item_sorted_insert(Evas_Object *obj, - const Elm_Slideshow_Item_Class *itc, - const void *data, - Eina_Compare_Cb func) +EAPI Elm_Object_Item* +elm_slideshow_item_sorted_insert(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data, Eina_Compare_Cb func) { Elm_Slideshow_Item *item; - - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; item = elm_widget_item_new(obj, Elm_Slideshow_Item); if (!item) return NULL; - elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook); item->itc = itc; item->l = eina_list_append(item->l, item); elm_widget_item_data_set(item, data); - sd->items = eina_list_sorted_merge(sd->items, item->l, func); + wd->items = eina_list_sorted_merge(wd->items, item->l, func); - if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item); + if (!wd->current) elm_slideshow_item_show((Elm_Object_Item *)item); return (Elm_Object_Item *)item; } @@ -513,33 +483,30 @@ elm_slideshow_item_sorted_insert(Evas_Object *obj, EAPI void elm_slideshow_item_show(Elm_Object_Item *it) { + ELM_OBJ_ITEM_CHECK_OR_RETURN(it); + char buf[1024]; Elm_Slideshow_Item *item, *next = NULL; - - ELM_SLIDESHOW_ITEM_CHECK(it); - + Widget_Data *wd; item = (Elm_Slideshow_Item *)it; - ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd); - - if (item == sd->current) return; + wd = elm_widget_data_get(WIDGET(item)); + if (!wd) return; + if (item == wd->current) return; next = item; - _on_slideshow_end(WIDGET(item), WIDGET(item), NULL, NULL); - - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; - if (sd->timeout > 0.0) - sd->timer = ecore_timer_add(sd->timeout, _timer_cb, WIDGET(item)); + _end(WIDGET(item), WIDGET(item), NULL, NULL); + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; + if (wd->timeout > 0.0) + wd->timer = ecore_timer_add(wd->timeout, _timer_cb, WIDGET(item)); _item_realize(next); - elm_layout_content_set(WIDGET(item), "elm.swallow.2", VIEW(next)); - - snprintf(buf, sizeof(buf), "%s,next", sd->transition); - elm_layout_signal_emit(WIDGET(item), buf, "slideshow"); - - sd->previous = sd->current; - sd->current = next; - evas_object_smart_callback_call(WIDGET(item), SIG_CHANGED, sd->current); + edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(next)); + snprintf(buf, sizeof(buf), "%s,next", wd->transition); + edje_object_signal_emit(wd->slideshow, buf, "slideshow"); + wd->previous = wd->current; + wd->current = next; + evas_object_smart_callback_call(WIDGET(item), SIG_CHANGED, wd->current); } EAPI void @@ -547,31 +514,33 @@ elm_slideshow_next(Evas_Object *obj) { char buf[1024]; Elm_Slideshow_Item *next = NULL; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); + if (!wd) return; - if (sd->current) next = _item_next_get(sd->current); + if (wd->current) + next = _item_next_get(wd->current); - if ((!next) || (next == sd->current)) return; + if ((!next) || (next == wd->current)) return; - _on_slideshow_end(obj, obj, NULL, NULL); + _end(obj, obj, NULL, NULL); - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; - if (sd->timeout > 0.0) - sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj); + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; + if (wd->timeout > 0.0) + wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj); _item_realize(next); - elm_layout_content_set(obj, "elm.swallow.2", VIEW(next)); + edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(next)); - snprintf(buf, sizeof(buf), "%s,next", sd->transition); - elm_layout_signal_emit(obj, buf, "slideshow"); + snprintf(buf, sizeof(buf), "%s,next", wd->transition); + edje_object_signal_emit(wd->slideshow, buf, "slideshow"); - sd->previous = sd->current; - sd->current = next; - evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current); + wd->previous = wd->current; + wd->current = next; + evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current); } EAPI void @@ -579,236 +548,229 @@ elm_slideshow_previous(Evas_Object *obj) { char buf[1024]; Elm_Slideshow_Item *prev = NULL; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); + if (!wd) return; - if (sd->current) prev = _item_prev_get(sd->current); + if (wd->current) + prev = _item_prev_get(wd->current); - if ((!prev) || (prev == sd->current)) return; + if ((!prev) || (prev == wd->current)) return; - _on_slideshow_end(obj, obj, NULL, NULL); + _end(obj, obj, NULL, NULL); - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; - if (sd->timeout > 0.0) - sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj); + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; + if (wd->timeout > 0.0) + wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj); _item_realize(prev); - elm_layout_content_set(obj, "elm.swallow.2", VIEW(prev)); + edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(prev)); - snprintf(buf, 1024, "%s,previous", sd->transition); - elm_layout_signal_emit(obj, buf, "slideshow"); + snprintf(buf, 1024, "%s,previous", wd->transition); + edje_object_signal_emit(wd->slideshow, buf, "slideshow"); - sd->previous = sd->current; - sd->current = prev; - evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current); + wd->previous = wd->current; + wd->current = prev; + evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current); } EAPI const Eina_List * elm_slideshow_transitions_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->transitions; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->transitions; } EAPI const Eina_List * elm_slideshow_layouts_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->layout.list; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->layout.list; } EAPI void -elm_slideshow_transition_set(Evas_Object *obj, - const char *transition) +elm_slideshow_transition_set(Evas_Object *obj, const char *transition) { - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - - eina_stringshare_replace(&sd->transition, transition); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + eina_stringshare_replace(&wd->transition, transition); } EAPI const char * elm_slideshow_transition_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->transition; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->transition; } EAPI void -elm_slideshow_timeout_set(Evas_Object *obj, - double timeout) -{ - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - - sd->timeout = timeout; - - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; - +elm_slideshow_timeout_set(Evas_Object *obj, double timeout) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->timeout = timeout; + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; if (timeout > 0.0) - sd->timer = ecore_timer_add(timeout, _timer_cb, obj); + wd->timer = ecore_timer_add(timeout, _timer_cb, obj); } EAPI double elm_slideshow_timeout_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) - 1.0; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->timeout; + ELM_CHECK_WIDTYPE(obj, widtype) -1.0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1.0; + return wd->timeout; } EAPI void -elm_slideshow_loop_set(Evas_Object *obj, - Eina_Bool loop) +elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop) { - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - - sd->loop = loop; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->loop = loop; } EAPI const char * elm_slideshow_layout_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) EINA_FALSE; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->layout.current; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->layout.current; } EAPI void -elm_slideshow_layout_set(Evas_Object *obj, - const char *layout) +elm_slideshow_layout_set(Evas_Object *obj, const char *layout) { char buf[PATH_MAX]; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - - sd->layout.current = layout; + wd->layout.current = layout; snprintf(buf, sizeof(buf), "layout,%s", layout); - elm_layout_signal_emit(obj, buf, "slideshow"); + edje_object_signal_emit(wd->slideshow, buf, "slideshow"); } EAPI Eina_Bool elm_slideshow_loop_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) EINA_FALSE; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->loop; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->loop; } EAPI void elm_slideshow_clear(Evas_Object *obj) { Elm_Slideshow_Item *item; - - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - - sd->previous = NULL; - sd->current = NULL; - EINA_LIST_FREE (sd->items_built, item) + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->previous = NULL; + wd->current = NULL; + EINA_LIST_FREE(wd->items_built, item) { if (item->itc->func.del) item->itc->func.del(elm_widget_item_data_get(item), VIEW(item)); } - EINA_LIST_FREE (sd->items, item) + EINA_LIST_FREE(wd->items, item) elm_widget_item_free(item); } EAPI const Eina_List * elm_slideshow_items_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->items; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->items; } EAPI Elm_Object_Item * elm_slideshow_item_current_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return (Elm_Object_Item *)sd->current; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return (Elm_Object_Item *) wd->current; } EAPI Evas_Object * -elm_slideshow_item_object_get(const Elm_Object_Item *it) +elm_slideshow_item_object_get(const Elm_Object_Item * it) { - ELM_SLIDESHOW_ITEM_CHECK_OR_RETURN(it, NULL); + ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL); return VIEW(it); } EAPI int elm_slideshow_cache_before_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) - 1; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->count_item_pre_before; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1; + return wd->count_item_pre_before; } EAPI void elm_slideshow_cache_before_set(Evas_Object *obj, int count) { - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - if (!sd) return; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (count < 0) count = 0; - sd->count_item_pre_before = count; + wd->count_item_pre_before = count; } EAPI int elm_slideshow_cache_after_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) - 1; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return sd->count_item_pre_after; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1; + return wd->count_item_pre_after; } EAPI void -elm_slideshow_cache_after_set(Evas_Object *obj, - int count) +elm_slideshow_cache_after_set(Evas_Object *obj, int count) { - ELM_SLIDESHOW_CHECK(obj); - ELM_SLIDESHOW_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; if (count < 0) count = 0; - sd->count_item_pre_after = count; + wd->count_item_pre_after = count; } EAPI Elm_Object_Item * -elm_slideshow_item_nth_get(const Evas_Object *obj, - unsigned int nth) +elm_slideshow_item_nth_get(const Evas_Object *obj, unsigned int nth) { - ELM_SLIDESHOW_CHECK(obj) NULL; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return eina_list_nth(sd->items, nth); + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return eina_list_nth(wd->items, nth); } EAPI unsigned int elm_slideshow_count_get(const Evas_Object *obj) { - ELM_SLIDESHOW_CHECK(obj) 0; - ELM_SLIDESHOW_DATA_GET(obj, sd); - - return eina_list_count(sd->items); + ELM_CHECK_WIDTYPE(obj, widtype) 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; + return eina_list_count(wd->items); } diff --git a/src/lib/elm_slideshow.h b/src/lib/elm_slideshow.h index 75eefa3db..9a014d837 100644 --- a/src/lib/elm_slideshow.h +++ b/src/lib/elm_slideshow.h @@ -45,11 +45,8 @@ * cached @b before and @b after the current item, in the widget's * item list. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for slideshow objects. + * Smart events one can add callbacks for are: * - * This widget emits the following signals, besides the ones sent from - * @ref Layout: * - @c "changed" - when the slideshow switches its view to a new * item. event_info parameter in callback contains the current visible item * - @c "transition,end" - when a slide transition ends. event_info parameter diff --git a/src/lib/elm_table.c b/src/lib/elm_table.c index 1ad3d89f8..532ccf437 100644 --- a/src/lib/elm_table.c +++ b/src/lib/elm_table.c @@ -1,48 +1,48 @@ #include <Elementary.h> #include "elm_priv.h" -static const char TABLE_SMART_NAME[] = "elm_table"; - -#define ELM_TABLE_DATA_GET(o, sd) \ - Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_TABLE_DATA_GET_OR_RETURN(o, ptr) \ - ELM_TABLE_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_TABLE_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_TABLE_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), TABLE_SMART_NAME, __func__)) \ - return - -EVAS_SMART_SUBCLASS_NEW - (TABLE_SMART_NAME, _elm_table, Elm_Widget_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL); +typedef struct _Widget_Data Widget_Data; + +struct _Widget_Data +{ + Evas_Object *tbl; +}; + +static const char *widtype = NULL; +static void _del_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); +static void _theme_hook(Evas_Object *obj); + +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_event_callback_del_full + (wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + evas_object_del(wd->tbl); +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} static Eina_Bool -_elm_table_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_table_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - Eina_Bool ret; + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *items; - Eina_List *(*list_free)(Eina_List *list); - void *(*list_data_get)(const Eina_List *list); + void *(*list_data_get) (const Eina_List *list); + Eina_List *(*list_free) (Eina_List *list); - ELM_TABLE_DATA_GET(obj, sd); + if ((!wd) || (!wd->tbl)) + return EINA_FALSE; /* Focus chain */ /* TODO: Change this to use other chain */ @@ -53,16 +53,18 @@ _elm_table_smart_focus_next(const Evas_Object *obj, } else { - items = evas_object_table_children_get(sd->resize_obj); + items = evas_object_table_children_get(wd->tbl); list_data_get = eina_list_data_get; list_free = eina_list_free; if (!items) return EINA_FALSE; } - ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next); + Eina_Bool ret = elm_widget_focus_list_next_get(obj, items, list_data_get, + dir, next); - if (list_free) list_free((Eina_List *)items); + if (list_free) + list_free((Eina_List *)items); return ret; } @@ -70,31 +72,29 @@ _elm_table_smart_focus_next(const Evas_Object *obj, static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl) { - ELM_TABLE_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if ((!wd) || (!wd->tbl)) + return; - evas_object_table_mirrored_set(sd->resize_obj, rtl); + evas_object_table_mirrored_set(wd->tbl, rtl); } -static Eina_Bool -_elm_table_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { - if (!_elm_table_parent_sc->theme(obj)) return EINA_FALSE; - + _elm_widget_mirrored_reload(obj); _mirrored_set(obj, elm_widget_mirrored_get(obj)); - - return EINA_TRUE; } 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 w, h; - - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_size_hint_min_get(sd->resize_obj, &minw, &minh); - evas_object_size_hint_max_get(sd->resize_obj, &maxw, &maxh); + if (!wd) return; + evas_object_size_hint_min_get(wd->tbl, &minw, &minh); + evas_object_size_hint_max_get(wd->tbl, &maxw, &maxh); evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, maxw, maxh); evas_object_geometry_get(obj, NULL, NULL, &w, &h); @@ -106,198 +106,123 @@ _sizing_eval(Evas_Object *obj) } static void -_on_size_hints_changed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { _sizing_eval(data); } -static Eina_Bool -_elm_table_smart_sub_object_del(Evas_Object *obj, - Evas_Object *child) -{ - if (!_elm_table_parent_sc->sub_object_del(obj, child)) return EINA_FALSE; - - _sizing_eval(obj); - - return EINA_TRUE; -} - -static void -_elm_table_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data); - - priv->resize_obj = evas_object_table_add(evas_object_evas_get(obj)); - - evas_object_event_callback_add - (priv->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_size_hints_changed, obj); - - _elm_table_parent_sc->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); - elm_widget_highlight_ignore_set(obj, EINA_FALSE); - - _elm_table_smart_theme(obj); -} - static void -_elm_table_smart_del(Evas_Object *obj) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Eina_List *l; - Evas_Object *child; - - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_event_callback_del_full - (sd->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_size_hints_changed, obj); - - /* let's make our table object the *last* to be processed, since it - * may (smart) parent other sub objects here */ - EINA_LIST_FOREACH (sd->subobjs, l, child) - { - if (child == sd->resize_obj) - { - sd->subobjs = eina_list_demote_list(sd->subobjs, l); - break; - } - } - - _elm_table_parent_sc->base.del(obj); -} - -static void -_elm_table_smart_set_user(Elm_Widget_Smart_Class *sc) -{ - sc->base.add = _elm_table_smart_add; - sc->base.del = _elm_table_smart_del; - - sc->sub_object_del = _elm_table_smart_sub_object_del; - sc->theme = _elm_table_smart_theme; - sc->focus_next = _elm_table_smart_focus_next; + _sizing_eval(obj); } EAPI Evas_Object * elm_table_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); - e = evas_object_evas_get(parent); - if (!e) return NULL; + ELM_SET_WIDTYPE(widtype, "table"); + elm_widget_type_set(obj, "table"); + elm_widget_sub_object_add(parent, obj); + elm_widget_data_set(obj, wd); + elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); + elm_widget_focus_next_hook_set(obj, _elm_table_focus_next_hook); + elm_widget_can_focus_set(obj, EINA_FALSE); + elm_widget_highlight_ignore_set(obj, EINA_FALSE); + elm_widget_theme_hook_set(obj, _theme_hook); - obj = evas_object_smart_add(e, _elm_table_smart_class_new()); + wd->tbl = evas_object_table_add(e); + evas_object_event_callback_add(wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + elm_widget_resize_object_set(obj, wd->tbl); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); return obj; } EAPI void -elm_table_homogeneous_set(Evas_Object *obj, - Eina_Bool homogeneous) +elm_table_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous) { - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_homogeneous_set(sd->resize_obj, homogeneous); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_table_homogeneous_set(wd->tbl, homogeneous); } EAPI Eina_Bool elm_table_homogeneous_get(const Evas_Object *obj) { - ELM_TABLE_CHECK(obj) EINA_FALSE; - ELM_TABLE_DATA_GET(obj, sd); - - return evas_object_table_homogeneous_get(sd->resize_obj); + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return evas_object_table_homogeneous_get(wd->tbl); } EAPI void -elm_table_padding_set(Evas_Object *obj, - Evas_Coord horizontal, - Evas_Coord vertical) +elm_table_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical) { - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_padding_set - (sd->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_table_padding_set(wd->tbl, horizontal, vertical); } EAPI void -elm_table_padding_get(const Evas_Object *obj, - Evas_Coord *horizontal, - Evas_Coord *vertical) +elm_table_padding_get(const Evas_Object *obj, Evas_Coord *horizontal, Evas_Coord *vertical) { - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_padding_get - (sd->resize_obj, horizontal, vertical); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_table_padding_get(wd->tbl, horizontal, vertical); } EAPI void -elm_table_pack(Evas_Object *obj, - Evas_Object *subobj, - int x, - int y, - int w, - int h) +elm_table_pack(Evas_Object *obj, Evas_Object *subobj, int x, int y, int w, int h) { - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_add(obj, subobj); - evas_object_table_pack(sd->resize_obj, subobj, x, y, w, h); + evas_object_table_pack(wd->tbl, subobj, x, y, w, h); } EAPI void -elm_table_unpack(Evas_Object *obj, - Evas_Object *subobj) +elm_table_unpack(Evas_Object *obj, Evas_Object *subobj) { - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; elm_widget_sub_object_del(obj, subobj); - evas_object_table_unpack(sd->resize_obj, subobj); + evas_object_table_unpack(wd->tbl, subobj); } EAPI void -elm_table_pack_set(Evas_Object *subobj, - int x, - int y, - int w, - int h) +elm_table_pack_set(Evas_Object *subobj, int x, int y, int w, int h) { Evas_Object *obj = elm_widget_parent_widget_get(subobj); - - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_pack(sd->resize_obj, subobj, x, y, w, h); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_table_pack(wd->tbl, subobj, x, y, w, h); } EAPI void -elm_table_pack_get(Evas_Object *subobj, - int *x, - int *y, - int *w, - int *h) +elm_table_pack_get(Evas_Object *subobj, int *x, int *y, int *w, int *h) { Evas_Object *obj = elm_widget_parent_widget_get(subobj); unsigned short ix, iy, iw, ih; - - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_pack_get(sd->resize_obj, subobj, &ix, &iy, &iw, &ih); + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_table_pack_get(wd->tbl, subobj, &ix, &iy, &iw, &ih); if (x) *x = ix; if (y) *y = iy; if (w) *w = iw; @@ -305,11 +230,14 @@ elm_table_pack_get(Evas_Object *subobj, } EAPI void -elm_table_clear(Evas_Object *obj, - Eina_Bool clear) -{ - ELM_TABLE_CHECK(obj); - ELM_TABLE_DATA_GET(obj, sd); - - evas_object_table_clear(sd->resize_obj, clear); +elm_table_clear(Evas_Object *obj, Eina_Bool clear) +{ + Eina_List *chld; + Evas_Object *o; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + chld = evas_object_table_children_get(wd->tbl); + EINA_LIST_FREE(chld, o) elm_widget_sub_object_del(obj, o); + evas_object_table_clear(wd->tbl, clear); } diff --git a/src/lib/elm_video.c b/src/lib/elm_video.c index a89549b30..173f9ed28 100644 --- a/src/lib/elm_video.c +++ b/src/lib/elm_video.c @@ -1,72 +1,49 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" #ifdef HAVE_EMOTION # include <Emotion.h> #endif -/* TODO: add buffering support to Emotion and display buffering - * progress in the theme when needed */ +/* TODO: add buffering support to Emotion and display buffering progression in the theme when needed */ -static const char VIDEO_SMART_NAME[] = "elm_video"; - -typedef struct _Elm_Video_Smart_Data Elm_Video_Smart_Data; -struct _Elm_Video_Smart_Data +typedef struct _Widget_Data Widget_Data; +struct _Widget_Data { - Elm_Layout_Smart_Data base; + Evas_Object *layout; + Evas_Object *emotion; + + Ecore_Timer *timer; + + Eina_Bool stop : 1; + Eina_Bool remember : 1; +}; - Evas_Object *emotion; - Ecore_Timer *timer; +#ifdef HAVE_EMOTION +static const char *widtype = NULL; - Eina_Bool stop : 1; - Eina_Bool remember : 1; +static const Evas_Smart_Cb_Description _signals[] = { + { NULL, NULL } }; -#define ELM_VIDEO_DATA_GET(o, sd) \ - Elm_Video_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_VIDEO_DATA_GET_OR_RETURN(o, ptr) \ - ELM_VIDEO_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_VIDEO_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_VIDEO_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_VIDEO_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), VIDEO_SMART_NAME, __func__)) \ - return - -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (VIDEO_SMART_NAME, _elm_video, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); +static void _del_hook(Evas_Object *obj); +static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _on_focus_hook(void *data, Evas_Object *obj); +static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src, + Evas_Callback_Type type, void *event_info); static Eina_Bool -_elm_video_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { -#ifdef HAVE_EMOTION - Evas_Event_Key_Down *ev = event_info; - if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; if (elm_widget_disabled_get(obj)) return EINA_FALSE; - if ((!strcmp(ev->keyname, "Left")) || ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) { @@ -82,10 +59,8 @@ _elm_video_smart_event(Evas_Object *obj, } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } - if ((!strcmp(ev->keyname, "Right")) || ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) { @@ -102,10 +77,8 @@ _elm_video_smart_event(Evas_Object *obj, } ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } - if (!strcmp(ev->keyname, "space")) { if (elm_video_is_playing_get(obj)) @@ -113,512 +86,496 @@ _elm_video_smart_event(Evas_Object *obj, else elm_video_play(obj); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - return EINA_TRUE; } + fprintf(stderr, "keyname: '%s' not handle\n", ev->keyname); + return EINA_FALSE; +} - INF("keyname: '%s' not handled", ev->keyname); +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); - return EINA_FALSE; -#else + if (!wd) return; + if (wd->timer) ecore_timer_del(wd->timer); + free(wd); +} - (void *)obj; - (void *)type; - (void *)event_info; +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (elm_widget_focus_get(obj)) + { + edje_object_signal_emit(wd->layout, "elm,action,focus", "elm"); + evas_object_focus_set(wd->layout, EINA_TRUE); + } + else + { + edje_object_signal_emit(wd->layout, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->layout, EINA_FALSE); + } +} - return EINA_FALSE; -#endif +static void +_mirrored_set(Evas_Object *obj, Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + edje_object_mirrored_set(wd->layout, rtl); } static void -_elm_video_smart_sizing_eval(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { -#ifdef HAVE_EMOTION - ELM_VIDEO_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _elm_theme_object_set(obj, wd->layout, "video", "base", elm_widget_style_get(obj)); + edje_object_scale_set(wd->layout, elm_widget_scale_get(obj) * + _elm_config->scale); + _sizing_eval(obj); +} +static void +_sizing_eval(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1; Evas_Coord w, h; - evas_object_size_hint_request_get(sd->emotion, &minw, &minh); - evas_object_size_hint_aspect_set - (sd->emotion, EVAS_ASPECT_CONTROL_BOTH, minw, minh); - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &w, &h); + if (!wd) return; + evas_object_size_hint_request_get(wd->emotion, &minw, &minh); + evas_object_size_hint_aspect_set(wd->emotion, EVAS_ASPECT_CONTROL_BOTH, minw, minh); + edje_object_size_min_calc(wd->layout, &w, &h); if (w != 0 && h != 0) { minw = w; minh = h; } - evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, minw, minh); -#else +} - (void *)obj; -#endif +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); } -#ifdef HAVE_EMOTION static void -_on_size_hints_changed(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - elm_layout_sizing_eval(data); + Widget_Data *wd = elm_widget_data_get(obj); + + if (wd->remember) emotion_object_last_position_save(wd->emotion); } static void -_on_open_done(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_open_done(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,video,open", "elm"); + Widget_Data *wd = elm_widget_data_get(data); + + edje_object_signal_emit(wd->layout, "elm,video,open", "elm"); } static void -_on_playback_started(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_playback_started(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,video,play", "elm"); + Widget_Data *wd = elm_widget_data_get(data); + + edje_object_signal_emit(wd->layout, "elm,video,play", "elm"); } static void -_on_playback_finished(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_playback_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_signal_emit(data, "elm,video,end", "elm"); + Widget_Data *wd = elm_widget_data_get(data); + + edje_object_signal_emit(wd->layout, "elm,video,end", "elm"); } static void -_on_aspect_ratio_updated(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_update_aspect_ratio(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - elm_layout_sizing_eval(data); + _sizing_eval(data); } static void -_on_title_changed(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_title_change(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { + Widget_Data *wd = elm_widget_data_get(data); const char *title; - ELM_VIDEO_DATA_GET(data, sd); - - title = emotion_object_title_get(sd->emotion); - elm_layout_text_set(data, "elm,title", title); - elm_layout_signal_emit(data, "elm,video,title", "elm"); + title = emotion_object_title_get(wd->emotion); + edje_object_part_text_escaped_set(wd->layout, "elm,title", title); + edje_object_signal_emit(wd->layout, "elm,video,title", "elm"); } static void -_on_audio_level_changed(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_audio_level_change(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - (void)data; + (void) data; } static Eina_Bool _suspend_cb(void *data) { + Widget_Data *wd = elm_widget_data_get(data); double interval; - ELM_VIDEO_DATA_GET(data, sd); - - interval = ecore_timer_interval_get(sd->timer); + interval = ecore_timer_interval_get(wd->timer); if (interval <= 20) - emotion_object_suspend_set(sd->emotion, EMOTION_SLEEP); + emotion_object_suspend_set(wd->emotion, EMOTION_SLEEP); else if (interval <= 30) - emotion_object_suspend_set(sd->emotion, EMOTION_DEEP_SLEEP); + emotion_object_suspend_set(wd->emotion, EMOTION_DEEP_SLEEP); else { - emotion_object_suspend_set(sd->emotion, EMOTION_HIBERNATE); - sd->timer = NULL; - + emotion_object_suspend_set(wd->emotion, EMOTION_HIBERNATE); + wd->timer = NULL; return ECORE_CALLBACK_CANCEL; } - ecore_timer_interval_set(sd->timer, interval + 10); + ecore_timer_interval_set(wd->timer, interval + 10); return ECORE_CALLBACK_RENEW; } - #endif Eina_Bool _elm_video_check(Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(video) EINA_FALSE; - - return EINA_TRUE; + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + return EINA_TRUE; #else - (void)video; - - return EINA_FALSE; + (void) video; + return EINA_FALSE; #endif } -static void -_elm_video_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Video_Smart_Data); - - ELM_WIDGET_CLASS(_elm_video_parent_sc)->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_TRUE); - -#ifdef HAVE_EMOTION - priv->stop = EINA_FALSE; - priv->remember = EINA_FALSE; - - priv->emotion = emotion_object_add(evas_object_evas_get(obj)); - emotion_object_init(priv->emotion, NULL); - - elm_layout_theme_set(obj, "video", "base", elm_widget_style_get(obj)); - elm_layout_content_set(obj, "elm.swallow.video", priv->emotion); - - evas_object_smart_callback_add - (priv->emotion, "open_done", _on_open_done, obj); - evas_object_smart_callback_add - (priv->emotion, "playback_started", _on_playback_started, obj); - evas_object_smart_callback_add - (priv->emotion, "playback_finished", _on_playback_finished, obj); - evas_object_smart_callback_add - (priv->emotion, "frame_resize", _on_aspect_ratio_updated, obj); - evas_object_smart_callback_add - (priv->emotion, "title_change", _on_title_changed, obj); - evas_object_smart_callback_add - (priv->emotion, "audio_level_change", _on_audio_level_changed, obj); - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, NULL); - - priv->timer = ecore_timer_add(20.0, _suspend_cb, obj); -#endif -} - -static void -_elm_video_smart_del(Evas_Object *obj) -{ - ELM_VIDEO_DATA_GET(obj, sd); - -#ifdef HAVE_EMOTION - if (sd->timer) ecore_timer_del(sd->timer); - if (sd->remember) emotion_object_last_position_save(sd->emotion); -#endif - - ELM_WIDGET_CLASS(_elm_video_parent_sc)->base.del(obj); -} - -static void -_elm_video_smart_set_user(Elm_Layout_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _elm_video_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _elm_video_smart_del; - - ELM_WIDGET_CLASS(sc)->event = _elm_video_smart_event; - ELM_WIDGET_CLASS(sc)->focus_next = NULL; /* not 'focus chain manager' */ - - sc->sizing_eval = _elm_video_smart_sizing_eval; -} - EAPI Evas_Object * elm_video_add(Evas_Object *parent) { #ifdef HAVE_EMOTION - Evas *e; Evas_Object *obj; + Evas *e; + Widget_Data *wd; + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + ELM_SET_WIDTYPE(widtype, "video"); + elm_widget_type_set(obj, "video"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + 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, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + + wd->stop = EINA_FALSE; + wd->remember = EINA_FALSE; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd->layout = edje_object_add(e); + _elm_theme_object_set(obj, wd->layout, "video", "base", "default"); + elm_widget_resize_object_set(obj, wd->layout); + evas_object_show(wd->layout); + evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - e = evas_object_evas_get(parent); - if (!e) return NULL; + wd->emotion = emotion_object_add(e); + emotion_object_init(wd->emotion, NULL); + elm_widget_sub_object_add(obj, wd->emotion); + edje_object_part_swallow(wd->layout, "elm.swallow.video", wd->emotion); - obj = evas_object_smart_add(e, _elm_video_smart_class_new()); + evas_object_smart_callback_add(wd->emotion, "open_done", _open_done, obj); + evas_object_smart_callback_add(wd->emotion, "playback_started", _playback_started, obj); + evas_object_smart_callback_add(wd->emotion, "playback_finished", _playback_finished, obj); + evas_object_smart_callback_add(wd->emotion, "frame_resize", _update_aspect_ratio, obj); + evas_object_smart_callback_add(wd->emotion, "title_change", _title_change, obj); + evas_object_smart_callback_add(wd->emotion, "audio_level_change", _audio_level_change, obj); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); + evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, NULL); + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + + wd->timer = ecore_timer_add(20.0, _suspend_cb, obj); return obj; #else - (void)parent; - + (void) parent; return NULL; #endif } EAPI Eina_Bool -elm_video_file_set(Evas_Object *obj, - const char *filename) +elm_video_file_set(Evas_Object *video, const char *filename) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) EINA_FALSE; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(video); - if (sd->remember) emotion_object_last_position_save(sd->emotion); - sd->stop = EINA_FALSE; - if (!emotion_object_file_set(sd->emotion, filename)) return EINA_FALSE; + if (wd->remember) emotion_object_last_position_save(wd->emotion); + wd->stop = EINA_FALSE; + if (!emotion_object_file_set(wd->emotion, filename)) return EINA_FALSE; if ((!strncmp(filename, "file://", 7)) || (!strstr(filename, "://"))) - emotion_object_last_position_load(sd->emotion); + emotion_object_last_position_load(wd->emotion); - elm_layout_signal_emit(obj, "elm,video,load", "elm"); + edje_object_signal_emit(wd->layout, "elm,video,load", "elm"); return EINA_TRUE; #else - (void)obj; - (void)filename; + (void) video; + (void) filename; return EINA_FALSE; #endif } EAPI Evas_Object * -elm_video_emotion_get(const Evas_Object *obj) +elm_video_emotion_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) NULL; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(video); - return sd->emotion; + return wd->emotion; #else - (void)obj; + (void) video; return NULL; #endif } EAPI void -elm_video_play(Evas_Object *obj) +elm_video_play(Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - if (emotion_object_play_get(sd->emotion)) return; + if (emotion_object_play_get(wd->emotion)) return ; - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; - sd->stop = EINA_FALSE; - emotion_object_play_set(sd->emotion, EINA_TRUE); + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; + wd->stop = EINA_FALSE; + emotion_object_play_set(wd->emotion, EINA_TRUE); #else - (void)obj; + (void) video; #endif } /* FIXME: pause will setup timer and go into sleep or * hibernate after a while without activity. */ + EAPI void -elm_video_pause(Evas_Object *obj) +elm_video_pause(Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - if (!emotion_object_play_get(sd->emotion)) return; + if (!emotion_object_play_get(wd->emotion)) return ; - if (!sd->timer) sd->timer = ecore_timer_add(20.0, _suspend_cb, obj); - emotion_object_play_set(sd->emotion, EINA_FALSE); - elm_layout_signal_emit(obj, "elm,video,pause", "elm"); + if (!wd->timer) wd->timer = ecore_timer_add(20.0, _suspend_cb, video); + emotion_object_play_set(wd->emotion, EINA_FALSE); + edje_object_signal_emit(wd->layout, "elm,video,pause", "elm"); #else - (void)obj; + (void) video; #endif } /* FIXME: stop should go into hibernate state directly. */ EAPI void -elm_video_stop(Evas_Object *obj) +elm_video_stop(Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); - - if (!emotion_object_play_get(sd->emotion) && sd->stop) return; + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - if (sd->timer) ecore_timer_del(sd->timer); - sd->timer = NULL; + if (!emotion_object_play_get(wd->emotion) && wd->stop) return ; - sd->stop = EINA_TRUE; - emotion_object_play_set(sd->emotion, EINA_FALSE); - elm_layout_signal_emit(obj, "elm,video,stop", "elm"); - emotion_object_suspend_set(sd->emotion, EMOTION_HIBERNATE); + if (wd->timer) ecore_timer_del(wd->timer); + wd->timer = NULL; + wd->stop = EINA_TRUE; + emotion_object_play_set(wd->emotion, EINA_FALSE); + edje_object_signal_emit(wd->layout, "elm,video,stop", "elm"); + emotion_object_suspend_set(wd->emotion, EMOTION_HIBERNATE); #else - (void)obj; + (void) video; #endif } EAPI Eina_Bool -elm_video_is_playing_get(const Evas_Object *obj) +elm_video_is_playing_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) EINA_FALSE; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_play_get(sd->emotion); + return emotion_object_play_get(wd->emotion); #else - (void)obj; + (void) video; return EINA_FALSE; #endif } EAPI Eina_Bool -elm_video_is_seekable_get(const Evas_Object *obj) +elm_video_is_seekable_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) EINA_FALSE; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_seekable_get(sd->emotion); + return emotion_object_seekable_get(wd->emotion); #else - (void)obj; + (void) video; return EINA_FALSE; #endif } EAPI Eina_Bool -elm_video_audio_mute_get(const Evas_Object *obj) +elm_video_audio_mute_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) EINA_FALSE; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_audio_mute_get(sd->emotion); + return emotion_object_audio_mute_get(wd->emotion); #else - (void)obj; + (void) video; return EINA_FALSE; #endif } EAPI void -elm_video_audio_mute_set(Evas_Object *obj, - Eina_Bool mute) +elm_video_audio_mute_set(Evas_Object *video, Eina_Bool mute) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - emotion_object_audio_mute_set(sd->emotion, mute); + emotion_object_audio_mute_set(wd->emotion, mute); #else - (void)obj; - (void)mute; + (void) video; + (void) mute; #endif } EAPI double -elm_video_audio_level_get(const Evas_Object *obj) +elm_video_audio_level_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) 0.0; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_audio_volume_get(sd->emotion); + return emotion_object_audio_volume_get(wd->emotion); #else - (void)obj; + (void) video; return 0.0; #endif } EAPI void -elm_video_audio_level_set(Evas_Object *obj, - double volume) +elm_video_audio_level_set(Evas_Object *video, double volume) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - emotion_object_audio_volume_set(sd->emotion, volume); + emotion_object_audio_volume_set(wd->emotion, volume); #else - (void)obj; - (void)volume; + (void) video; + (void) volume; #endif } EAPI double -elm_video_play_position_get(const Evas_Object *obj) +elm_video_play_position_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) 0.0; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_position_get(sd->emotion); + return emotion_object_position_get(wd->emotion); #else - (void)obj; + (void) video; return 0.0; #endif } EAPI void -elm_video_play_position_set(Evas_Object *obj, - double position) +elm_video_play_position_set(Evas_Object *video, double position) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - emotion_object_position_set(sd->emotion, position); + emotion_object_position_set(wd->emotion, position); #else - (void)obj; - (void)position; + (void) video; + (void) position; #endif } EAPI double -elm_video_play_length_get(const Evas_Object *obj) +elm_video_play_length_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) 0.0; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) 0.0; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_play_length_get(sd->emotion); + return emotion_object_play_length_get(wd->emotion); #else - (void)obj; + (void) video; return 0.0; #endif } EAPI const char * -elm_video_title_get(const Evas_Object *obj) +elm_video_title_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) NULL; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(video); - return emotion_object_title_get(sd->emotion); + return emotion_object_title_get(wd->emotion); #else - (void)obj; + (void) video; return NULL; #endif } EAPI void -elm_video_remember_position_set(Evas_Object *obj, - Eina_Bool remember) +elm_video_remember_position_set(Evas_Object *video, Eina_Bool remember) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj); - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype); + Widget_Data *wd = elm_widget_data_get(video); - sd->remember = remember; + wd->remember = remember; #else - (void)obj; - (void)remember; + (void) video; + (void) remember; #endif } EAPI Eina_Bool -elm_video_remember_position_get(const Evas_Object *obj) +elm_video_remember_position_get(const Evas_Object *video) { #ifdef HAVE_EMOTION - ELM_VIDEO_CHECK(obj) EINA_FALSE; - ELM_VIDEO_DATA_GET(obj, sd); + ELM_CHECK_WIDTYPE(video, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(video); - return sd->remember; + return wd->remember; #else - (void)obj; + (void) video; return EINA_FALSE; #endif } diff --git a/src/lib/elm_video.h b/src/lib/elm_video.h index 8fd9778a4..018f63245 100644 --- a/src/lib/elm_video.h +++ b/src/lib/elm_video.h @@ -20,19 +20,16 @@ * linked Elm_Video so it will use the video decoder, if available. It also * activates the "remember" function on the linked Elm_Video object. * - * Both widgets inherit from the @ref Layout one, so that all the - * functions acting on it also work for video objects. - * - * The player widget emits the following signals, besides the ones - * sent from @ref Layout: - * - @c "forward,clicked" - the user clicked the forward button. - * - @c "info,clicked" - the user clicked the info button. - * - @c "next,clicked" - the user clicked the next button. - * - @c "pause,clicked" - the user clicked the pause button. - * - @c "play,clicked" - the user clicked the play button. - * - @c "prev,clicked" - the user clicked the prev button. - * - @c "rewind,clicked" - the user clicked the rewind button. - * - @c "stop,clicked" - the user clicked the stop button. + * Signals that you can add callback for are : + * + * "forward,clicked" - the user clicked the forward button. + * "info,clicked" - the user clicked the info button. + * "next,clicked" - the user clicked the next button. + * "pause,clicked" - the user clicked the pause button. + * "play,clicked" - the user clicked the play button. + * "prev,clicked" - the user clicked the prev button. + * "rewind,clicked" - the user clicked the rewind button. + * "stop,clicked" - the user clicked the stop button. * * Default content parts of the player widget that you can use for are: * @li "video" - A video of the player diff --git a/src/lib/elm_web.c b/src/lib/elm_web.c index e070f8cfd..c0367cd6b 100644 --- a/src/lib/elm_web.c +++ b/src/lib/elm_web.c @@ -9,107 +9,68 @@ #include <EWebKit.h> /* Similar to iPhone */ -// TODO: switch between iPhone, iPad or Chrome/Safari based on some -// elm setting? +// TODO: switch between iPhone, iPad or Chrome/Safari based on some elm setting? +#define ELM_WEB_USER_AGENT "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " PACKAGE_NAME "/" PACKAGE_VERSION -#define ELM_WEB_USER_AGENT \ - "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)" \ - " AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a" \ - " Safari/419.3 " PACKAGE_NAME "/" PACKAGE_VERSION -#endif - -static const char WEB_SMART_NAME[] = "elm_web"; - -#define ELM_WEB_DATA_GET(o, sd) \ - Elm_Web_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_WEB_DATA_GET_OR_RETURN(o, ptr) \ - ELM_WEB_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_WEB_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_WEB_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_WEB_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), WEB_SMART_NAME, __func__)) \ - return - -#ifdef HAVE_ELEMENTARY_WEB -static Ewk_View_Smart_Class _ewk_view_parent_sc = - EWK_VIEW_SMART_CLASS_INIT_NULL; +static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL; typedef struct _View_Smart_Data View_Smart_Data; struct _View_Smart_Data { Ewk_View_Smart_Data base; struct - { - Evas_Event_Mouse_Down event; - Evas_Coord x, y; - unsigned int move_count; - Ecore_Timer *longpress_timer; - Ecore_Animator *pan_anim; - } mouse; + { + Evas_Event_Mouse_Down event; + Evas_Coord x, y; + unsigned int move_count; + Ecore_Timer *longpress_timer; + Ecore_Animator *pan_anim; + } mouse; }; #endif -typedef struct _Elm_Web_Smart_Data Elm_Web_Smart_Data; -struct _Elm_Web_Smart_Data +typedef struct _Widget_Data Widget_Data; +struct _Widget_Data { - Elm_Widget_Smart_Data base; /* base widget smart data as - * first member obligatory, as - * we're inheriting from it */ - + Evas_Object *self; #ifdef HAVE_ELEMENTARY_WEB + Evas_Object *ewk_view; struct - { - Elm_Web_Window_Open window_create; - void *window_create_data; - Elm_Web_Dialog_Alert alert; - void *alert_data; - Elm_Web_Dialog_Confirm confirm; - void *confirm_data; - Elm_Web_Dialog_Prompt prompt; - void *prompt_data; - Elm_Web_Dialog_File_Selector file_selector; - void *file_selector_data; - Elm_Web_Console_Message console_message; - void *console_message_data; - } hook; - + { + Elm_Web_Window_Open window_create; + void *window_create_data; + Elm_Web_Dialog_Alert alert; + void *alert_data; + Elm_Web_Dialog_Confirm confirm; + void *confirm_data; + Elm_Web_Dialog_Prompt prompt; + void *prompt_data; + Elm_Web_Dialog_File_Selector file_selector; + void *file_selector_data; + Elm_Web_Console_Message console_message; + void *console_message_data; + } hook; Elm_Win_Keyboard_Mode input_method; - struct - { - Elm_Web_Zoom_Mode mode; - float current; - float min, max; - Eina_Bool no_anim; - Ecore_Timer *timer; - } zoom; - + { + Elm_Web_Zoom_Mode mode; + float current; + float min, max; + Eina_Bool no_anim; + Ecore_Timer *timer; + } zoom; struct - { - struct - { - int x, y; - } start, end; - Ecore_Animator *animator; - } bring_in; - + { + struct + { + int x, y; + } start, end; + Ecore_Animator *animator; + } bring_in; Eina_Bool tab_propagate : 1; Eina_Bool inwin_mode : 1; +#else + Evas_Object *label; #endif }; @@ -125,26 +86,26 @@ typedef struct _Dialog_Data Dialog_Data; struct _Dialog_Data { enum Dialog_Type type; - - Evas_Object *dialog; - Evas_Object *box; - Evas_Object *bt_ok, *bt_cancel; - Evas_Object *entry; - Evas_Object *file_sel; - - Eina_Bool *response; - char **entry_value; - Eina_List **selected_files; + Evas_Object *dialog; + Evas_Object *box; + Evas_Object *bt_ok, *bt_cancel; + Evas_Object *entry; + Evas_Object *file_sel; + + Eina_Bool *response; + char **entry_value; + Eina_List **selected_files; }; struct _Elm_Web_Callback_Proxy_Context { - const char *name; + const char *name; Evas_Object *obj; }; typedef struct _Elm_Web_Callback_Proxy_Context Elm_Web_Callback_Proxy_Context; -static const Evas_Smart_Cb_Description _elm_web_smart_callbacks[] = { +static const char *widtype = NULL; +static const Evas_Smart_Cb_Description _elm_web_callback_names[] = { { "download,request", "p" }, { "editorclient,contents,changed", "" }, { "editorclient,selection,changed", "" }, @@ -182,10 +143,6 @@ static const Evas_Smart_Cb_Description _elm_web_smart_callbacks[] = { { NULL, NULL } }; -EVAS_SMART_SUBCLASS_NEW - (WEB_SMART_NAME, _elm_web, Elm_Widget_Smart_Class, Elm_Widget_Smart_Class, - elm_widget_smart_class_get, _elm_web_smart_callbacks); - #ifdef HAVE_ELEMENTARY_WEB static char * _webkit_theme_find(const Eina_List *list) @@ -193,35 +150,28 @@ _webkit_theme_find(const Eina_List *list) const Eina_List *l; const char *th; - EINA_LIST_FOREACH (list, l, th) + EINA_LIST_FOREACH(list, l, th) { char *path = elm_theme_list_item_path_get(th, NULL); - if (!path) continue; - - if (edje_file_group_exists(path, "webkit/base")) return path; - + if (edje_file_group_exists(path, "webkit/base")) + return path; free(path); } return NULL; } - #endif -static Eina_Bool -_elm_web_smart_theme(Evas_Object *obj) +static void +_theme_hook(Evas_Object *obj) { #ifdef HAVE_ELEMENTARY_WEB - Elm_Theme *theme; + Elm_Theme *theme = elm_object_theme_get(obj); + Widget_Data *wd = elm_widget_data_get(obj); const Eina_List *themes; char *view_theme = NULL; - ELM_WEB_DATA_GET(obj, sd); - - if (!_elm_web_parent_sc->theme(obj)) return EINA_FALSE; - - theme = elm_object_theme_get(obj); themes = elm_theme_overlay_list_get(theme); view_theme = _webkit_theme_find(themes); if (view_theme) goto set; @@ -236,73 +186,64 @@ _elm_web_smart_theme(Evas_Object *obj) set: if (view_theme) { - ewk_view_theme_set(ELM_WIDGET_DATA(sd)->resize_obj, view_theme); + ewk_view_theme_set(wd->ewk_view, view_theme); free(view_theme); } else - ewk_view_theme_set - (ELM_WIDGET_DATA(sd)->resize_obj, WEBKIT_DATADIR "/themes/default.edj"); -#endif - + ewk_view_theme_set(wd->ewk_view, WEBKIT_DATADIR"/themes/default.edj"); +#else (void)obj; - - return EINA_TRUE; +#endif } -static Eina_Bool -_elm_web_smart_on_focus(Evas_Object *obj) +static void +_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { #ifdef HAVE_ELEMENTARY_WEB - Evas_Object *top; - - ELM_WEB_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *top = elm_widget_top_get(obj); - top = elm_widget_top_get(obj); + if (!wd) return; if (elm_object_focus_get(obj)) { - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE); - if (top) elm_win_keyboard_mode_set(top, sd->input_method); + evas_object_focus_set(wd->ewk_view, EINA_TRUE); + if (top) elm_win_keyboard_mode_set(top, wd->input_method); } else { - evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE); + evas_object_focus_set(wd->ewk_view, EINA_FALSE); if (top) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF); } #else (void)obj; #endif - - return EINA_TRUE; } static Eina_Bool -_elm_web_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { #ifdef HAVE_ELEMENTARY_WEB Evas_Event_Key_Down *ev = event_info; + Widget_Data *wd = elm_widget_data_get(obj); - ELM_WEB_DATA_GET(obj, sd); - + if (!wd) return EINA_FALSE; if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; if (elm_widget_disabled_get(obj)) return EINA_FALSE; - if ((!strcmp(ev->keyname, "Tab")) && (!sd->tab_propagate)) + if ((!strcmp(ev->keyname, "Tab")) && (!wd->tab_propagate)) { ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; return EINA_TRUE; } - else return EINA_FALSE; + else + return EINA_FALSE; #else + return EINA_FALSE; (void)obj; (void)type; (void)event_info; - - return EINA_FALSE; #endif } @@ -326,7 +267,7 @@ _view_pan_animator(void *data) sd->mouse.x = x; sd->mouse.y = y; -end: + end: return EINA_TRUE; } @@ -338,11 +279,10 @@ _view_smart_add(Evas_Object *obj) sd = calloc(1, sizeof(View_Smart_Data)); evas_object_smart_data_set(obj, sd); - _ewk_view_parent_sc.sc.add(obj); + _parent_sc.sc.add(obj); ewk_view_history_enable_set(obj, EINA_TRUE); ewk_history_limit_set(ewk_view_history_get(obj), 100); - // TODO: auto toggle between smooth/nearest during bring-in animations //ewk_view_zoom_weak_smooth_scale_set(obj, EINA_TRUE); } @@ -357,7 +297,7 @@ _view_smart_del(Evas_Object *obj) if (sd->mouse.pan_anim) ecore_animator_del(sd->mouse.pan_anim); - _ewk_view_parent_sc.sc.del(obj); + _parent_sc.sc.del(obj); } static Eina_Bool @@ -367,24 +307,21 @@ _view_longpress_timer(void *data) sd->mouse.move_count = 0; sd->mouse.longpress_timer = NULL; - return ECORE_CALLBACK_CANCEL; } static Eina_Bool -_view_smart_mouse_down(Ewk_View_Smart_Data *esd, - const Evas_Event_Mouse_Down *event) +_view_smart_mouse_down(Ewk_View_Smart_Data *esd, const Evas_Event_Mouse_Down *event) { // TODO: mimic elm_scroller and like // TODO-minor: offer hook? View_Smart_Data *sd = (View_Smart_Data *)esd; if (event->button != 1) - return _ewk_view_parent_sc.mouse_down(esd, event); + return _parent_sc.mouse_down(esd, event); sd->mouse.pan_anim = ecore_animator_add(_view_pan_animator, sd); - sd->mouse.longpress_timer = ecore_timer_add - (_elm_config->longpress_timeout, _view_longpress_timer, sd); + sd->mouse.longpress_timer = ecore_timer_add(_elm_config->longpress_timeout, _view_longpress_timer, sd); sd->mouse.move_count = 1; sd->mouse.x = event->canvas.x; sd->mouse.y = event->canvas.y; @@ -394,8 +331,7 @@ _view_smart_mouse_down(Ewk_View_Smart_Data *esd, } static Eina_Bool -_view_smart_mouse_up(Ewk_View_Smart_Data *esd, - const Evas_Event_Mouse_Up *event) +_view_smart_mouse_up(Ewk_View_Smart_Data *esd, const Evas_Event_Mouse_Up *event) { // TODO: mimic elm_scroller and like // TODO-minor: offer hook? @@ -407,7 +343,7 @@ _view_smart_mouse_up(Ewk_View_Smart_Data *esd, sd->mouse.pan_anim = NULL; if (sd->mouse.longpress_timer) - _ewk_view_parent_sc.mouse_down(esd, &sd->mouse.event); + _parent_sc.mouse_down(esd, &sd->mouse.event); else return EINA_TRUE; } @@ -419,17 +355,15 @@ _view_smart_mouse_up(Ewk_View_Smart_Data *esd, } sd->mouse.move_count = 0; - return _ewk_view_parent_sc.mouse_up(esd, event); + return _parent_sc.mouse_up(esd, event); } static Eina_Bool -_view_smart_mouse_move(Ewk_View_Smart_Data *esd, - const Evas_Event_Mouse_Move *event) +_view_smart_mouse_move(Ewk_View_Smart_Data *esd, const Evas_Event_Mouse_Move *event) { // TODO: mimic elm_scroller and like // TODO-minor: offer hook? View_Smart_Data *sd = (View_Smart_Data *)esd; - sd->mouse.move_count++; if (sd->mouse.longpress_timer && @@ -445,24 +379,19 @@ _view_smart_mouse_move(Ewk_View_Smart_Data *esd, return EINA_FALSE; } - return _ewk_view_parent_sc.mouse_move(esd, event); + return _parent_sc.mouse_move(esd, event); } static Evas_Object * -_view_smart_window_create(Ewk_View_Smart_Data *vsd, - Eina_Bool javascript, - const Ewk_Window_Features *window_features) +_view_smart_window_create(Ewk_View_Smart_Data *sd, Eina_Bool javascript, const Ewk_Window_Features *window_features) { Evas_Object *new; - Evas_Object *obj = evas_object_smart_parent_get(vsd->self); - - ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - if (!sd->hook.window_create) return NULL; + Evas_Object *obj = evas_object_smart_parent_get(sd->self); + Widget_Data *wd = elm_widget_data_get(obj); - new = sd->hook.window_create - (sd->hook.window_create_data, obj, javascript, - (const Elm_Web_Window_Features *)window_features); + if (!wd->hook.window_create) return NULL; + new = wd->hook.window_create(wd->hook.window_create_data, obj, javascript, + (const Elm_Web_Window_Features *)window_features); if (new) return elm_web_webkit_view_get(new); return NULL; @@ -472,40 +401,31 @@ static void _view_smart_window_close(Ewk_View_Smart_Data *sd) { Evas_Object *obj = evas_object_smart_parent_get(sd->self); - - ELM_WEB_CHECK(obj); - evas_object_smart_callback_call(obj, "windows,close,request", NULL); } static void -_bt_close(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) +_bt_close(void *data, Evas_Object *obj, void *event_info __UNUSED__) { Dialog_Data *d = data; *d->response = (obj == d->bt_ok); if ((d->type == DIALOG_PROMPT) && (*d->response == EINA_TRUE)) *d->entry_value = strdup(elm_entry_entry_get(d->entry)); - evas_object_del(d->dialog); } static void -_file_sel_done(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_file_sel_done(void *data, Evas_Object *obj __UNUSED__, void *event_info) { Dialog_Data *d = data; - if (event_info) { *d->selected_files = eina_list_append(NULL, strdup(event_info)); *d->response = EINA_TRUE; } - else *d->response = EINA_FALSE; - + else + *d->response = EINA_FALSE; evas_object_del(d->dialog); free(d); } @@ -514,44 +434,42 @@ static Dialog_Data * _dialog_new(Evas_Object *parent) { Dialog_Data *d; - - ELM_WEB_DATA_GET(parent, sd); + Widget_Data *wd = elm_widget_data_get(parent); d = calloc(1, sizeof(Dialog_Data)); if (!d) return NULL; - if (!parent || !sd->inwin_mode) + if (!parent || !wd->inwin_mode) { Evas_Object *bg; d->dialog = elm_win_add(NULL, "elm-web-popup", ELM_WIN_DIALOG_BASIC); - evas_object_smart_callback_add - (d->dialog, "delete,request", _bt_close, d); + evas_object_smart_callback_add(d->dialog, "delete,request", + _bt_close, d); bg = elm_bg_add(d->dialog); - evas_object_size_hint_weight_set - (bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); elm_win_resize_object_add(d->dialog, bg); evas_object_show(bg); d->box = elm_box_add(d->dialog); - evas_object_size_hint_weight_set - (d->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(d->box, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); elm_win_resize_object_add(d->dialog, d->box); evas_object_show(d->box); } else { Evas_Object *win = elm_widget_top_get(parent); - d->dialog = elm_win_inwin_add(win); elm_object_style_set(d->dialog, "minimal"); - evas_object_size_hint_weight_set - (d->dialog, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(d->dialog, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); d->box = elm_box_add(win); - evas_object_size_hint_weight_set - (d->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(d->box, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); elm_win_inwin_content_set(d->dialog, d->box); evas_object_show(d->box); } @@ -560,30 +478,13 @@ _dialog_new(Evas_Object *parent) } static Evas_Object * -_run_dialog(Evas_Object *parent, - enum Dialog_Type type, - const char *message, - const char *default_entry_value, - char **entry_value, - Eina_Bool allows_multiple_files __UNUSED__, - Eina_List *accept_types __UNUSED__, - Eina_List **selected_filenames, - Eina_Bool *response) +_run_dialog(Evas_Object *parent, enum Dialog_Type type, const char *message, const char *default_entry_value, char **entry_value, Eina_Bool allows_multiple_files __UNUSED__, Eina_List *accept_types __UNUSED__, Eina_List **selected_filenames, Eina_Bool *response) { - Evas_Object *lb; - Evas_Object *obj; - Dialog_Data *dialog_data; - - EINA_SAFETY_ON_TRUE_RETURN_VAL - ((type != DIALOG_PROMPT) && (!!default_entry_value), EINA_FALSE); - EINA_SAFETY_ON_TRUE_RETURN_VAL - ((type != DIALOG_PROMPT) && (!!entry_value), EINA_FALSE); - - obj = evas_object_smart_parent_get(parent); - - ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); + EINA_SAFETY_ON_TRUE_RETURN_VAL((type != DIALOG_PROMPT) && (!!default_entry_value), EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL((type != DIALOG_PROMPT) && (!!entry_value), EINA_FALSE); - dialog_data = _dialog_new(obj); + Dialog_Data *dialog_data = _dialog_new(evas_object_smart_parent_get(parent)); + Evas_Object *lb; if (type != DIALOG_FILE_SELECTOR) { @@ -603,10 +504,8 @@ _run_dialog(Evas_Object *parent, dialog_data->bt_ok = elm_button_add(dialog_data->box); elm_object_text_set(dialog_data->bt_ok, "Close"); elm_box_pack_end(dialog_data->box, dialog_data->bt_ok); - evas_object_size_hint_align_set - (dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_smart_callback_add - (dialog_data->bt_ok, "clicked", _bt_close, dialog_data); + evas_object_size_hint_align_set(dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(dialog_data->bt_ok, "clicked", _bt_close, dialog_data); evas_object_show(dialog_data->bt_ok); } else if (type == DIALOG_FILE_SELECTOR) @@ -638,10 +537,8 @@ _run_dialog(Evas_Object *parent, elm_entry_single_line_set(dialog_data->entry, EINA_TRUE); elm_entry_scrollable_set(dialog_data->entry, EINA_TRUE); elm_entry_entry_set(dialog_data->entry, default_entry_value); - evas_object_size_hint_align_set - (dialog_data->entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_weight_set - (dialog_data->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(dialog_data->entry, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(dialog_data->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_box_pack_end(dialog_data->box, dialog_data->entry); evas_object_show(dialog_data->entry); } @@ -651,35 +548,28 @@ _run_dialog(Evas_Object *parent, Evas_Object *bx_h = elm_box_add(dialog_data->box); elm_box_horizontal_set(bx_h, 1); elm_box_pack_end(dialog_data->box, bx_h); - evas_object_size_hint_weight_set - (bx_h, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (bx_h, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bx_h, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bx_h, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(bx_h); dialog_data->bt_cancel = elm_button_add(bx_h); elm_object_text_set(dialog_data->bt_cancel, "Cancel"); elm_box_pack_end(bx_h, dialog_data->bt_cancel); - evas_object_size_hint_weight_set - (dialog_data->bt_cancel, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (dialog_data->bt_cancel, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_smart_callback_add - (dialog_data->bt_cancel, "clicked", _bt_close, dialog_data); + evas_object_size_hint_weight_set(dialog_data->bt_cancel, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(dialog_data->bt_cancel, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(dialog_data->bt_cancel, "clicked", _bt_close, dialog_data); evas_object_show(dialog_data->bt_cancel); dialog_data->bt_ok = elm_button_add(bx_h); elm_object_text_set(dialog_data->bt_ok, "Ok"); elm_box_pack_end(bx_h, dialog_data->bt_ok); - evas_object_size_hint_weight_set - (dialog_data->bt_ok, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set - (dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_smart_callback_add - (dialog_data->bt_ok, "clicked", _bt_close, dialog_data); + evas_object_size_hint_weight_set(dialog_data->bt_ok, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(dialog_data->bt_ok, "clicked", _bt_close, dialog_data); evas_object_show(dialog_data->bt_ok); } - else return EINA_FALSE; + else + return EINA_FALSE; } evas_object_show(dialog_data->dialog); @@ -688,10 +578,7 @@ _run_dialog(Evas_Object *parent, } static void -_dialog_del_cb(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_dialog_del_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { ecore_main_loop_quit(); } @@ -699,108 +586,92 @@ _dialog_del_cb(void *data __UNUSED__, static void _exec_dialog(Evas_Object *dialog) { - evas_object_event_callback_add - (dialog, EVAS_CALLBACK_DEL, _dialog_del_cb, NULL); + evas_object_event_callback_add(dialog, EVAS_CALLBACK_DEL, _dialog_del_cb, + NULL); ecore_main_loop_begin(); } -/* - * called by ewk_view when javascript called alert() +/* called by ewk_view when javascript called alert() + * */ static void -_view_smart_run_javascript_alert(Ewk_View_Smart_Data *esd, - Evas_Object *frame __UNUSED__, - const char *message) +_view_smart_run_javascript_alert(Ewk_View_Smart_Data *esd, Evas_Object *frame __UNUSED__, const char *message) { - View_Smart_Data *vsd = (View_Smart_Data *)esd; - Evas_Object *view = vsd->base.self; + View_Smart_Data *sd = (View_Smart_Data *)esd; + Evas_Object *view = sd->base.self; Evas_Object *obj = evas_object_smart_parent_get(view); Evas_Object *diag = NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_Bool response = EINA_FALSE; - ELM_WEB_DATA_GET_OR_RETURN(obj, sd); - - if (sd->hook.alert) - diag = sd->hook.alert(sd->hook.alert_data, obj, message); + if (wd->hook.alert) + diag = wd->hook.alert(wd->hook.alert_data, obj, message); else diag = _run_dialog(view, DIALOG_ALERT, message, NULL, NULL, EINA_FALSE, NULL, NULL, &response); if (diag) _exec_dialog(diag); } -/* - * called by ewk_view when javascript called confirm() +/* called by ewk_view when javascript called confirm() + * */ static Eina_Bool -_view_smart_run_javascript_confirm(Ewk_View_Smart_Data *esd, - Evas_Object *frame __UNUSED__, - const char *message) +_view_smart_run_javascript_confirm(Ewk_View_Smart_Data *esd, Evas_Object *frame __UNUSED__, const char *message) { - View_Smart_Data *vsd = (View_Smart_Data *)esd; - Evas_Object *view = vsd->base.self; + View_Smart_Data *sd = (View_Smart_Data *)esd; + Evas_Object *view = sd->base.self; Evas_Object *obj = evas_object_smart_parent_get(view); Evas_Object *diag = NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_Bool response = EINA_FALSE; - ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - if (sd->hook.confirm) - diag = sd->hook.confirm(sd->hook.confirm_data, obj, message, &response); + if (wd->hook.confirm) + diag = wd->hook.confirm(wd->hook.confirm_data, obj, message, &response); else - diag = _run_dialog(view, DIALOG_CONFIRM, message, NULL, NULL, EINA_FALSE, - NULL, NULL, &response); + diag = _run_dialog(view, DIALOG_CONFIRM, message, NULL, NULL, EINA_FALSE, + NULL, NULL, &response); if (diag) _exec_dialog(diag); return response; } -/* - * called by ewk_view when javascript called confirm() +/* called by ewk_view when javascript called confirm() + * */ static Eina_Bool -_view_smart_run_javascript_prompt(Ewk_View_Smart_Data *esd, - Evas_Object *frame __UNUSED__, - const char *message, - const char *default_value, - char **value) -{ - View_Smart_Data *vsd = (View_Smart_Data *)esd; - Evas_Object *view = vsd->base.self; +_view_smart_run_javascript_prompt(Ewk_View_Smart_Data *esd, Evas_Object *frame __UNUSED__, const char *message, const char *default_value, char **value) +{ + View_Smart_Data *sd = (View_Smart_Data *)esd; + Evas_Object *view = sd->base.self; Evas_Object *obj = evas_object_smart_parent_get(view); Evas_Object *diag = NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_Bool response = EINA_FALSE; - ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - if (sd->hook.prompt) - diag = sd->hook.prompt(sd->hook.prompt_data, obj, message, default_value, + if (wd->hook.prompt) + diag = wd->hook.prompt(wd->hook.prompt_data, obj, message, default_value, value, &response); else diag = _run_dialog(view, DIALOG_PROMPT, message, default_value, value, EINA_FALSE, NULL, NULL, &response); if (diag) _exec_dialog(diag); if (!response) - *value = NULL; + *value = NULL; return EINA_TRUE; } static Eina_Bool -_view_smart_run_open_panel(Ewk_View_Smart_Data *esd, - Evas_Object *frame __UNUSED__, - Eina_Bool allows_multiple_files, - Eina_List *accept_types, - Eina_List **selected_filenames) -{ - View_Smart_Data *vsd = (View_Smart_Data *)esd; - Evas_Object *view = vsd->base.self; +_view_smart_run_open_panel(Ewk_View_Smart_Data *esd, Evas_Object *frame __UNUSED__, Eina_Bool allows_multiple_files, Eina_List *accept_types, Eina_List **selected_filenames) +{ + View_Smart_Data *sd = (View_Smart_Data *)esd; + Evas_Object *view = sd->base.self; Evas_Object *obj = evas_object_smart_parent_get(view); Evas_Object *diag = NULL; + Widget_Data *wd = elm_widget_data_get(obj); Eina_Bool response = EINA_FALSE; - ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - if (sd->hook.file_selector) - diag = sd->hook.file_selector(sd->hook.file_selector_data, obj, + if (wd->hook.file_selector) + diag = wd->hook.file_selector(wd->hook.file_selector_data, obj, allows_multiple_files, accept_types, selected_filenames, &response); else @@ -813,42 +684,32 @@ _view_smart_run_open_panel(Ewk_View_Smart_Data *esd, } static void -_view_smart_add_console_message(Ewk_View_Smart_Data *esd, - const char *message, - unsigned int line_number, - const char *source_id) +_view_smart_add_console_message(Ewk_View_Smart_Data *esd, const char *message, unsigned int line_number, const char *source_id) { Evas_Object *obj = evas_object_smart_parent_get(esd->self); + Widget_Data *wd = elm_widget_data_get(obj); - ELM_WEB_DATA_GET_OR_RETURN(obj, sd); - - if (sd->hook.console_message) - sd->hook.console_message(sd->hook.console_message_data, obj, message, + if (wd->hook.console_message) + wd->hook.console_message(wd->hook.console_message_data, obj, message, line_number, source_id); } static Eina_Bool -_view_smart_focus_can_cycle(Ewk_View_Smart_Data *sd, - Ewk_Focus_Direction direction) +_view_smart_focus_can_cycle(Ewk_View_Smart_Data *sd, Ewk_Focus_Direction direction) { Evas_Object *obj = evas_object_smart_parent_get(sd->self); - - ELM_WEB_CHECK(obj) EINA_FALSE; - Elm_Focus_Direction dir; switch (direction) { case EWK_FOCUS_DIRECTION_FORWARD: - dir = ELM_FOCUS_NEXT; - break; - + dir = ELM_FOCUS_NEXT; + break; case EWK_FOCUS_DIRECTION_BACKWARD: - dir = ELM_FOCUS_PREVIOUS; - break; - + dir = ELM_FOCUS_PREVIOUS; + break; default: - return EINA_FALSE; + return EINA_FALSE; } elm_widget_focus_cycle(elm_widget_parent_get(obj), dir); @@ -866,14 +727,13 @@ _view_smart_focus_can_cycle(Ewk_View_Smart_Data *sd, Evas_Object * _view_add(Evas_Object *parent) { - Evas *canvas = evas_object_evas_get(parent); static Evas_Smart *smart = NULL; + Evas *canvas = evas_object_evas_get(parent); Evas_Object *view; if (!smart) { - static Ewk_View_Smart_Class api = - EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Elementary"); + static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Elementary"); #ifndef TILED_BACKING_STORE ewk_view_single_smart_set(&api); @@ -881,7 +741,7 @@ _view_add(Evas_Object *parent) ewk_view_tiled_smart_set(&api); #endif - _ewk_view_parent_sc = api; + _parent_sc = api; // TODO: check every api method and provide overrides with hooks! // TODO: hooks should provide extension points @@ -923,98 +783,83 @@ _view_add(Evas_Object *parent) } static void -_ewk_view_inputmethod_change_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_ewk_view_inputmethod_change_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info) { - Elm_Web_Smart_Data *sd = data; - Evas_Object *top = elm_widget_top_get(ELM_WIDGET_DATA(sd)->obj); + Widget_Data *wd = data; + Evas_Object *top = elm_widget_top_get(wd->self); if (!top) return; if (event_info) - sd->input_method = ELM_WIN_KEYBOARD_ON; + wd->input_method = ELM_WIN_KEYBOARD_ON; else - sd->input_method = ELM_WIN_KEYBOARD_OFF; - elm_win_keyboard_mode_set(top, sd->input_method); + wd->input_method = ELM_WIN_KEYBOARD_OFF; + elm_win_keyboard_mode_set(top, wd->input_method); } static void -_ewk_view_load_started_cb(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) +_ewk_view_load_started_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { _ewk_view_inputmethod_change_cb(data, obj, (void *)(long)EINA_FALSE); } static void -_ewk_view_load_finished_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_ewk_view_load_finished_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info) { - Elm_Web_Smart_Data *sd = data; + Widget_Data *wd = data; - if (event_info) return; + if (event_info) + return; - if (sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL) + if (wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL) { - float tz = sd->zoom.current; - sd->zoom.current = 0.0; - elm_web_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz); + float tz = wd->zoom.current; + wd->zoom.current = 0.0; + elm_web_zoom_set(wd->self, tz); } } static void -_ewk_view_viewport_changed_cb(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) +_ewk_view_viewport_changed_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Elm_Web_Smart_Data *sd = data; + Widget_Data *wd = data; - if (sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL) + if (wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL) { ewk_view_zoom_set(obj, 1.0, 0, 0); - sd->zoom.no_anim = EINA_TRUE; + wd->zoom.no_anim = EINA_TRUE; } } static Eina_Bool _restore_zoom_mode_timer_cb(void *data) { - Elm_Web_Smart_Data *sd = data; - float tz = sd->zoom.current; - - sd->zoom.timer = NULL; - sd->zoom.current = 0.0; - sd->zoom.no_anim = EINA_TRUE; - elm_web_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz); - + Widget_Data *wd = data; + float tz = wd->zoom.current; + wd->zoom.timer = NULL; + wd->zoom.current = 0.0; + wd->zoom.no_anim = EINA_TRUE; + elm_web_zoom_set(wd->self, tz); return EINA_FALSE; } static Eina_Bool _reset_zoom_timer_cb(void *data) { - Elm_Web_Smart_Data *sd = data; - - sd->zoom.timer = ecore_timer_add(0.0, _restore_zoom_mode_timer_cb, sd); - ewk_view_zoom_set(ELM_WIDGET_DATA(sd)->resize_obj, 1.0, 0, 0); - + Widget_Data *wd = data; + wd->zoom.timer = ecore_timer_add(0.0, _restore_zoom_mode_timer_cb, wd); + ewk_view_zoom_set(wd->ewk_view, 1.0, 0, 0); return EINA_FALSE; } static void -_ewk_view_resized_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_ewk_view_resized_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Web_Smart_Data *sd = data; - - if (!(sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)) + Widget_Data *wd = data; + if (!(wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)) return; - - if (sd->zoom.timer) - ecore_timer_del(sd->zoom.timer); - sd->zoom.timer = ecore_timer_add(0.5, _reset_zoom_timer_cb, sd); + if (wd->zoom.timer) + ecore_timer_del(wd->zoom.timer); + wd->zoom.timer = ecore_timer_add(0.5, _reset_zoom_timer_cb, wd); } static void @@ -1024,56 +869,48 @@ _popup_del_job(void *data) } static void -_popup_will_delete(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) +_popup_will_delete(void *data, Evas_Object *obj, void *event_info __UNUSED__) { ecore_job_add(_popup_del_job, data); evas_object_smart_callback_del(obj, "popup,willdelete", _popup_will_delete); } static void -_popup_item_selected(void *data, - Evas_Object *obj, - void *event_info __UNUSED__) +_popup_item_selected(void *data, Evas_Object *obj, void *event_info __UNUSED__) { + Evas_Object *view = data; Elm_Object_Item *list_it = elm_list_selected_item_get(obj); const Eina_List *itr, *list = elm_list_items_get(obj); - Evas_Object *view = data; - int i = 0; void *d; + int i = 0; - EINA_LIST_FOREACH (list, itr, d) - { - if (d == list_it) - break; + EINA_LIST_FOREACH(list, itr, d) + { + if (d == list_it) + break; - i++; - } + i++; + } ewk_view_popup_selected_set(view, i); ewk_view_popup_destroy(view); } static void -_popup_dismiss_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_popup_dismiss_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { ewk_view_popup_destroy(data); } static void -_ewk_view_popup_create_cb(void *data, - Evas_Object *obj, - void *event_info) +_ewk_view_popup_create_cb(void *data, Evas_Object *obj, void *event_info) { - Elm_Web_Smart_Data *sd = data; - Evas_Object *notify, *list; + Widget_Data *wd = data; Ewk_Menu *m = event_info; - Ewk_Menu_Item *it; Elm_Web_Menu m2; + Ewk_Menu_Item *it; Eina_List *itr; + Evas_Object *notify, *list; m2.items = m->items; m2.x = m->x; @@ -1081,9 +918,9 @@ _ewk_view_popup_create_cb(void *data, m2.width = m->width; m2.height = m->height; m2.handled = EINA_FALSE; - evas_object_smart_callback_call - (ELM_WIDGET_DATA(sd)->obj, "popup,create", &m2); - if (m2.handled) return; + evas_object_smart_callback_call(wd->self, "popup,create", &m2); + if (m2.handled) + return; notify = elm_notify_add(obj); elm_notify_allow_events_set(notify, EINA_FALSE); @@ -1098,32 +935,27 @@ _ewk_view_popup_create_cb(void *data, elm_object_content_set(notify, list); evas_object_show(list); - EINA_LIST_FOREACH (m->items, itr, it) - elm_list_item_append(list, it->text, NULL, NULL, _popup_item_selected, - obj); + EINA_LIST_FOREACH(m->items, itr, it) + elm_list_item_append(list, it->text, NULL, NULL, _popup_item_selected, + obj); elm_list_go(list); evas_object_show(notify); - evas_object_smart_callback_add - (obj, "popup,willdelete", _popup_will_delete, notify); - evas_object_smart_callback_add - (notify, "block,clicked", _popup_dismiss_cb, obj); + evas_object_smart_callback_add(obj, "popup,willdelete", _popup_will_delete, + notify); + evas_object_smart_callback_add(notify, "block,clicked", _popup_dismiss_cb, + obj); } static void -_view_smart_callback_proxy_free_cb(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_view_smart_callback_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { free(data); } static void -_view_smart_callback_proxy_cb(void *data, - Evas_Object *obj __UNUSED__, - void *event_info) +_view_smart_callback_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info) { Elm_Web_Callback_Proxy_Context *ctxt = data; @@ -1131,23 +963,20 @@ _view_smart_callback_proxy_cb(void *data, } static void -_view_smart_callback_proxy(Evas_Object *view, - Evas_Object *parent) +_view_smart_callback_proxy(Evas_Object *view, Evas_Object *parent) { const Evas_Smart_Cb_Description **cls_descs, **inst_descs; unsigned int cls_count, inst_count, total; Elm_Web_Callback_Proxy_Context *ctxt; - evas_object_smart_callbacks_descriptions_get - (view, &cls_descs, &cls_count, &inst_descs, &inst_count); + evas_object_smart_callbacks_descriptions_get(view, &cls_descs, &cls_count, + &inst_descs, &inst_count); total = cls_count + inst_count; if (!total) return; - ctxt = malloc(sizeof(Elm_Web_Callback_Proxy_Context) * total); if (!ctxt) return; - - evas_object_event_callback_add - (view, EVAS_CALLBACK_FREE, _view_smart_callback_proxy_free_cb, ctxt); + evas_object_event_callback_add(view, EVAS_CALLBACK_FREE, + _view_smart_callback_proxy_free_cb, ctxt); for (; cls_count > 0; cls_count--, cls_descs++, ctxt++) { @@ -1156,8 +985,8 @@ _view_smart_callback_proxy(Evas_Object *view, continue; ctxt->name = d->name; ctxt->obj = parent; - evas_object_smart_callback_add - (view, d->name, _view_smart_callback_proxy_cb, ctxt); + evas_object_smart_callback_add(view, d->name, + _view_smart_callback_proxy_cb, ctxt); } for (; inst_count > 0; inst_count--, inst_descs++, ctxt++) @@ -1165,37 +994,34 @@ _view_smart_callback_proxy(Evas_Object *view, const Evas_Smart_Cb_Description *d = *inst_descs; ctxt->name = d->name; ctxt->obj = parent; - evas_object_smart_callback_add - (view, d->name, _view_smart_callback_proxy_cb, ctxt); + evas_object_smart_callback_add(view, d->name, + _view_smart_callback_proxy_cb, ctxt); } } static Eina_Bool -_bring_in_anim_cb(void *data, - double pos) +_bring_in_anim_cb(void *data, double pos) { - Elm_Web_Smart_Data *sd = data; - Evas_Object *frame = - ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = data; + Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view); int sx, sy, rx, ry; - sx = sd->bring_in.start.x; - sy = sd->bring_in.start.y; - rx = (sd->bring_in.end.x - sx) * pos; - ry = (sd->bring_in.end.y - sy) * pos; + sx = wd->bring_in.start.x; + sy = wd->bring_in.start.y; + rx = (wd->bring_in.end.x - sx) * pos; + ry = (wd->bring_in.end.y - sy) * pos; ewk_frame_scroll_set(frame, rx + sx, ry + sy); if (pos == 1.0) { - sd->bring_in.end.x = sd->bring_in.end.y = sd->bring_in.start.x = - sd->bring_in.start.y = 0; - sd->bring_in.animator = NULL; + wd->bring_in.end.x = wd->bring_in.end.y = wd->bring_in.start.x = + wd->bring_in.start.y = 0; + wd->bring_in.animator = NULL; } return EINA_TRUE; } - #endif #ifdef HAVE_ELEMENTARY_WEB @@ -1225,109 +1051,73 @@ elm_need_web(void) #endif } -static void -_elm_web_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Web_Smart_Data); - -#ifdef HAVE_ELEMENTARY_WEB - ELM_WIDGET_DATA(priv)->resize_obj = _view_add(obj); -#else - ELM_WIDGET_DATA(priv)->resize_obj = elm_label_add(obj); - elm_object_text_set - (ELM_WIDGET_DATA(priv)->resize_obj, "WebKit not supported!"); - evas_object_show(ELM_WIDGET_DATA(priv)->resize_obj); -#endif - - _elm_web_parent_sc->base.add(obj); - -#ifdef HAVE_ELEMENTARY_WEB - ewk_view_setting_user_agent_set - (ELM_WIDGET_DATA(priv)->resize_obj, ELM_WEB_USER_AGENT); - - priv->input_method = ELM_WIN_KEYBOARD_OFF; - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "inputmethod,changed", - _ewk_view_inputmethod_change_cb, priv); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "load,started", - _ewk_view_load_started_cb, priv); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "popup,create", - _ewk_view_popup_create_cb, priv); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "load,finished", - _ewk_view_load_finished_cb, priv); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "viewport,changed", - _ewk_view_viewport_changed_cb, priv); - evas_object_smart_callback_add - (ELM_WIDGET_DATA(priv)->resize_obj, "view,resized", - _ewk_view_resized_cb, priv); - - priv->tab_propagate = EINA_FALSE; - priv->inwin_mode = _elm_config->inwin_dialogs_enable; - priv->zoom.min = - ewk_view_zoom_range_min_get(ELM_WIDGET_DATA(priv)->resize_obj); - priv->zoom.max = - ewk_view_zoom_range_max_get(ELM_WIDGET_DATA(priv)->resize_obj); - priv->zoom.current = 1.0; - - _view_smart_callback_proxy(ELM_WIDGET_DATA(priv)->resize_obj, obj); - _elm_web_smart_theme(obj); - - elm_widget_can_focus_set(obj, EINA_TRUE); -#endif -} - -static void -_elm_web_smart_del(Evas_Object *obj) -{ - ELM_WEB_DATA_GET(obj, sd); - -#ifdef HAVE_ELEMENTARY_WEB - if (sd->zoom.timer) - { - ecore_timer_del(sd->zoom.timer); - sd->zoom.timer = NULL; - } - - if (sd->bring_in.animator) - { - ecore_animator_del(sd->bring_in.animator); - sd->bring_in.animator = NULL; - } -#endif - - _elm_web_parent_sc->base.del(obj); /* handles freeing sd */ -} - -static void -_elm_web_smart_set_user(Elm_Widget_Smart_Class *sc) -{ - sc->base.add = _elm_web_smart_add; - sc->base.del = _elm_web_smart_del; - - sc->on_focus = _elm_web_smart_on_focus; - sc->theme = _elm_web_smart_theme; - sc->event = _elm_web_smart_event; -} - EAPI Evas_Object * elm_web_add(Evas_Object *parent) { - Evas *e; Evas_Object *obj; + Widget_Data *wd; + Evas *e; EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + wd = calloc(1, sizeof(Widget_Data)); e = evas_object_evas_get(parent); - if (!e) return NULL; + if (!e) + return NULL; + obj = elm_widget_add(e); + wd->self = obj; - obj = evas_object_smart_add(e, _elm_web_smart_class_new()); + if (!widtype) + { + widtype = eina_stringshare_add("web"); + elm_widget_type_register(&widtype); + } + + elm_widget_type_set(obj, widtype); + elm_widget_sub_object_add(parent, obj); + elm_widget_theme_hook_set(obj, _theme_hook); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_data_set(obj, wd); + elm_widget_can_focus_set(obj, EINA_TRUE); + +#ifdef HAVE_ELEMENTARY_WEB + wd->ewk_view = _view_add(obj); + ewk_view_setting_user_agent_set(wd->ewk_view, ELM_WEB_USER_AGENT); + + wd->input_method = ELM_WIN_KEYBOARD_OFF; + evas_object_smart_callback_add(wd->ewk_view, "inputmethod,changed", + _ewk_view_inputmethod_change_cb, wd); + evas_object_smart_callback_add(wd->ewk_view, "load,started", + _ewk_view_load_started_cb, wd); + evas_object_smart_callback_add(wd->ewk_view, "popup,create", + _ewk_view_popup_create_cb, wd); + evas_object_smart_callback_add(wd->ewk_view, "load,finished", + _ewk_view_load_finished_cb, wd); + evas_object_smart_callback_add(wd->ewk_view, "viewport,changed", + _ewk_view_viewport_changed_cb, wd); + evas_object_smart_callback_add(wd->ewk_view, "view,resized", + _ewk_view_resized_cb, wd); + + elm_widget_resize_object_set(obj, wd->ewk_view); + + wd->tab_propagate = EINA_FALSE; + wd->inwin_mode = _elm_config->inwin_dialogs_enable; + wd->zoom.min = ewk_view_zoom_range_min_get(wd->ewk_view); + wd->zoom.max = ewk_view_zoom_range_max_get(wd->ewk_view); + wd->zoom.current = 1.0; + + _view_smart_callback_proxy(wd->ewk_view, wd->self); + evas_object_smart_callbacks_descriptions_set(obj, _elm_web_callback_names); + + _theme_hook(obj); - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); +#else + wd->label = elm_label_add(obj); + elm_object_text_set(wd->label, "WebKit not supported!"); + evas_object_show(wd->label); + elm_widget_resize_object_set(obj, wd->label); +#endif return obj; } @@ -1335,12 +1125,11 @@ elm_web_add(Evas_Object *parent) EAPI Evas_Object * elm_web_webkit_view_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ELM_WIDGET_DATA(sd)->resize_obj; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->ewk_view; #else ERR("Elementary not compiled with EWebKit support."); return NULL; @@ -1348,17 +1137,14 @@ elm_web_webkit_view_get(const Evas_Object *obj) } EAPI void -elm_web_window_create_hook_set(Evas_Object *obj, - Elm_Web_Window_Open func, - void *data) +elm_web_window_create_hook_set(Evas_Object *obj, Elm_Web_Window_Open func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.window_create = func; - sd->hook.window_create_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.window_create = func; + wd->hook.window_create_data = data; #else (void)func; (void)data; @@ -1366,17 +1152,14 @@ elm_web_window_create_hook_set(Evas_Object *obj, } EAPI void -elm_web_dialog_alert_hook_set(Evas_Object *obj, - Elm_Web_Dialog_Alert func, - void *data) +elm_web_dialog_alert_hook_set(Evas_Object *obj, Elm_Web_Dialog_Alert func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.alert = func; - sd->hook.alert_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.alert = func; + wd->hook.alert_data = data; #else (void)func; (void)data; @@ -1384,17 +1167,14 @@ elm_web_dialog_alert_hook_set(Evas_Object *obj, } EAPI void -elm_web_dialog_confirm_hook_set(Evas_Object *obj, - Elm_Web_Dialog_Confirm func, - void *data) +elm_web_dialog_confirm_hook_set(Evas_Object *obj, Elm_Web_Dialog_Confirm func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.confirm = func; - sd->hook.confirm_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.confirm = func; + wd->hook.confirm_data = data; #else (void)func; (void)data; @@ -1402,17 +1182,14 @@ elm_web_dialog_confirm_hook_set(Evas_Object *obj, } EAPI void -elm_web_dialog_prompt_hook_set(Evas_Object *obj, - Elm_Web_Dialog_Prompt func, - void *data) +elm_web_dialog_prompt_hook_set(Evas_Object *obj, Elm_Web_Dialog_Prompt func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.prompt = func; - sd->hook.prompt_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.prompt = func; + wd->hook.prompt_data = data; #else (void)func; (void)data; @@ -1420,17 +1197,14 @@ elm_web_dialog_prompt_hook_set(Evas_Object *obj, } EAPI void -elm_web_dialog_file_selector_hook_set(Evas_Object *obj, - Elm_Web_Dialog_File_Selector func, - void *data) +elm_web_dialog_file_selector_hook_set(Evas_Object *obj, Elm_Web_Dialog_File_Selector func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.file_selector = func; - sd->hook.file_selector_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.file_selector = func; + wd->hook.file_selector_data = data; #else (void)func; (void)data; @@ -1438,17 +1212,14 @@ elm_web_dialog_file_selector_hook_set(Evas_Object *obj, } EAPI void -elm_web_console_message_hook_set(Evas_Object *obj, - Elm_Web_Console_Message func, - void *data) +elm_web_console_message_hook_set(Evas_Object *obj, Elm_Web_Console_Message func, void *data) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->hook.console_message = func; - sd->hook.console_message_data = data; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->hook.console_message = func; + wd->hook.console_message_data = data; #else (void)func; (void)data; @@ -1456,30 +1227,26 @@ elm_web_console_message_hook_set(Evas_Object *obj, } EAPI void -elm_web_useragent_set(Evas_Object *obj, - const char *user_agent) +elm_web_useragent_set(Evas_Object *obj, const char *user_agent) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - ewk_view_setting_user_agent_set - (ELM_WIDGET_DATA(sd)->resize_obj, user_agent); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + ewk_view_setting_user_agent_set(wd->ewk_view, user_agent); #else (void)user_agent; #endif } -EAPI const char * +EAPI const char* elm_web_useragent_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_setting_user_agent_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return ewk_view_setting_user_agent_get(wd->ewk_view); #else return NULL; #endif @@ -1488,42 +1255,37 @@ elm_web_useragent_get(const Evas_Object *obj) EAPI Eina_Bool elm_web_tab_propagate_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return sd->tab_propagate; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->tab_propagate; #else return EINA_FALSE; #endif } EAPI void -elm_web_tab_propagate_set(Evas_Object *obj, - Eina_Bool propagate) +elm_web_tab_propagate_set(Evas_Object *obj, Eina_Bool propagate) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - sd->tab_propagate = propagate; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->tab_propagate = propagate; #else (void)propagate; #endif } EAPI Eina_Bool -elm_web_uri_set(Evas_Object *obj, - const char *uri) +elm_web_uri_set(Evas_Object *obj, const char *uri) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_uri_set(ELM_WIDGET_DATA(sd)->resize_obj, uri); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_uri_set(wd->ewk_view, uri); #else (void)uri; return EINA_FALSE; @@ -1533,12 +1295,11 @@ elm_web_uri_set(Evas_Object *obj, EAPI const char * elm_web_uri_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_uri_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return ewk_view_uri_get(wd->ewk_view); #else return NULL; #endif @@ -1547,30 +1308,24 @@ elm_web_uri_get(const Evas_Object *obj) EAPI const char * elm_web_title_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_title_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return ewk_view_title_get(wd->ewk_view); #else return NULL; #endif } EAPI void -elm_web_bg_color_set(Evas_Object *obj, - int r, - int g, - int b, - int a) +elm_web_bg_color_set(Evas_Object *obj, int r, int g, int b, int a) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - ewk_view_bg_color_set(ELM_WIDGET_DATA(sd)->resize_obj, r, g, b, a); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + ewk_view_bg_color_set(wd->ewk_view, r, g, b, a); #else (void)r; (void)g; @@ -1580,49 +1335,40 @@ elm_web_bg_color_set(Evas_Object *obj, } EAPI void -elm_web_bg_color_get(const Evas_Object *obj, - int *r, - int *g, - int *b, - int *a) +elm_web_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) { if (r) *r = 0; if (g) *g = 0; if (b) *b = 0; if (a) *a = 0; - - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_bg_color_get(ELM_WIDGET_DATA(sd)->resize_obj, r, g, b, a); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + return ewk_view_bg_color_get(wd->ewk_view, r, g, b, a); #endif } EAPI char * elm_web_selection_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) NULL; - + ELM_CHECK_WIDTYPE(obj, widtype) NULL; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_selection_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return ewk_view_selection_get(wd->ewk_view); #else return NULL; #endif } EAPI void -elm_web_popup_selected_set(Evas_Object *obj, - int idx) +elm_web_popup_selected_set(Evas_Object *obj, int idx) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - ewk_view_popup_selected_set(ELM_WIDGET_DATA(sd)->resize_obj, idx); + Widget_Data *wd = elm_widget_data_get(obj); + ewk_view_popup_selected_set(wd->ewk_view, idx); #else (void)idx; #endif @@ -1631,31 +1377,24 @@ elm_web_popup_selected_set(Evas_Object *obj, EAPI Eina_Bool elm_web_popup_destroy(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - return ewk_view_popup_destroy(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + return ewk_view_popup_destroy(wd->ewk_view); #else return EINA_FALSE; #endif } EAPI Eina_Bool -elm_web_text_search(const Evas_Object *obj, - const char *string, - Eina_Bool case_sensitive, - Eina_Bool forward, - Eina_Bool wrap) +elm_web_text_search(const Evas_Object *obj, const char *string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; return ewk_view_text_search - (ELM_WIDGET_DATA(sd)->resize_obj, string, - case_sensitive, forward, wrap); + (wd->ewk_view, string, case_sensitive, forward, wrap); #else (void)string; (void)case_sensitive; @@ -1666,20 +1405,14 @@ elm_web_text_search(const Evas_Object *obj, } EAPI unsigned int -elm_web_text_matches_mark(Evas_Object *obj, - const char *string, - Eina_Bool case_sensitive, - Eina_Bool highlight, - unsigned int limit) +elm_web_text_matches_mark(Evas_Object *obj, const char *string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit) { - ELM_WEB_CHECK(obj) 0; - + ELM_CHECK_WIDTYPE(obj, widtype) 0; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - if (!sd) return 0; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return 0; return ewk_view_text_matches_mark - (ELM_WIDGET_DATA(sd)->resize_obj, string, - case_sensitive, highlight, limit); + (wd->ewk_view, string, case_sensitive, highlight, limit); #else (void)string; (void)case_sensitive; @@ -1692,28 +1425,24 @@ elm_web_text_matches_mark(Evas_Object *obj, EAPI Eina_Bool elm_web_text_matches_unmark_all(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_text_matches_unmark_all(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_text_matches_unmark_all(wd->ewk_view); #else return EINA_FALSE; #endif } EAPI Eina_Bool -elm_web_text_matches_highlight_set(Evas_Object *obj, - Eina_Bool highlight) +elm_web_text_matches_highlight_set(Evas_Object *obj, Eina_Bool highlight) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_text_matches_highlight_set - (ELM_WIDGET_DATA(sd)->resize_obj, highlight); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_text_matches_highlight_set(wd->ewk_view, highlight); #else (void)highlight; return EINA_FALSE; @@ -1723,12 +1452,11 @@ elm_web_text_matches_highlight_set(Evas_Object *obj, EAPI Eina_Bool elm_web_text_matches_highlight_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_text_matches_highlight_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_text_matches_highlight_get(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1737,12 +1465,11 @@ elm_web_text_matches_highlight_get(const Evas_Object *obj) EAPI double elm_web_load_progress_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) - 1.0; - + ELM_CHECK_WIDTYPE(obj, widtype) -1.0; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_load_progress_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return -1.0; + return ewk_view_load_progress_get(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1751,12 +1478,11 @@ elm_web_load_progress_get(const Evas_Object *obj) EAPI Eina_Bool elm_web_stop(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_stop(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_stop(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1765,12 +1491,11 @@ elm_web_stop(Evas_Object *obj) EAPI Eina_Bool elm_web_reload(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_reload(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_reload(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1779,26 +1504,25 @@ elm_web_reload(Evas_Object *obj) EAPI Eina_Bool elm_web_reload_full(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_reload_full(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_reload_full(wd->ewk_view); #else return EINA_FALSE; #endif } + EAPI Eina_Bool elm_web_back(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_back(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_back(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1807,27 +1531,24 @@ elm_web_back(Evas_Object *obj) EAPI Eina_Bool elm_web_forward(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_forward(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_forward(wd->ewk_view); #else return EINA_FALSE; #endif } EAPI Eina_Bool -elm_web_navigate(Evas_Object *obj, - int steps) +elm_web_navigate(Evas_Object *obj, int steps) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_navigate(ELM_WIDGET_DATA(sd)->resize_obj, steps); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_navigate(wd->ewk_view, steps); #else return EINA_FALSE; (void)steps; @@ -1843,12 +1564,11 @@ elm_web_back_possible(Evas_Object *obj) EAPI Eina_Bool elm_web_back_possible_get(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_back_possible(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_back_possible(wd->ewk_view); #else return EINA_FALSE; #endif @@ -1857,27 +1577,24 @@ elm_web_back_possible_get(Evas_Object *obj) EAPI Eina_Bool elm_web_forward_possible_get(Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_forward_possible(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_forward_possible(wd->ewk_view); #else return EINA_FALSE; #endif } EAPI Eina_Bool -elm_web_navigate_possible_get(Evas_Object *obj, - int steps) +elm_web_navigate_possible_get(Evas_Object *obj, int steps) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_navigate_possible(ELM_WIDGET_DATA(sd)->resize_obj, steps); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_navigate_possible(wd->ewk_view, steps); #else return EINA_FALSE; (void)steps; @@ -1887,27 +1604,24 @@ elm_web_navigate_possible_get(Evas_Object *obj, EAPI Eina_Bool elm_web_history_enabled_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return ewk_view_history_enable_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return ewk_view_history_enable_get(wd->ewk_view); #else return EINA_FALSE; #endif } EAPI void -elm_web_history_enabled_set(Evas_Object *obj, - Eina_Bool enable) +elm_web_history_enabled_set(Evas_Object *obj, Eina_Bool enable) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - ewk_view_history_enable_set(ELM_WIDGET_DATA(sd)->resize_obj, enable); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + ewk_view_history_enable_set(wd->ewk_view, enable); #else (void)enable; #endif @@ -1916,35 +1630,30 @@ elm_web_history_enabled_set(Evas_Object *obj, //EAPI Ewk_History *ewk_view_history_get(const Evas_Object *obj); // TODO: EAPI void -elm_web_zoom_set(Evas_Object *obj, - double zoom) +elm_web_zoom_set(Evas_Object *obj, double zoom) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); int vw, vh, cx, cy; float z = 1.0; - - evas_object_geometry_get - (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &vw, &vh); + evas_object_geometry_get(wd->ewk_view, NULL, NULL, &vw, &vh); cx = vw / 2; cy = vh / 2; - if (zoom > sd->zoom.max) zoom = sd->zoom.max; - else if (zoom < sd->zoom.min) - zoom = sd->zoom.min; - if (zoom == sd->zoom.current) return; - - sd->zoom.current = zoom; - if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_MANUAL) z = zoom; - else if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FIT) + if (zoom > wd->zoom.max) + zoom = wd->zoom.max; + else if (zoom < wd->zoom.min) + zoom = wd->zoom.min; + if (zoom == wd->zoom.current) return; + wd->zoom.current = zoom; + if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_MANUAL) + z = zoom; + else if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FIT) { - Evas_Object *frame = - ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj); + Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view); Evas_Coord fw, fh, pw, ph; - - if (!ewk_frame_contents_size_get(frame, &fw, &fh)) return; + if (!ewk_frame_contents_size_get(frame, &fw, &fh)) + return; z = ewk_frame_page_zoom_get(frame); fw /= z; fh /= z; @@ -1964,13 +1673,12 @@ elm_web_zoom_set(Evas_Object *obj, z = (float)ph / fh; } } - else if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FILL) + else if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FILL) { - Evas_Object *frame = - ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj); + Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view); Evas_Coord fw, fh, pw, ph; - - if (!ewk_frame_contents_size_get(frame, &fw, &fh)) return; + if (!ewk_frame_contents_size_get(frame, &fw, &fh)) + return; z = ewk_frame_page_zoom_get(frame); fw /= z; fh /= z; @@ -1990,13 +1698,12 @@ elm_web_zoom_set(Evas_Object *obj, z = (float)ph / fh; } } - if (sd->zoom.no_anim) - ewk_view_zoom_set(ELM_WIDGET_DATA(sd)->resize_obj, z, cx, cy); + if (wd->zoom.no_anim) + ewk_view_zoom_set(wd->ewk_view, z, cx, cy); else - ewk_view_zoom_animated_set - (ELM_WIDGET_DATA(sd)->resize_obj, z, - _elm_config->zoom_friction, cx, cy); - sd->zoom.no_anim = EINA_FALSE; + ewk_view_zoom_animated_set(wd->ewk_view, z, _elm_config->zoom_friction, + cx, cy); + wd->zoom.no_anim = EINA_FALSE; #else (void)zoom; #endif @@ -2005,36 +1712,29 @@ elm_web_zoom_set(Evas_Object *obj, EAPI double elm_web_zoom_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) - 1.0; - + ELM_CHECK_WIDTYPE(obj, widtype) -1.0; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return sd->zoom.current; + Widget_Data *wd = elm_widget_data_get(obj); + return wd->zoom.current; #else return -1.0; #endif } EAPI void -elm_web_zoom_mode_set(Evas_Object *obj, - Elm_Web_Zoom_Mode mode) +elm_web_zoom_mode_set(Evas_Object *obj, Elm_Web_Zoom_Mode mode) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - + Widget_Data *wd = elm_widget_data_get(obj); float tz; - if (mode >= ELM_WEB_ZOOM_MODE_LAST) return; - if (mode == sd->zoom.mode) + if (mode == wd->zoom.mode) return; - - sd->zoom.mode = mode; - tz = sd->zoom.current; - sd->zoom.current = 0.0; + wd->zoom.mode = mode; + tz = wd->zoom.current; + wd->zoom.current = 0.0; elm_web_zoom_set(obj, tz); #else (void)mode; @@ -2044,44 +1744,34 @@ elm_web_zoom_mode_set(Evas_Object *obj, EAPI Elm_Web_Zoom_Mode elm_web_zoom_mode_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) ELM_WEB_ZOOM_MODE_LAST; - + ELM_CHECK_WIDTYPE(obj, widtype) ELM_WEB_ZOOM_MODE_LAST; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - return sd->zoom.mode; + Widget_Data *wd = elm_widget_data_get(obj); + return wd->zoom.mode; #else return ELM_WEB_ZOOM_MODE_LAST; #endif } EAPI void -elm_web_region_show(Evas_Object *obj, - int x, - int y, - int w __UNUSED__, - int h __UNUSED__) +elm_web_region_show(Evas_Object *obj, int x, int y, int w __UNUSED__, int h __UNUSED__) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - Evas_Object *frame = - ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view); int fw, fh, zw, zh, rx, ry; float zoom; - ewk_frame_contents_size_get(frame, &fw, &fh); zoom = ewk_frame_page_zoom_get(frame); zw = fw / zoom; zh = fh / zoom; rx = (x * fw) / zw; ry = (y * fh) / zh; - if (sd->bring_in.animator) + if (wd->bring_in.animator) { - ecore_animator_del(sd->bring_in.animator); - sd->bring_in.animator = NULL; + ecore_animator_del(wd->bring_in.animator); + wd->bring_in.animator = NULL; } ewk_frame_scroll_set(frame, rx, ry); #else @@ -2091,22 +1781,14 @@ elm_web_region_show(Evas_Object *obj, } EAPI void -elm_web_region_bring_in(Evas_Object *obj, - int x, - int y, - int w __UNUSED__, - int h __UNUSED__) +elm_web_region_bring_in(Evas_Object *obj, int x, int y, int w __UNUSED__, int h __UNUSED__) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); - - Evas_Object *frame = - ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj); + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view); int fw, fh, zw, zh, rx, ry, sx, sy; float zoom; - ewk_frame_contents_size_get(frame, &fw, &fh); ewk_frame_scroll_pos_get(frame, &sx, &sy); zoom = ewk_frame_page_zoom_get(frame); @@ -2114,16 +1796,16 @@ elm_web_region_bring_in(Evas_Object *obj, zh = fh / zoom; rx = (x * fw) / zw; ry = (y * fh) / zh; - if ((sd->bring_in.end.x == rx) && (sd->bring_in.end.y == ry)) + if ((wd->bring_in.end.x == rx) && (wd->bring_in.end.y == ry)) return; - sd->bring_in.start.x = sx; - sd->bring_in.start.y = sy; - sd->bring_in.end.x = rx; - sd->bring_in.end.y = ry; - if (sd->bring_in.animator) - ecore_animator_del(sd->bring_in.animator); - sd->bring_in.animator = ecore_animator_timeline_add( - _elm_config->bring_in_scroll_friction, _bring_in_anim_cb, sd); + wd->bring_in.start.x = sx; + wd->bring_in.start.y = sy; + wd->bring_in.end.x = rx; + wd->bring_in.end.y = ry; + if (wd->bring_in.animator) + ecore_animator_del(wd->bring_in.animator); + wd->bring_in.animator = ecore_animator_timeline_add( + _elm_config->bring_in_scroll_friction, _bring_in_anim_cb, wd); #else (void)x; (void)y; @@ -2131,15 +1813,13 @@ elm_web_region_bring_in(Evas_Object *obj, } EAPI void -elm_web_inwin_mode_set(Evas_Object *obj, - Eina_Bool value) +elm_web_inwin_mode_set(Evas_Object *obj, Eina_Bool value) { - ELM_WEB_CHECK(obj); - + ELM_CHECK_WIDTYPE(obj, widtype); #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); - sd->inwin_mode = value; + wd->inwin_mode = value; #else (void)value; #endif @@ -2148,12 +1828,11 @@ elm_web_inwin_mode_set(Evas_Object *obj, EAPI Eina_Bool elm_web_inwin_mode_get(const Evas_Object *obj) { - ELM_WEB_CHECK(obj) EINA_FALSE; - + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; #ifdef HAVE_ELEMENTARY_WEB - ELM_WEB_DATA_GET(obj, sd); + Widget_Data *wd = elm_widget_data_get(obj); - return sd->inwin_mode; + return wd->inwin_mode; #else return EINA_FALSE; #endif @@ -2180,93 +1859,86 @@ elm_web_window_features_unref(Elm_Web_Window_Features *wf) } EAPI Eina_Bool -elm_web_window_features_property_get(const Elm_Web_Window_Features *wf, - Elm_Web_Window_Feature_Flag flag) +elm_web_window_features_property_get(const Elm_Web_Window_Features *wf, Elm_Web_Window_Feature_Flag flag) { #ifdef HAVE_ELEMENTARY_WEB Eina_Bool toolbar_visible, statusbar_visible; Eina_Bool scrollbars_visible, menubar_visible; Eina_Bool locationbar_visible, fullscreen; - ewk_window_features_bool_property_get - ((const Ewk_Window_Features *)wf, &toolbar_visible, &statusbar_visible, - &scrollbars_visible, &menubar_visible, &locationbar_visible, - &fullscreen); + ewk_window_features_bool_property_get((const Ewk_Window_Features *)wf, + &toolbar_visible, &statusbar_visible, + &scrollbars_visible, &menubar_visible, + &locationbar_visible, &fullscreen); //TODO : Improve ewk API usage to get one value. - switch (flag) + // + switch(flag) { - case ELM_WEB_WINDOW_FEATURE_TOOLBAR: - return toolbar_visible; - break; - - case ELM_WEB_WINDOW_FEATURE_STATUSBAR: - return statusbar_visible; - break; - - case ELM_WEB_WINDOW_FEATURE_SCROLLBARS: - return scrollbars_visible; - break; - - case ELM_WEB_WINDOW_FEATURE_MENUBAR: - return menubar_visible; - break; - - case ELM_WEB_WINDOW_FEATURE_LOCATIONBAR: - return locationbar_visible; - break; - - case ELM_WEB_WINDOW_FEATURE_FULLSCREEN: - return fullscreen; - break; + case ELM_WEB_WINDOW_FEATURE_TOOLBAR: + return toolbar_visible; + break; + case ELM_WEB_WINDOW_FEATURE_STATUSBAR: + return statusbar_visible; + break; + case ELM_WEB_WINDOW_FEATURE_SCROLLBARS: + return scrollbars_visible; + break; + case ELM_WEB_WINDOW_FEATURE_MENUBAR: + return menubar_visible; + break; + case ELM_WEB_WINDOW_FEATURE_LOCATIONBAR: + return locationbar_visible; + break; + case ELM_WEB_WINDOW_FEATURE_FULLSCREEN: + return fullscreen; + break; } #else if (!wf) return EINA_FALSE; - if (flag == ELM_WEB_WINDOW_FEATURE_TOOLBAR) + if (flag==ELM_WEB_WINDOW_FEATURE_TOOLBAR) { //TODO Handle unused variable warnings when //ewk is not installed. } /* What to do with these ? - (void)wf; - (void)toolbar_visible; - (void)statusbar_visible; - (void)scrollbars_visible; - (void)menubar_visible; - (void)locationbar_visible; - (void)fullscreen; - */ + + (void)wf; + (void)toolbar_visible; + (void)statusbar_visible; + (void)scrollbars_visible; + (void)menubar_visible; + (void)locationbar_visible; + (void)fullscreen; + + */ #endif return EINA_FALSE; } EAPI void -elm_web_window_features_region_get(const Elm_Web_Window_Features *wf, - Evas_Coord *x, - Evas_Coord *y, - Evas_Coord *w, - Evas_Coord *h) +elm_web_window_features_region_get(const Elm_Web_Window_Features *wf, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) { #ifdef HAVE_ELEMENTARY_WEB - ewk_window_features_int_property_get - ((const Ewk_Window_Features *)wf, x, y, w, h); + ewk_window_features_int_property_get((const Ewk_Window_Features *)wf, + x, y, w, h); #else if (!wf || !x || !y || !w || !h) return; /* What to do with these ? - (void)wf; - (void)x; - (void)y; - (void)w; - (void)h; - */ + + (void)wf; + (void)x; + (void)y; + (void)w; + (void)h; + + */ #endif } -// TODO: use all ewk_view_zoom stuff to implement bring-in and -// animated zoom like elm_photocam. Should be simple to use, must not -// expose every single bit to users! +// TODO: use all ewk_view_zoom stuff to implement bring-in and animated zoom like elm_photocam. Should be simple to use, must not expose every single bit to users! diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index 554d2080d..4b62b63b8 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -1,144 +1,125 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_container.h" static const char SMART_NAME[] = "elm_widget"; -static const char SMART_NAME_COMPAT[] = "elm_widget_compat"; #define API_ENTRY \ - Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(obj); \ + Smart_Data * sd = evas_object_smart_data_get(obj); \ if ((!sd) || (!_elm_widget_is(obj))) #define INTERNAL_ENTRY \ - Elm_Widget_Smart_Data * sd = evas_object_smart_data_get(obj); \ + Smart_Data * sd = evas_object_smart_data_get(obj); \ if (!sd) return -/* this will vanish as soon as we finish the migration of widgets to - * the new hierarchical schema. */ -#define COMPAT_SMART_DATA(_sd) \ - ((Elm_Widget_Compat_Smart_Data *)_sd) - -/* these typedefs are just to save typing on - * _elm_widget_compat_smart_set_user() and will die eventually */ -typedef Eina_Bool (*one_arg_class_func)(Evas_Object *obj); -typedef Eina_Bool (*event_class_func)(Evas_Object *obj, - Evas_Object *source, - Evas_Callback_Type type, - void *event_info); -typedef Eina_Bool (*focus_next_func)(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next); - -/* these will eventually take place of the two on the top */ -#define ELM_WIDGET_DATA_GET(o, wd) \ - Elm_Widget_Smart_Data * wd = evas_object_smart_data_get(o) - -#define ELM_WIDGET_DATA_GET_OR_RETURN(o, ptr) \ - ELM_WIDGET_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("no widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - #undef elm_widget_text_set_hook_set #undef elm_widget_text_get_hook_set #undef elm_widget_content_set_hook_set #undef elm_widget_content_get_hook_set #undef elm_widget_content_unset_hook_set -/** - * @addtogroup Widget - * @{ - */ - -/** - * Base widget smart data extended with instance widget hooks. This - * will be used for compatibility with the old (non-hierarchical) - * widget structure, until all widgets are adapted to the new - * hierarchical schema - */ -typedef struct _Elm_Widget_Compat_Smart_Data -{ - Elm_Widget_Smart_Data base; /**< Base widget smart data as first member obligatory, as we're inheriting from it */ - - const char *type; - void *data; - - void *on_focus_data; - void *on_change_data; - - Eina_List *edje_signals; - - /* (instance) widget hooks */ - void (*del)(Evas_Object *obj); - void (*del_pre)(Evas_Object *obj); - void (*focus)(Evas_Object *obj); - void (*activate)(Evas_Object *obj); - void (*disable)(Evas_Object *obj); - void (*theme)(Evas_Object *obj); - void (*translate)(Evas_Object *obj); - Eina_Bool (*event)(Evas_Object *obj, - Evas_Object *source, - Evas_Callback_Type type, - void *event_info); - void (*signal)(Evas_Object *obj, - const char *emission, - const char *source); - void (*callback_add)(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func, - void *data); - void (*callback_del)(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func, - void *data); - void (*changed)(Evas_Object *obj); - Eina_Bool (*focus_next)(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next); - void (*on_focus)(void *data, - Evas_Object *obj); - void (*on_change)(void *data, - Evas_Object *obj); - void (*focus_region)(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y, - Evas_Coord w, - Evas_Coord h); - void (*on_focus_region)(const Evas_Object *obj, - Evas_Coord *x, - Evas_Coord *y, - Evas_Coord *w, - Evas_Coord *h); - Elm_Widget_Text_Set_Cb text_set; - Elm_Widget_Text_Get_Cb text_get; - Elm_Widget_Content_Set_Cb content_set; - Elm_Widget_Content_Get_Cb content_get; - Elm_Widget_Content_Unset_Cb content_unset; -} Elm_Widget_Compat_Smart_Data; - -/** - * Inheriting from base widget smart class, so that we flag widgets - * not migrated to new hierarchical schema as "compat" (or legacy), - * until we get all of them migrated. Then, this class will be - * dropped. - */ -typedef struct _Elm_Widget_Compat_Smart_Class -{ - Elm_Widget_Smart_Class base; /**< Base widget smart class wrapped here */ -} Elm_Widget_Compat_Smart_Class; - -/** - * @} - */ - +typedef struct _Smart_Data Smart_Data; typedef struct _Edje_Signal_Data Edje_Signal_Data; typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data; typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data; +struct _Smart_Data +{ + Evas_Object *obj; + const char *type; + Evas_Object *parent_obj; + Evas_Object *parent2; + Evas_Coord x, y, w, h; + Eina_List *subobjs; + Evas_Object *resize_obj; + Evas_Object *hover_obj; + Eina_List *tooltips, *cursors; + void (*del_func)(Evas_Object *obj); + void (*del_pre_func)(Evas_Object *obj); + void (*focus_func)(Evas_Object *obj); + void (*activate_func)(Evas_Object *obj); + void (*disable_func)(Evas_Object *obj); + void (*theme_func)(Evas_Object *obj); + void (*translate_func)(Evas_Object *obj); + Eina_Bool (*event_func)(Evas_Object *obj, + Evas_Object *source, + Evas_Callback_Type type, + void *event_info); + void (*signal_func)(Evas_Object *obj, + const char *emission, + const char *source); + void (*callback_add_func)(Evas_Object *obj, + const char *emission, + const char *source, + Edje_Signal_Cb func, + void *data); + void (*callback_del_func)(Evas_Object *obj, + const char *emission, + const char *source, + Edje_Signal_Cb func, + void *data); + void (*changed_func)(Evas_Object *obj); + Eina_Bool (*focus_next_func)(const Evas_Object *obj, + Elm_Focus_Direction dir, + Evas_Object **next); + void (*on_focus_func)(void *data, + Evas_Object *obj); + void *on_focus_data; + void (*on_change_func)(void *data, + Evas_Object *obj); + void *on_change_data; + void (*on_show_region_func)(void *data, + Evas_Object *obj); + void *on_show_region_data; + void (*focus_region_func)(Evas_Object *obj, + Evas_Coord x, + Evas_Coord y, + Evas_Coord w, + Evas_Coord h); + void (*on_focus_region_func)(const Evas_Object *obj, + Evas_Coord *x, + Evas_Coord *y, + Evas_Coord *w, + Evas_Coord *h); + Elm_Widget_Text_Set_Cb text_set_func; + Elm_Widget_Text_Get_Cb text_get_func; + Elm_Widget_Content_Set_Cb content_set_func; + Elm_Widget_Content_Get_Cb content_get_func; + Elm_Widget_Content_Unset_Cb content_unset_func; + void *data; + Evas_Coord rx, ry, rw, rh; + int scroll_hold; + int scroll_freeze; + double scale; + Elm_Theme *theme; + const char *style; + const char *access_info; + unsigned int focus_order; + Eina_Bool focus_order_on_calc; + + int child_drag_x_locked; + int child_drag_y_locked; + + Eina_List *edje_signals; + Eina_List *translate_strings; + + Eina_Bool drag_x_locked : 1; + Eina_Bool drag_y_locked : 1; + + Eina_Bool can_focus : 1; + Eina_Bool child_can_focus : 1; + Eina_Bool focused : 1; + Eina_Bool top_win_focused : 1; + Eina_Bool tree_unfocusable : 1; + Eina_Bool highlight_ignore : 1; + Eina_Bool highlight_in_theme : 1; + Eina_Bool disabled : 1; + Eina_Bool is_mirrored : 1; + Eina_Bool mirrored_auto_mode : 1; /* This is TRUE by default */ + Eina_Bool still_in : 1; + + Eina_List *focus_chain; + Eina_List *event_cb; +}; + struct _Edje_Signal_Data { Evas_Object *obj; @@ -162,7 +143,7 @@ struct _Elm_Translate_String_Data }; /* local subsystem functions */ -static void _smart_reconfigure(Elm_Widget_Smart_Data *sd); +static void _smart_reconfigure(Smart_Data *sd); static void _smart_add(Evas_Object *obj); static void _smart_del(Evas_Object *obj); static void _smart_move(Evas_Object *obj, @@ -184,30 +165,26 @@ static void _smart_clip_unset(Evas_Object *obj); static void _smart_calculate(Evas_Object *obj); static void _smart_member_add(Evas_Object *obj, Evas_Object *child); static void _smart_member_del(Evas_Object *obj, Evas_Object *child); +static void _smart_init(void); + static void _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only); static Evas_Object *_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only); -static void _sub_obj_del(void *data, - Evas *e, - Evas_Object *obj, - void *event_info); -static void _focus_parents(Evas_Object *obj); -static void _sub_obj_hide(void *data, - Evas *e, - Evas_Object *obj, - void *event_info); /* local subsystem globals */ +static Evas_Smart *_e_smart = NULL; static Eina_List *widtypes = NULL; static unsigned int focus_order = 0; +// internal funcs static inline Eina_Bool _elm_widget_is(const Evas_Object *obj) { - return evas_object_smart_type_check_ptr(obj, SMART_NAME); + const char *type = evas_object_type_get(obj); + return type == SMART_NAME; } static inline Eina_Bool @@ -217,346 +194,6 @@ _is_focusable(Evas_Object *obj) return sd->can_focus || (sd->child_can_focus); } -static inline Eina_Bool -_elm_legacy_is(const Evas_Object *obj) -{ - return evas_object_smart_type_check_ptr(obj, SMART_NAME_COMPAT); -} - -/* what follows are both basic (unimplemented) smart class functions - * and proxies from those to smart data (instance) widget - * functions. one by one we'll be surpassing the proxies on the - * widgets, as long as we make them extensions of the basic elm widget - * the right way */ -#define PROXY_MAKE(_prefix) \ - static Eina_Bool \ - _elm_widget_##_prefix##_func_compat(Evas_Object * obj) \ - { \ - ELM_WIDGET_DATA_GET(obj, sd); \ - if (COMPAT_SMART_DATA(sd)->_prefix) \ - { \ - COMPAT_SMART_DATA(sd)->_prefix(obj); \ - return EINA_TRUE; \ - } \ - return EINA_FALSE; \ - } - -#define UNIMPLEMENTED_MAKE(_prefix) \ - static Eina_Bool \ - _elm_widget_##_prefix##_func_unimplemented(Evas_Object * obj) \ - { \ - WRN("The %s widget does not implement the \"" #_prefix "\" function.", \ - elm_widget_type_get(obj)); \ - return EINA_FALSE; \ - } - -PROXY_MAKE(disable); -PROXY_MAKE(theme); -PROXY_MAKE(translate); -UNIMPLEMENTED_MAKE(disable); -UNIMPLEMENTED_MAKE(translate); - -#undef PROXY_MAKE -#undef UNIMPLEMENTED_MAKE - -static Eina_Bool -_elm_widget_theme_func(Evas_Object *obj) -{ - _elm_widget_mirrored_reload(obj); - - elm_widget_disabled_set(obj, elm_widget_disabled_get(obj)); - - return EINA_TRUE; -} - -static Eina_Bool -_elm_widget_on_focus_func_compat(Evas_Object *obj) -{ - ELM_WIDGET_DATA_GET(obj, sd); - - if (COMPAT_SMART_DATA(sd)->on_focus) - { - COMPAT_SMART_DATA(sd)->on_focus - (COMPAT_SMART_DATA(sd)->on_focus_data, obj); - return EINA_TRUE; - } - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_on_focus_func_unimplemented(Evas_Object *obj) -{ - WRN("The %s widget does not implement the \"on_focus\" function.", - elm_widget_type_get(obj)); - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_event_func_compat(Evas_Object *obj, - Evas_Object *source, - Evas_Callback_Type type, - void *event_info) -{ - ELM_WIDGET_DATA_GET(obj, sd); - - if (COMPAT_SMART_DATA(sd)->event) - return COMPAT_SMART_DATA(sd)->event(obj, source, type, event_info); - - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_event_func_unimplemented(Evas_Object *obj, - Evas_Object *source __UNUSED__, - Evas_Callback_Type type __UNUSED__, - void *event_info __UNUSED__) -{ - WRN("The %s widget does not implement the \"event\" function.", - elm_widget_type_get(obj)); - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_focus_next_func_compat(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) -{ - ELM_WIDGET_DATA_GET(obj, sd); - - if (COMPAT_SMART_DATA(sd)->focus_next) - return COMPAT_SMART_DATA(sd)->focus_next(obj, dir, next); - - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_focus_next_func_unimplemented(const Evas_Object *obj __UNUSED__, - Elm_Focus_Direction dir __UNUSED__, - Evas_Object **next __UNUSED__) -{ - WRN("The %s widget does not implement the \"focus_next\" function.", - elm_widget_type_get(obj)); - return EINA_FALSE; -} - -static Eina_Bool -_elm_widget_sub_object_add_func(Evas_Object *obj, - Evas_Object *sobj) -{ - double scale, pscale = elm_widget_scale_get(sobj); - Elm_Theme *th, *pth = elm_widget_theme_get(sobj); - Eina_Bool mirrored, pmirrored = elm_widget_mirrored_get(obj); - - ELM_WIDGET_DATA_GET(obj, sd); - EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE); - - if (sobj == sd->parent_obj) - { - /* in this case, sobj must be an elm widget, or something - * very wrong is happening */ - if (!_elm_widget_is(sobj)) return EINA_FALSE; - - if (!elm_widget_sub_object_del(sobj, obj)) return EINA_FALSE; - WRN("You passed a parent object of obj = %p as the sub object = %p!", - obj, sobj); - } - - if (_elm_widget_is(sobj)) - { - ELM_WIDGET_DATA_GET(sobj, sdc); - - if (sdc) - { - if (sdc->parent_obj == obj) return EINA_TRUE; - if (sdc->parent_obj) - { - if (!elm_widget_sub_object_del(sdc->parent_obj, sobj)) - return EINA_FALSE; - } - sdc->parent_obj = obj; - _elm_widget_top_win_focused_set(sobj, sd->top_win_focused); - if (!sd->child_can_focus && (_is_focusable(sobj))) - sd->child_can_focus = EINA_TRUE; - } - } - else - { - void *data = evas_object_data_get(sobj, "elm-parent"); - - if (data) - { - if (data == obj) return EINA_TRUE; - if (!elm_widget_sub_object_del(data, sobj)) return EINA_FALSE; - } - } - - sd->subobjs = eina_list_append(sd->subobjs, sobj); - evas_object_data_set(sobj, "elm-parent", obj); - evas_object_event_callback_add - (sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); - if (_elm_widget_is(sobj)) - { - evas_object_event_callback_add - (sobj, EVAS_CALLBACK_HIDE, _sub_obj_hide, sd); - - scale = elm_widget_scale_get(sobj); - th = elm_widget_theme_get(sobj); - mirrored = elm_widget_mirrored_get(sobj); - - if ((scale != pscale) || (th != pth) || (pmirrored != mirrored)) - elm_widget_theme(sobj); - - if (elm_widget_focus_get(sobj)) _focus_parents(obj); - } - - return EINA_TRUE; -} - - -static Eina_Bool -_elm_widget_sub_object_del_func(Evas_Object *obj, - Evas_Object *sobj) -{ - Evas_Object *sobj_parent; - - if (!sobj) return EINA_FALSE; - - ELM_WIDGET_DATA_GET(obj, sd); - EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE); - - sobj_parent = evas_object_data_del(sobj, "elm-parent"); - if (sobj_parent != obj) - { - static int abort_on_warn = -1; - - ERR("removing sub object %p (%s) from parent %p (%s), " - "but elm-parent is different %p (%s)!", - sobj, elm_widget_type_get(sobj), obj, elm_widget_type_get(obj), - sobj_parent, elm_widget_type_get(sobj_parent)); - - if (EINA_UNLIKELY(abort_on_warn == -1)) - { - if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1; - else abort_on_warn = 0; - } - if (abort_on_warn == 1) abort(); - - return EINA_FALSE; - } - - if (_elm_widget_is(sobj)) - { - if (elm_widget_focus_get(sobj)) - { - elm_widget_tree_unfocusable_set(sobj, EINA_TRUE); - elm_widget_tree_unfocusable_set(sobj, EINA_FALSE); - } - if ((sd->child_can_focus) && (_is_focusable(sobj))) - { - Evas_Object *subobj; - const Eina_List *l; - - sd->child_can_focus = EINA_FALSE; - - EINA_LIST_FOREACH (sd->subobjs, l, subobj) - { - if (_is_focusable(subobj)) - { - sd->child_can_focus = EINA_TRUE; - break; - } - } - } - - ELM_WIDGET_DATA_GET(sobj, sdc); - sdc->parent_obj = NULL; - } - - if (sd->resize_obj == sobj) sd->resize_obj = NULL; - - sd->subobjs = eina_list_remove(sd->subobjs, sobj); - - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); - if (_elm_widget_is(sobj)) - evas_object_event_callback_del_full - (sobj, EVAS_CALLBACK_HIDE, _sub_obj_hide, sd); - - return EINA_TRUE; -} - -static const Evas_Smart_Cb_Description _smart_callbacks[] = -{ - /* FIXME: complete later */ - {NULL, NULL} -}; - -static void -_elm_widget_smart_set(Elm_Widget_Smart_Class *api) -{ - Evas_Smart_Class *sc; - - if (!(sc = (Evas_Smart_Class *)api)) - return; - - sc->add = _smart_add; - sc->del = _smart_del; - sc->move = _smart_move; - sc->resize = _smart_resize; - sc->show = _smart_show; - sc->hide = _smart_hide; - sc->color_set = _smart_color_set; - sc->clip_set = _smart_clip_set; - sc->clip_unset = _smart_clip_unset; - sc->calculate = _smart_calculate; - sc->member_add = _smart_member_add; - sc->member_del = _smart_member_del; - -#define API_DEFAULT_SET_UNIMPLEMENTED(_prefix) \ - api->_prefix = _elm_widget_##_prefix##_func_unimplemented; - - /* NB: always remember to call these parent versions on children, - * except for the unimplemented ones and calculate, which is moot */ - -#define API_DEFAULT_SET(_prefix) \ - api->_prefix = _elm_widget_##_prefix##_func; - - /* base api */ - API_DEFAULT_SET_UNIMPLEMENTED(on_focus); - API_DEFAULT_SET_UNIMPLEMENTED(disable); - - api->theme = _elm_widget_theme_func; - - API_DEFAULT_SET_UNIMPLEMENTED(translate); - API_DEFAULT_SET_UNIMPLEMENTED(event); - API_DEFAULT_SET_UNIMPLEMENTED(focus_next); - - /* NB: because those two weren't hooks before, translate the - * individual calls to them on the widgets as we bring them to the - * new class hierarchy. also, sub_object_{add,del} must be - * different than member_{add,del} here, because widget parenting - * on elm does not always imply parent and child will live on the - * same Evas layer */ - API_DEFAULT_SET(sub_object_add); - API_DEFAULT_SET(sub_object_del); - -#undef API_DEFAULT_SET -#undef API_DEFAULT_SET_UNIMPLEMENTED - - sc->callbacks = _smart_callbacks; -} - -// internal funcs -static inline Eina_Bool -_elm_widget_focus_chain_manager_is(const Evas_Object *obj) -{ - API_ENTRY return EINA_FALSE; - - if (_elm_legacy_is(obj)) return !!COMPAT_SMART_DATA(sd)->focus_next; - return sd->api->focus_next && - (sd->api->focus_next != _elm_widget_focus_next_func_unimplemented); -} - static void _unfocus_parents(Evas_Object *obj) { @@ -585,33 +222,19 @@ _sub_obj_del(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Elm_Widget_Smart_Data *sd = data; + Smart_Data *sd = data; if (_elm_widget_is(obj)) { if (elm_widget_focus_get(obj)) _unfocus_parents(sd->obj); } if (obj == sd->resize_obj) - { - /* already dels sub object */ - elm_widget_resize_object_set(sd->obj, NULL); - return; - } + sd->resize_obj = NULL; else if (obj == sd->hover_obj) - { - sd->hover_obj = NULL; - return; - } - else if (_elm_legacy_is(sd->obj)) - { - evas_object_smart_callback_call(sd->obj, "sub-object-del", obj); - sd->subobjs = eina_list_remove(sd->subobjs, obj); - } + sd->hover_obj = NULL; else - { - if (!elm_widget_sub_object_del(sd->obj, obj)) - ERR("failed to remove sub object %p from %p\n", obj, sd->obj); - } + sd->subobjs = eina_list_remove(sd->subobjs, obj); + evas_object_smart_callback_call(sd->obj, "sub-object-del", obj); } static void @@ -629,7 +252,7 @@ _sub_obj_mouse_down(void *data, Evas_Object *obj __UNUSED__, void *event_info) { - Elm_Widget_Smart_Data *sd = data; + Smart_Data *sd = data; Evas_Event_Mouse_Down *ev = event_info; if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)) sd->still_in = EINA_TRUE; @@ -641,7 +264,7 @@ _sub_obj_mouse_move(void *data, Evas_Object *obj, void *event_info) { - Elm_Widget_Smart_Data *sd = data; + Smart_Data *sd = data; Evas_Event_Mouse_Move *ev = event_info; if (sd->still_in) { @@ -664,7 +287,7 @@ _sub_obj_mouse_up(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Elm_Widget_Smart_Data *sd = data; + Smart_Data *sd = data; if (sd->still_in) elm_widget_focus_mouse_up_handle(obj); sd->still_in = EINA_FALSE; @@ -677,7 +300,7 @@ _propagate_x_drag_lock(Evas_Object *obj, INTERNAL_ENTRY; if (sd->parent_obj) { - Elm_Widget_Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj); + Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj); if (sd2) { sd2->child_drag_x_locked += dir; @@ -693,7 +316,7 @@ _propagate_y_drag_lock(Evas_Object *obj, INTERNAL_ENTRY; if (sd->parent_obj) { - Elm_Widget_Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj); + Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj); if (sd2) { sd2->child_drag_y_locked += dir; @@ -746,7 +369,6 @@ static void _parent_focus(Evas_Object *obj) { API_ENTRY return; - if (sd->focused) return; Evas_Object *o = elm_widget_parent_get(obj); @@ -764,9 +386,8 @@ _parent_focus(Evas_Object *obj) if (sd->top_win_focused) { sd->focused = EINA_TRUE; - sd->api->on_focus(obj); - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->focus) - COMPAT_SMART_DATA(sd)->focus(obj); + if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj); + if (sd->focus_func) sd->focus_func(obj); _elm_widget_focus_region_show(obj); } sd->focus_order_on_calc = EINA_FALSE; @@ -778,7 +399,7 @@ _elm_object_focus_chain_del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Elm_Widget_Smart_Data *sd = data; + Smart_Data *sd = data; sd->focus_chain = eina_list_remove(sd->focus_chain, obj); } @@ -800,7 +421,7 @@ void _elm_widget_focus_region_show(const Evas_Object *obj) { Evas_Coord x, y, w, h, ox, oy; - Elm_Widget_Smart_Data *sd2; + Smart_Data *sd2; Evas_Object *o; API_ENTRY return; @@ -814,9 +435,9 @@ _elm_widget_focus_region_show(const Evas_Object *obj) { Evas_Coord px, py; sd2 = evas_object_smart_data_get(o); - if (_elm_legacy_is(o) && COMPAT_SMART_DATA(sd2)->focus_region) + if (sd2->focus_region_func) { - COMPAT_SMART_DATA(sd2)->focus_region(o, x, y, w, h); + sd2->focus_region_func(o, x, y, w, h); elm_widget_focus_region_get(o, &x, &y, &w, &h); } else @@ -831,28 +452,24 @@ _elm_widget_focus_region_show(const Evas_Object *obj) } } -EAPI const Elm_Widget_Smart_Class * -elm_widget_smart_class_get(void) -{ - static Elm_Widget_Smart_Class _sc = - ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(SMART_NAME); - static const Elm_Widget_Smart_Class *class = NULL; - - if (class) - return class; - - _elm_widget_smart_set(&_sc); - class = &_sc; - - return class; -} - +/** + * @defgroup Widget Widget + * + * @internal + * Exposed api for making widgets + */ EAPI void elm_widget_type_register(const char **ptr) { widtypes = eina_list_append(widtypes, (void *)ptr); } +/** + * @defgroup Widget Widget + * + * @internal + * Disposed api for making widgets + */ EAPI void elm_widget_type_unregister(const char **ptr) { @@ -870,81 +487,14 @@ elm_widget_api_check(int ver) return EINA_TRUE; } -/* creating compat smart class */ -EVAS_SMART_SUBCLASS_NEW - (SMART_NAME_COMPAT, _elm_widget_compat, Elm_Widget_Compat_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL); - -static void -_compat_smart_add(Evas_Object *obj) -{ - EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Compat_Smart_Data); - - _elm_widget_compat_parent_sc->base.add(obj); -} - -static void -_compat_smart_del(Evas_Object *obj) -{ - Edje_Signal_Data *esd; - - ELM_WIDGET_DATA_GET(obj, sd); - - if (COMPAT_SMART_DATA(sd)->del_pre) - COMPAT_SMART_DATA(sd)->del_pre(obj); - if (COMPAT_SMART_DATA(sd)->del) - COMPAT_SMART_DATA(sd)->del(obj); - - if (COMPAT_SMART_DATA(sd)->type) - eina_stringshare_del(COMPAT_SMART_DATA(sd)->type); - - EINA_LIST_FREE(COMPAT_SMART_DATA(sd)->edje_signals, esd) - { - eina_stringshare_del(esd->emission); - eina_stringshare_del(esd->source); - free(esd); - } - - COMPAT_SMART_DATA(sd)->data = NULL; - - _elm_widget_compat_parent_sc->base.del(obj); -} - -static void -_compat_smart_calculate(Evas_Object *obj) -{ - ELM_WIDGET_DATA_GET(obj, sd); - - if (COMPAT_SMART_DATA(sd)->changed) COMPAT_SMART_DATA(sd)->changed(obj); -} - -static void -_elm_widget_compat_smart_set_user(Elm_Widget_Compat_Smart_Class *sc) -{ - ELM_WIDGET_CLASS(sc)->base.add = _compat_smart_add; - ELM_WIDGET_CLASS(sc)->base.del = _compat_smart_del; - ELM_WIDGET_CLASS(sc)->base.calculate = _compat_smart_calculate; - -/* proxying base class functions to instance ones on compat widgets - * (and overriding defaults -- unimplemented) */ -#define API_BASE_COMPAT_SET(_cast, _prefix) \ - ELM_WIDGET_CLASS(sc)->_prefix = (_cast)_elm_widget_##_prefix##_func_compat - - /* base api */ - API_BASE_COMPAT_SET(one_arg_class_func, on_focus); - API_BASE_COMPAT_SET(one_arg_class_func, disable); - API_BASE_COMPAT_SET(one_arg_class_func, theme); - API_BASE_COMPAT_SET(one_arg_class_func, translate); - API_BASE_COMPAT_SET(event_class_func, event); - API_BASE_COMPAT_SET(focus_next_func, focus_next); - -#undef API_BASE_COMPAT_SET -} - EAPI Evas_Object * elm_widget_add(Evas *evas) { - return evas_object_smart_add(evas, _elm_widget_compat_smart_class_new()); + Evas_Object *obj; + _smart_init(); + obj = evas_object_smart_add(evas, _e_smart); + elm_widget_mirrored_set(obj, elm_config_mirrored_get()); + return obj; } EAPI void @@ -952,8 +502,7 @@ elm_widget_del_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->del = func; + sd->del_func = func; } EAPI void @@ -961,8 +510,7 @@ elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->del_pre = func; + sd->del_pre_func = func; } EAPI void @@ -970,8 +518,7 @@ elm_widget_focus_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->focus = func; + sd->focus_func = func; } EAPI void @@ -979,8 +526,7 @@ elm_widget_activate_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->activate = func; + sd->activate_func = func; } EAPI void @@ -988,8 +534,7 @@ elm_widget_disable_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->disable = func; + sd->disable_func = func; } EAPI void @@ -997,8 +542,7 @@ elm_widget_theme_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->theme = func; + sd->theme_func = func; } EAPI void @@ -1006,8 +550,7 @@ elm_widget_translate_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->translate = func; + sd->translate_func = func; } EAPI void @@ -1018,8 +561,7 @@ elm_widget_event_hook_set(Evas_Object *obj, void *event_info)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->event = func; + sd->event_func = func; } EAPI void @@ -1027,8 +569,7 @@ elm_widget_text_set_hook_set(Evas_Object *obj, Elm_Widget_Text_Set_Cb func) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->text_set = func; + sd->text_set_func = func; } EAPI void @@ -1036,8 +577,7 @@ elm_widget_text_get_hook_set(Evas_Object *obj, Elm_Widget_Text_Get_Cb func) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->text_get = func; + sd->text_get_func = func; } EAPI void @@ -1045,8 +585,7 @@ elm_widget_content_set_hook_set(Evas_Object *obj, Elm_Widget_Content_Set_Cb func) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->content_set = func; + sd->content_set_func = func; } EAPI void @@ -1054,8 +593,7 @@ elm_widget_content_get_hook_set(Evas_Object *obj, Elm_Widget_Content_Get_Cb func) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->content_get = func; + sd->content_get_func = func; } EAPI void @@ -1063,8 +601,7 @@ elm_widget_content_unset_hook_set(Evas_Object *obj, Elm_Widget_Content_Unset_Cb func) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->content_unset = func; + sd->content_unset_func = func; } EAPI void @@ -1072,8 +609,7 @@ elm_widget_changed_hook_set(Evas_Object *obj, void (*func)(Evas_Object *obj)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->changed = func; + sd->changed_func = func; } EAPI void @@ -1083,8 +619,7 @@ elm_widget_signal_emit_hook_set(Evas_Object *obj, const char *source)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->signal = func; + sd->signal_func = func; } EAPI void @@ -1096,8 +631,7 @@ elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void *data)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->callback_add = func; + sd->callback_add_func = func; } EAPI void @@ -1109,8 +643,7 @@ elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *data)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->callback_del = func; + sd->callback_del_func = func; } EAPI Eina_Bool @@ -1129,8 +662,7 @@ elm_widget_theme(Evas_Object *obj) if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj); EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt); EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur); - - ret &= sd->api->theme(obj); + if (sd->theme_func) sd->theme_func(obj); return ret; } @@ -1147,7 +679,6 @@ elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th2, *thdef; API_ENTRY return; - thdef = elm_theme_default_get(); if (!th) th = thdef; if (!force) @@ -1173,7 +704,7 @@ elm_widget_theme_specific(Evas_Object *obj, if (sd->hover_obj) elm_widget_theme(sd->hover_obj); EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt); EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur); - sd->api->theme(obj); + if (sd->theme_func) sd->theme_func(obj); } /** @@ -1193,8 +724,7 @@ elm_widget_focus_next_hook_set(Evas_Object *obj, Evas_Object **next)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->focus_next = func; + sd->focus_next_func = func; } /** @@ -1292,9 +822,8 @@ elm_widget_on_focus_hook_set(Evas_Object *obj, void *data) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->on_focus = func; - COMPAT_SMART_DATA(sd)->on_focus_data = data; + sd->on_focus_func = func; + sd->on_focus_data = data; } EAPI void @@ -1304,9 +833,8 @@ elm_widget_on_change_hook_set(Evas_Object *obj, void *data) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->on_change = func; - COMPAT_SMART_DATA(sd)->on_change_data = data; + sd->on_change_func = func; + sd->on_change_data = data; } EAPI void @@ -1316,8 +844,7 @@ elm_widget_on_show_region_hook_set(Evas_Object *obj, void *data) { API_ENTRY return; - - sd->on_show_region = func; + sd->on_show_region_func = func; sd->on_show_region_data = data; } @@ -1345,8 +872,7 @@ elm_widget_focus_region_hook_set(Evas_Object *obj, Evas_Coord h)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->focus_region = func; + sd->focus_region_func = func; } /** @@ -1373,8 +899,7 @@ elm_widget_on_focus_region_hook_set(Evas_Object *obj, Evas_Coord *h)) { API_ENTRY return; - - COMPAT_SMART_DATA(sd)->on_focus_region = func; + sd->on_focus_region_func = func; } EAPI void @@ -1382,49 +907,39 @@ elm_widget_data_set(Evas_Object *obj, void *data) { API_ENTRY return; - - if (!_elm_widget_is(obj)) return; - - COMPAT_SMART_DATA(sd)->data = data; + sd->data = data; } EAPI void * elm_widget_data_get(const Evas_Object *obj) { API_ENTRY return NULL; - - if (!_elm_legacy_is(obj)) return NULL; - - return COMPAT_SMART_DATA(sd)->data; + return sd->data; } -EAPI Eina_Bool +EAPI void elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj) { - API_ENTRY return EINA_FALSE; - EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE); - - if (!_elm_legacy_is(obj)) return sd->api->sub_object_add(obj, sobj); - - /* this part will go away once all widgets are migrated to the new schema */ + API_ENTRY return; + EINA_SAFETY_ON_TRUE_RETURN(obj == sobj); double scale, pscale = elm_widget_scale_get(sobj); Elm_Theme *th, *pth = elm_widget_theme_get(sobj); Eina_Bool mirrored, pmirrored = elm_widget_mirrored_get(obj); if (sobj == sd->parent_obj) { - if (!elm_widget_sub_object_del(sobj, obj)) return EINA_FALSE; + elm_widget_sub_object_del(sobj, obj); WRN("You passed a parent object of obj = %p as the sub object = %p!", obj, sobj); } if (_elm_widget_is(sobj)) { - Elm_Widget_Smart_Data *sd2 = evas_object_smart_data_get(sobj); + Smart_Data *sd2 = evas_object_smart_data_get(sobj); if (sd2) { if (sd2->parent_obj == obj) - return EINA_TRUE; + return; if (sd2->parent_obj) elm_widget_sub_object_del(sd2->parent_obj, sobj); sd2->parent_obj = obj; @@ -1438,8 +953,9 @@ elm_widget_sub_object_add(Evas_Object *obj, void *data = evas_object_data_get(sobj, "elm-parent"); if (data) { - if (data == obj) return EINA_TRUE; - elm_widget_sub_object_del(data, sobj); + if (data == obj) return; + evas_object_event_callback_del(sobj, EVAS_CALLBACK_DEL, + _sub_obj_del); } } sd->subobjs = eina_list_append(sd->subobjs, sobj); @@ -1453,24 +969,16 @@ elm_widget_sub_object_add(Evas_Object *obj, mirrored = elm_widget_mirrored_get(sobj); if ((scale != pscale) || (th != pth) || (pmirrored != mirrored)) elm_widget_theme(sobj); if (elm_widget_focus_get(sobj)) _focus_parents(obj); - - return EINA_TRUE; } -EAPI Eina_Bool +EAPI void elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj) { Evas_Object *sobj_parent; + API_ENTRY return; + if (!sobj) return; - API_ENTRY return EINA_FALSE; - EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE); - - if (!sobj) return EINA_FALSE; - - if (!_elm_legacy_is(obj)) return sd->api->sub_object_del(obj, sobj); - - /* this part will go away once all widgets are migrated to the new schema */ sobj_parent = evas_object_data_del(sobj, "elm-parent"); if (sobj_parent != obj) { @@ -1485,8 +993,6 @@ elm_widget_sub_object_del(Evas_Object *obj, else abort_on_warn = 0; } if (abort_on_warn == 1) abort(); - - return EINA_FALSE; } if (_elm_widget_is(sobj)) { @@ -1509,13 +1015,14 @@ elm_widget_sub_object_del(Evas_Object *obj, } } } - Elm_Widget_Smart_Data *sd2 = evas_object_smart_data_get(sobj); + Smart_Data *sd2 = evas_object_smart_data_get(sobj); if (sd2) { sd2->parent_obj = NULL; - if (sd2->resize_obj == sobj) sd2->resize_obj = NULL; - - sd->subobjs = eina_list_remove(sd->subobjs, sobj); + if (sd2->resize_obj == sobj) + sd2->resize_obj = NULL; + else + sd->subobjs = eina_list_remove(sd->subobjs, sobj); } else sd->subobjs = eina_list_remove(sd->subobjs, sobj); @@ -1528,28 +1035,35 @@ elm_widget_sub_object_del(Evas_Object *obj, evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE, _sub_obj_hide, sd); evas_object_smart_callback_call(obj, "sub-object-del", sobj); +} - return EINA_TRUE; +EAPI const Eina_List * +elm_widget_sub_object_list_get(const Evas_Object *obj) +{ + API_ENTRY return NULL; + return (const Eina_List *)sd->subobjs; } -/* a resize object is a sub object with some more callbacks on it and - * a smart member of the parent - */ EAPI void elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj) { - Evas_Object *parent; - API_ENTRY return; - - if (sd->resize_obj == sobj) return; - // orphan previous resize obj if (sd->resize_obj) { evas_object_clip_unset(sd->resize_obj); - + evas_object_data_del(sd->resize_obj, "elm-parent"); + if (_elm_widget_is(sd->resize_obj)) + { + Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj); + if (sd2) sd2->parent_obj = NULL; + evas_object_event_callback_del_full(sd->resize_obj, + EVAS_CALLBACK_HIDE, + _sub_obj_hide, sd); + } + evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL, + _sub_obj_del, sd); evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN, _sub_obj_mouse_down, sd); @@ -1565,33 +1079,49 @@ elm_widget_resize_object_set(Evas_Object *obj, { if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj); } - - elm_widget_sub_object_del(obj, sd->resize_obj); } sd->resize_obj = sobj; if (!sobj) return; // orphan new resize obj - parent = evas_object_data_get(sobj, "elm-parent"); - if (parent && parent != obj) + evas_object_data_del(sobj, "elm-parent"); + if (_elm_widget_is(sobj)) + { + Smart_Data *sd2 = evas_object_smart_data_get(sobj); + if (sd2) sd2->parent_obj = NULL; + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE, + _sub_obj_hide, sd); + } + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, + _sub_obj_del, sd); + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN, + _sub_obj_mouse_down, sd); + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_MOVE, + _sub_obj_mouse_move, sd); + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_UP, + _sub_obj_mouse_up, sd); + evas_object_smart_member_del(sobj); + if (_elm_widget_is(sobj)) { - Elm_Widget_Smart_Data *sdp = evas_object_smart_data_get(parent); + if (elm_widget_focus_get(sobj)) _unfocus_parents(obj); + } - /* should be there, just being paranoid */ - if (sdp) + // set the resize obj up + if (_elm_widget_is(sobj)) + { + Smart_Data *sd2 = evas_object_smart_data_get(sobj); + if (sd2) { - if (sdp->resize_obj == sobj) - elm_widget_resize_object_set(parent, NULL); - else - elm_widget_sub_object_del(parent, sobj); + sd2->parent_obj = obj; + sd2->top_win_focused = sd->top_win_focused; } + evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE, + _sub_obj_hide, sd); } - - elm_widget_sub_object_add(obj, sobj); - evas_object_smart_member_add(sobj, obj); - + evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, + _sub_obj_del, sd); evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN, _sub_obj_mouse_down, sd); evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_MOVE, @@ -1599,12 +1129,14 @@ elm_widget_resize_object_set(Evas_Object *obj, evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_UP, _sub_obj_mouse_up, sd); _smart_reconfigure(sd); + evas_object_data_set(sobj, "elm-parent", obj); + evas_object_smart_callback_call(obj, "sub-object-add", sobj); + if (_elm_widget_is(sobj)) + { + if (elm_widget_focus_get(sobj)) _focus_parents(obj); + } } -/* WARNING: the programmer is responsible, in the scenario of - * exchanging a hover object, of cleaning the old hover "target" - * before - */ EAPI void elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj) @@ -1831,7 +1363,7 @@ elm_widget_parent_widget_get(const Evas_Object *obj) if (_elm_widget_is(obj)) { - Elm_Widget_Smart_Data *sd = evas_object_smart_data_get(obj); + Smart_Data *sd = evas_object_smart_data_get(obj); if (!sd) return NULL; parent = sd->parent_obj; } @@ -1857,7 +1389,7 @@ elm_widget_parent2_get(const Evas_Object *obj) { if (_elm_widget_is(obj)) { - Elm_Widget_Smart_Data *sd = evas_object_smart_data_get(obj); + Smart_Data *sd = evas_object_smart_data_get(obj); if (sd) return sd->parent2; } return NULL; @@ -1909,7 +1441,6 @@ elm_widget_event_propagate(Evas_Object *obj, Evas_Event_Flags *event_flags) { API_ENTRY return EINA_FALSE; //TODO reduce. - if (!_elm_widget_is(obj)) return EINA_FALSE; Evas_Object *parent = obj; Elm_Event_Cb_Data *ecd; @@ -1922,7 +1453,7 @@ elm_widget_event_propagate(Evas_Object *obj, if ((!sd) || (!_elm_widget_is(obj))) return EINA_FALSE; //Not Elm Widget - if (sd->api->event(parent, obj, type, event_info)) + if (sd->event_func && (sd->event_func(parent, obj, type, event_info))) return EINA_TRUE; EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd) @@ -1957,8 +1488,8 @@ elm_widget_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs) { API_ENTRY return; - - if (!_elm_widget_focus_chain_manager_is(obj)) return; + if (!sd->focus_next_func) + return; elm_widget_focus_custom_chain_unset(obj); @@ -2034,8 +1565,7 @@ elm_widget_focus_custom_chain_append(Evas_Object *obj, { API_ENTRY return; EINA_SAFETY_ON_NULL_RETURN(child); - - if (!_elm_widget_focus_chain_manager_is(obj)) return; + if (!sd->focus_next_func) return; evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _elm_object_focus_chain_del_cb, sd); @@ -2070,7 +1600,7 @@ elm_widget_focus_custom_chain_prepend(Evas_Object *obj, API_ENTRY return; EINA_SAFETY_ON_NULL_RETURN(child); - if (!_elm_widget_focus_chain_manager_is(obj)) return; + if (!sd->focus_next_func) return; evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL, _elm_object_focus_chain_del_cb, sd); @@ -2168,8 +1698,8 @@ elm_widget_focus_next_get(const Evas_Object *obj, return EINA_FALSE; /* Try use hook */ - if (_elm_widget_focus_chain_manager_is(obj)) - return sd->api->focus_next(obj, dir, next); + if (sd->focus_next_func) + return sd->focus_next_func(obj, dir, next); if (!elm_widget_can_focus_get(obj)) return EINA_FALSE; @@ -2291,11 +1821,8 @@ elm_widget_signal_emit(Evas_Object *obj, const char *source) { API_ENTRY return; - - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->signal) - COMPAT_SMART_DATA(sd)->signal(obj, emission, source); - else if (evas_object_smart_type_check(obj, "elm_layout")) - elm_layout_signal_emit(obj, emission, source); + if (!sd->signal_func) return; + sd->signal_func(obj, emission, source); } static void @@ -2317,31 +1844,19 @@ elm_widget_signal_callback_add(Evas_Object *obj, { Edje_Signal_Data *esd; API_ENTRY return; - + if (!sd->callback_add_func) return; EINA_SAFETY_ON_NULL_RETURN(func); - if (_elm_legacy_is(obj) && !COMPAT_SMART_DATA(sd)->callback_add) return; - else if (!evas_object_smart_type_check(obj, "elm_layout")) - return; + esd = ELM_NEW(Edje_Signal_Data); + if (!esd) return; - if (_elm_legacy_is(obj)) - { - esd = ELM_NEW(Edje_Signal_Data); - if (!esd) return; - - esd->obj = obj; - esd->func = func; - esd->emission = eina_stringshare_add(emission); - esd->source = eina_stringshare_add(source); - esd->data = data; - COMPAT_SMART_DATA(sd)->edje_signals = eina_list_append - (COMPAT_SMART_DATA(sd)->edje_signals, esd); - - COMPAT_SMART_DATA(sd)->callback_add - (obj, emission, source, _edje_signal_callback, esd); - } - else - elm_layout_signal_callback_add(obj, emission, source, func, data); + esd->obj = obj; + esd->func = func; + esd->emission = eina_stringshare_add(emission); + esd->source = eina_stringshare_add(source); + esd->data = data; + sd->edje_signals = eina_list_append(sd->edje_signals, esd); + sd->callback_add_func(obj, emission, source, _edje_signal_callback, esd); } EAPI void * @@ -2354,34 +1869,24 @@ elm_widget_signal_callback_del(Evas_Object *obj, Eina_List *l; void *data = NULL; API_ENTRY return NULL; + if (!sd->callback_del_func) return NULL; - if (_elm_legacy_is(obj) && !COMPAT_SMART_DATA(sd)->callback_del) - return NULL; - else if (!evas_object_smart_type_check(obj, "elm_layout")) - return NULL; - - if (_elm_legacy_is(obj)) + EINA_LIST_FOREACH(sd->edje_signals, l, esd) { - EINA_LIST_FOREACH (COMPAT_SMART_DATA(sd)->edje_signals, l, esd) + if ((esd->func == func) && (!strcmp(esd->emission, emission)) && + (!strcmp(esd->source, source))) { - if ((esd->func == func) && (!strcmp(esd->emission, emission)) && - (!strcmp(esd->source, source))) - { - COMPAT_SMART_DATA(sd)->edje_signals = eina_list_remove_list - (COMPAT_SMART_DATA(sd)->edje_signals, l); - eina_stringshare_del(esd->emission); - eina_stringshare_del(esd->source); - data = esd->data; - free(esd); - break; - } + sd->edje_signals = eina_list_remove_list(sd->edje_signals, l); + eina_stringshare_del(esd->emission); + eina_stringshare_del(esd->source); + data = esd->data; + free(esd); + + sd->callback_del_func + (obj, emission, source, _edje_signal_callback, esd); + return data; } - - COMPAT_SMART_DATA(sd)->callback_del - (obj, emission, source, _edje_signal_callback, esd); } - else - elm_layout_signal_callback_del(obj, emission, source, func); return data; } @@ -2391,18 +1896,16 @@ elm_widget_focus_set(Evas_Object *obj, int first) { API_ENTRY return; - if (!sd->focused) { focus_order++; sd->focus_order = focus_order; sd->focused = EINA_TRUE; - sd->api->on_focus(obj); + if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj); } - - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->focus) + if (sd->focus_func) { - COMPAT_SMART_DATA(sd)->focus(obj); + sd->focus_func(obj); return; } else @@ -2465,7 +1968,6 @@ EAPI void elm_widget_focused_object_clear(Evas_Object *obj) { API_ENTRY return; - if (!sd->focused) return; if (sd->resize_obj && elm_widget_focus_get(sd->resize_obj)) elm_widget_focused_object_clear(sd->resize_obj); @@ -2483,9 +1985,8 @@ elm_widget_focused_object_clear(Evas_Object *obj) } } sd->focused = EINA_FALSE; - sd->api->on_focus(obj); - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->focus) - COMPAT_SMART_DATA(sd)->focus(obj); + if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj); + if (sd->focus_func) sd->focus_func(obj); } EAPI void @@ -2583,21 +2084,16 @@ EAPI void elm_widget_activate(Evas_Object *obj) { API_ENTRY return; - elm_widget_change(obj); - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->activate) - COMPAT_SMART_DATA(sd)->activate(obj); + if (sd->activate_func) sd->activate_func(obj); } EAPI void elm_widget_change(Evas_Object *obj) { API_ENTRY return; - elm_widget_change(elm_widget_parent_get(obj)); - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->on_change) - COMPAT_SMART_DATA(sd)->on_change - (COMPAT_SMART_DATA(sd)->on_change_data, obj); + if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj); } EAPI void @@ -2609,7 +2105,7 @@ elm_widget_disabled_set(Evas_Object *obj, if (sd->disabled == disabled) return; sd->disabled = !!disabled; elm_widget_focus_disabled_handle(obj); - sd->api->disable(obj); + if (sd->disable_func) sd->disable_func(obj); } EAPI Eina_Bool @@ -2636,14 +2132,12 @@ elm_widget_show_region_set(Evas_Object *obj, if (!forceshow && (x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return; - sd->rx = x; sd->ry = y; sd->rw = w; sd->rh = h; - if (sd->on_show_region) - sd->on_show_region - (sd->on_show_region_data, obj); + if (sd->on_show_region_func) + sd->on_show_region_func(sd->on_show_region_data, obj); do { @@ -2663,10 +2157,9 @@ elm_widget_show_region_set(Evas_Object *obj, sd->rw = w; sd->rh = h; - if (sd->on_show_region) + if (sd->on_show_region_func) { - sd->on_show_region - (sd->on_show_region_data, parent_obj); + sd->on_show_region_func(sd->on_show_region_data, parent_obj); } } while (parent_obj); @@ -2713,20 +2206,19 @@ elm_widget_focus_region_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) { - Elm_Widget_Smart_Data *sd; + Smart_Data *sd; if (!obj) return; sd = evas_object_smart_data_get(obj); - if (!sd || !_elm_widget_is(obj) || - !(_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->on_focus_region)) + if (!sd || !_elm_widget_is(obj) || !sd->on_focus_region_func) { evas_object_geometry_get(obj, NULL, NULL, w, h); if (x) *x = 0; if (y) *y = 0; return; } - COMPAT_SMART_DATA(sd)->on_focus_region(obj, x, y, w, h); + sd->on_focus_region_func(obj, x, y, w, h); } EAPI void @@ -2834,10 +2326,10 @@ elm_widget_text_part_set(Evas_Object *obj, const char *part, const char *label) { API_ENTRY return; - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->text_set) - COMPAT_SMART_DATA(sd)->text_set(obj, part, label); - else if (evas_object_smart_type_check(obj, "elm_layout")) - elm_layout_text_set(obj, part, label); + if (!sd->text_set_func) + return; + + sd->text_set_func(obj, part, label); } EAPI const char * @@ -2845,12 +2337,10 @@ elm_widget_text_part_get(const Evas_Object *obj, const char *part) { API_ENTRY return NULL; - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->text_get) - return COMPAT_SMART_DATA(sd)->text_get(obj, part); - else if (evas_object_smart_type_check(obj, "elm_layout")) - return elm_layout_text_get(obj, part); + if (!sd->text_get_func) + return NULL; - return NULL; + return sd->text_get_func(obj, part); } EAPI void @@ -2935,11 +2425,10 @@ elm_widget_translate(Evas_Object *obj) #endif API_ENTRY return; - EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child); if (sd->resize_obj) elm_widget_translate(sd->resize_obj); if (sd->hover_obj) elm_widget_translate(sd->hover_obj); - sd->api->translate(obj); + if (sd->translate_func) sd->translate_func(obj); #ifdef HAVE_GETTEXT EINA_LIST_FOREACH(sd->translate_strings, l, ts) @@ -2955,10 +2444,8 @@ elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *con { API_ENTRY return; - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->content_set) - COMPAT_SMART_DATA(sd)->content_set(obj, part, content); - else if (evas_object_smart_type_check(obj, "elm_container")) - ELM_CONTAINER_CLASS(sd->api)->content_set(obj, part, content); + if (!sd->content_set_func) return; + sd->content_set_func(obj, part, content); } EAPI Evas_Object * @@ -2966,12 +2453,8 @@ elm_widget_content_part_get(const Evas_Object *obj, const char *part) { API_ENTRY return NULL; - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->content_get) - return COMPAT_SMART_DATA(sd)->content_get(obj, part); - else if (evas_object_smart_type_check(obj, "elm_container")) - return ELM_CONTAINER_CLASS(sd->api)->content_get(obj, part); - - return NULL; + if (!sd->content_get_func) return NULL; + return sd->content_get_func(obj, part); } EAPI Evas_Object * @@ -2979,12 +2462,8 @@ elm_widget_content_part_unset(Evas_Object *obj, const char *part) { API_ENTRY return NULL; - if (_elm_legacy_is(obj) && COMPAT_SMART_DATA(sd)->content_unset) - return COMPAT_SMART_DATA(sd)->content_unset(obj, part); - else if (evas_object_smart_type_check(obj, "elm_container")) - return ELM_CONTAINER_CLASS(sd->api)->content_unset(obj, part); - - return NULL; + if (!sd->content_unset_func) return NULL; + return sd->content_unset_func(obj, part); } EAPI void @@ -3042,21 +2521,15 @@ elm_widget_type_set(Evas_Object *obj, const char *type) { API_ENTRY return; - - if (!_elm_legacy_is(obj)) return; - - eina_stringshare_replace(&(COMPAT_SMART_DATA(sd)->type), type); + eina_stringshare_replace(&sd->type, type); } EAPI const char * elm_widget_type_get(const Evas_Object *obj) { API_ENTRY return NULL; - - if (_elm_legacy_is(obj) && (COMPAT_SMART_DATA(sd)->type)) - return COMPAT_SMART_DATA(sd)->type; - - return evas_object_type_get(obj); + if (sd->type) return sd->type; + return ""; } EAPI void @@ -3177,10 +2650,7 @@ elm_widget_type_check(const Evas_Object *obj, const char *provided, *expected = "(unknown)"; static int abort_on_warn = -1; provided = elm_widget_type_get(obj); - if (_elm_legacy_is(obj) && EINA_LIKELY(provided == type)) - return EINA_TRUE; - /* TODO: eventually migrate to check_ptr version */ - else if (evas_object_smart_type_check(obj, type)) return EINA_TRUE; + if (EINA_LIKELY(provided == type)) return EINA_TRUE; if (type) expected = type; if ((!provided) || (!provided[0])) { @@ -3912,7 +3382,7 @@ _elm_widget_item_cursor_engine_only_get(const Elm_Widget_Item *item) // smart object funcs static void -_smart_reconfigure(Elm_Widget_Smart_Data *sd) +_smart_reconfigure(Smart_Data *sd) { if (sd->resize_obj) { @@ -4068,29 +3538,15 @@ _elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt) static void _smart_add(Evas_Object *obj) { - const Evas_Smart_Class *sc; - const Evas_Smart *smart; + Smart_Data *sd; - EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data); - - smart = evas_object_smart_smart_get(obj); - sc = evas_smart_class_get(smart); - priv->api = (const Elm_Widget_Smart_Class *)sc; - priv->obj = obj; - priv->x = priv->y = priv->w = priv->h = 0; - priv->mirrored_auto_mode = EINA_TRUE; /* will follow system locale - * settings */ + sd = calloc(1, sizeof(Smart_Data)); + if (!sd) return; + sd->obj = obj; + sd->x = sd->y = sd->w = sd->h = 0; + sd->mirrored_auto_mode = EINA_TRUE; /* will follow system locale settings */ + evas_object_smart_data_set(obj, sd); elm_widget_can_focus_set(obj, EINA_TRUE); - elm_widget_mirrored_set(obj, elm_config_mirrored_get()); - - /* just a helper for inheriting classes */ - if (priv->resize_obj) - { - Evas_Object *r_obj = priv->resize_obj; - priv->resize_obj = NULL; - - elm_widget_resize_object_set(obj, r_obj); - } } static Evas_Object * @@ -4157,41 +3613,44 @@ static void _smart_del(Evas_Object *obj) { Evas_Object *sobj; + Edje_Signal_Data *esd; Elm_Translate_String_Data *ts; - ELM_WIDGET_DATA_GET(obj, sd); + INTERNAL_ENTRY; + if (sd->del_pre_func) sd->del_pre_func(obj); + if (sd->resize_obj) + { + sobj = sd->resize_obj; + sd->resize_obj = NULL; + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); + evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj); + evas_object_del(sobj); + sd->resize_obj = NULL; + } if (sd->hover_obj) { - /* detach it from us */ - evas_object_event_callback_del_full - (sd->hover_obj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); + sobj = sd->hover_obj; + sd->hover_obj = NULL; + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); + evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj); + evas_object_del(sobj); sd->hover_obj = NULL; } - - while (sd->subobjs) + EINA_LIST_FREE(sd->subobjs, sobj) { - sobj = eina_list_data_get(sd->subobjs); - - /* let the objects clean-up themselves and get rid of this list */ - if (_elm_legacy_is(sd->obj)) - { - evas_object_smart_callback_call(obj, "sub-object-del", sobj); - sd->subobjs = eina_list_remove_list(sd->subobjs, sd->subobjs); - } - else - { - if (!elm_widget_sub_object_del(obj, sobj)) - { - ERR("failed to remove sub object %p from %p\n", sobj, obj); - sd->subobjs = eina_list_remove_list - (sd->subobjs, sd->subobjs); - } - } + evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd); + evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj); evas_object_del(sobj); } sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */ sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */ + EINA_LIST_FREE(sd->edje_signals, esd) + { + eina_stringshare_del(esd->emission); + eina_stringshare_del(esd->source); + free(esd); + } EINA_LIST_FREE(sd->translate_strings, ts) { eina_stringshare_del(ts->id); @@ -4200,8 +3659,11 @@ _smart_del(Evas_Object *obj) free(ts); } sd->event_cb = eina_list_free(sd->event_cb); /* should be empty anyway */ + 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); + sd->data = NULL; _if_focused_revert(obj, EINA_TRUE); if (sd->access_info) eina_stringshare_del(sd->access_info); free(sd); @@ -4213,11 +3675,9 @@ _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { - ELM_WIDGET_DATA_GET(obj, sd); - + INTERNAL_ENTRY; sd->x = x; sd->y = y; - _smart_reconfigure(sd); } @@ -4226,11 +3686,9 @@ _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { - ELM_WIDGET_DATA_GET(obj, sd); - + INTERNAL_ENTRY; sd->w = w; sd->h = h; - _smart_reconfigure(sd); } @@ -4239,7 +3697,7 @@ _smart_show(Evas_Object *obj) { Eina_List *list; Evas_Object *o; - + INTERNAL_ENTRY; if ((list = evas_object_smart_members_get(obj))) { EINA_LIST_FREE(list, o) @@ -4255,6 +3713,7 @@ _smart_hide(Evas_Object *obj) { Eina_List *list; Evas_Object *o; + INTERNAL_ENTRY; list = evas_object_smart_members_get(obj); EINA_LIST_FREE(list, o) @@ -4273,7 +3732,7 @@ _smart_color_set(Evas_Object *obj, { Eina_List *list; Evas_Object *o; - + INTERNAL_ENTRY; if ((list = evas_object_smart_members_get(obj))) { EINA_LIST_FREE(list, o) @@ -4290,7 +3749,7 @@ _smart_clip_set(Evas_Object *obj, { Eina_List *list; Evas_Object *o; - + INTERNAL_ENTRY; if ((list = evas_object_smart_members_get(obj))) { EINA_LIST_FREE(list, o) @@ -4306,7 +3765,7 @@ _smart_clip_unset(Evas_Object *obj) { Eina_List *list; Evas_Object *o; - + INTERNAL_ENTRY; if ((list = evas_object_smart_members_get(obj))) { EINA_LIST_FREE(list, o) @@ -4318,9 +3777,10 @@ _smart_clip_unset(Evas_Object *obj) } static void -_smart_calculate(Evas_Object *obj __UNUSED__) +_smart_calculate(Evas_Object *obj) { - /* a NO-OP, on the base */ + INTERNAL_ENTRY; + if (sd->changed_func) sd->changed_func(obj); } static void @@ -4348,6 +3808,37 @@ _smart_member_del(Evas_Object *obj __UNUSED__, Evas_Object *child) evas_object_clip_unset(child); } +/* never need to touch this */ +static void +_smart_init(void) +{ + if (_e_smart) return; + { + static const Evas_Smart_Class sc = + { + SMART_NAME, + EVAS_SMART_CLASS_VERSION, + _smart_add, + _smart_del, + _smart_move, + _smart_resize, + _smart_show, + _smart_hide, + _smart_color_set, + _smart_clip_set, + _smart_clip_unset, + _smart_calculate, + _smart_member_add, + _smart_member_del, + NULL, + NULL, + NULL, + NULL + }; + _e_smart = evas_smart_class_new(&sc); + } +} + /* happy debug functions */ #ifdef ELM_DEBUG static void @@ -4364,7 +3855,7 @@ _sub_obj_tree_dump(const Evas_Object *obj, Eina_List *l; INTERNAL_ENTRY; printf("+ %s(%p)\n", - elm_widget_type_get(obj), + sd->type, obj); if (sd->resize_obj) _sub_obj_tree_dump(sd->resize_obj, lvl + 1); @@ -4405,8 +3896,7 @@ _sub_obj_tree_dot_dump(const Evas_Object *obj, } fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|" - "disabled: %d|focused: %d/%d|focus order:%d}\"", - obj, obj, elm_widget_type_get(obj), + "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type, evas_object_name_get(obj), visible, disabled, focused, can_focus, sd->focus_order); diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index 43d2e260b..2f0012109 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -188,297 +188,6 @@ #endif #define ELM_INTERNAL_API_VERSION 7000 -/** - * @defgroup Widget Widgets Extension Infrastructure - * - * This section is intended for people willing to create @b custom - * Elementary widgets or to contribute new (useful, unique) widgets - * upstream. If neither is your case, this text won't be of any use - * for you. - * - * Elementary widgets are built in a @b hierarchical fashion. The idea - * is to factorize as much code as possible between widgets with - * behavioral similarities, as long as to facilitate the creation of - * @b custom, new widgets, may the user need them. - * - * It all starts with a base class, which aggregates behaviour - * @b every Elementary widget is supposed to have: - * #Elm_Widget_Smart_Class. Every Elementary widget will be of that - * type, be it directly or by means of @b inheriting from it. - * - * #Elm_Widget_Smart_Class happens to be an @c Evas_Smart_Class. If - * you check out Evas' documentation on it, you'll see it's how one is - * supposed to create custom Evas objects, what Elementary widgets - * are. - * - * Once one instantiates an Elementary widget, since it inherits from - * #Elm_Widget_Smart_Class, the system will raise a class instance of - * that type for you. But that happens only @b once: the first time - * you ask for an Elementary widget (of a given type). All subsequent - * ones will only point to the very same class instance. Since it's - * the class which points to the functions implementing the behavior - * of objects of that type, all of the live instances of Elementary - * widgets (of that type) will share the same blob of code loaded in - * memory to execute their routines. - * - * Now go and take a look at #Elm_Widget_Smart_Class's fields. Because - * it inherits from Evas' base smart class, we got a field of that - * type as the first member, so that Evas can handle Elementary - * objects internally as if they were 'normal' Evas objects. Evas has - * the Evas-only behavior function pointers in there, so it's all it - * needs. - * - * Then, comes a version field, so that whenever we got to update or - * change the fields on our base smart class, there'll be a runtime - * check of the version expected by Elementary and the one provided by - * any code linking with it. A mismatch will show the developer of - * that code he/she needs to recompile and link its code to a newer - * version of Elementary. - * - * The next fields are the class functions itself. We call them - * 'virtual' because, as in object-oriented languages, one is supposed - * here to override them on inheriting classes. On most of - * inheritances you'll probably want to call the parent's version of - * the class function too: you must analise each case to tell. - * - * Take a look at #Elm_Widget_Smart_Data. That's private data bound to - * each Elementary object @b instance. It aggregates data needed for - * all widgets, since it's meant for the #Elm_Widget_Smart_Class-typed - * ones. - * - * When inheriting from that base type, instance data for this new - * class has to have, as the first member, a field of type - * #Elm_Widget_Smart_Data. This has to be respected recursively -- if - * a third class is to be created inheriting from the one that is a - * direct 'child' of #Elm_Widget_Smart_Class, then the private data on - * this third class has to have, as its first field, a variable of the - * type of the private data of the second class (its parent), direct - * child of #Elm_Widget_Smart_Class. - * - * [image here later, explaining process] - * - * It is from the base private data, #Elm_Widget_Smart_Data, that we - * reach an object's class functions, by the given object - * instance. This is the reason of the first field of that struct: a - * pointer set to point to its class when the object is instantiated. - * - * @section elm-migration Elementary's Migration to a hierarchical schema - * - * What's been stated before is a work in progress. Elementary 1.0 is - * @b not hierarchical in this way, but the idea is to get at this - * shape, now. This section is here to explain the process of - * migration, and it will be taken off once it's completed. - * - * We want to migrate widgets to the new schema progressively, one by - * one. In order for this to happen without hurting anyone during the - * process, it was made a @b compatibility class for Elementary - * widgets, to take place of the old, unique smart class for - * them. This is the role of #Elm_Widget_Compat_Smart_Class. - * - * All functions we had as 'hooks' before will be migrated to class - * functions. As you can see, all calls to @b instance hooks on the - * common code for widgets were replaced to <b> class function calls - * </b>, now. It just happens that, for - * #Elm_Widget_Compat_Smart_Class-typed widgets, i.e., the ones not - * migrated to the new schema yet, class calls are proxyed back to - * their instance 'hook' calls, that live on - * #Elm_Widget_Compat_Smart_Data structs. Those structs are - * #Elm_Widget_Smart_Data augmented with what is needed to reach the - * original widget's data field set, so that things go on @b unnoticed - * for the widgets awaiting translation to the new hierarchy. - * - * The following figure illustrates the old an new widget schemas, - * with highlights on their differences. - * - * @image html elm-widget-hierarchy.png - * @image rtf elm-widget-hierarchy.png - * @image latex elm-widget-hierarchy.eps - */ - -/** - * @addtogroup Widget - * @{ - */ - -/** - * @def ELM_WIDGET_CLASS - * - * Use this macro to cast whichever subclass of - * #Elm_Widget_Smart_Class into it, so to acess its fields. - * - * @ingroup Widget - */ -#define ELM_WIDGET_CLASS(x) ((Elm_Widget_Smart_Class *) x) - -/** - * @def ELM_WIDGET_DATA - * - * Use this macro to cast whichever subdata of - * #Elm_Widget_Smart_Data into it, so to acess its fields. - * - * @ingroup Widget - */ -#define ELM_WIDGET_DATA(x) ((Elm_Widget_Smart_Data *) x) - -/** - * @def ELM_WIDGET_SMART_CLASS_VERSION - * - * Current version for Elementary widget @b base smart class, a value - * which goes to _Elm_Widget_Smart_Class::version. - * - * @ingroup Wiget - */ -#define ELM_WIDGET_SMART_CLASS_VERSION 1 - -/** - * @def ELM_WIDGET_SMART_CLASS_INIT - * - * Initializer for a whole #Elm_Widget_Smart_Class structure, with - * @c NULL values on its specific fields. - * - * @param smart_class_init initializer to use for the "base" field - * (#Evas_Smart_Class). - * - * @see EVAS_SMART_CLASS_INIT_NULL - * @see EVAS_SMART_CLASS_INIT_VERSION - * @see EVAS_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_WIDGET_SMART_CLASS_INIT_NULL - * @see ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION - * - * @ingroup Widget - */ -#define ELM_WIDGET_SMART_CLASS_INIT(smart_class_init) \ - {smart_class_init, ELM_WIDGET_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL} - -/** - * @def ELM_WIDGET_SMART_CLASS_INIT_NULL - * - * Initializer to zero out a whole #Elm_Widget_Smart_Class structure. - * - * @see ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_WIDGET_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_WIDGET_SMART_CLASS_INIT_NULL \ - ELM_WIDGET_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL) - -/** - * @def ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION - * - * Initializer to zero out a whole #Elm_Widget_Smart_Class structure and - * set its name and version. - * - * This is similar to #ELM_WIDGET_SMART_CLASS_INIT_NULL, but it will - * also set the version field of #Elm_Widget_Smart_Class (base field) - * to the latest #ELM_WIDGET_SMART_CLASS_VERSION and name it to the - * specific value. - * - * It will keep a reference to the name field as a <c>"const char *"</c>, - * i.e., the name must be available while the structure is - * used (hint: static or global variable!) and must not be modified. - * - * @see ELM_WIDGET_SMART_CLASS_INIT_NULL - * @see ELM_WIDGET_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(name) \ - ELM_WIDGET_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NAME_VERSION(name)) - -/** - * Base widget smart class. It has the 'virtual' functions for all - * general, common actions on Elementary widgets. - */ -typedef struct _Elm_Widget_Smart_Class -{ - Evas_Smart_Class base; /**< Base smart class struct, needed for all smart objects */ - int version; /**< Version of this smart class definition */ - - Eina_Bool (*on_focus)(Evas_Object *obj); /**< 'Virtual' function handling receipt of focus on the widget */ - Eina_Bool (*disable)(Evas_Object *obj); /**< 'Virtual' function on the widget being disabled */ - Eina_Bool (*theme)(Evas_Object *obj); /**< 'Virtual' function on the widget being re-themed */ - Eina_Bool (*translate)(Evas_Object *obj); /**< 'Virtual' function handling language changes on Elementary */ - Eina_Bool (*event)(Evas_Object *obj, - Evas_Object *source, - Evas_Callback_Type type, - void *event_info); /**< 'Virtual' function handling input events on the widget */ - Eina_Bool (*focus_next)(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next); /**< 'Virtual' function handling passing focus to sub-objects */ - - Eina_Bool (*sub_object_add)(Evas_Object *obj, - Evas_Object *sobj); /**< 'Virtual' function handling sub objects being added */ - - Eina_Bool (*sub_object_del)(Evas_Object *obj, - Evas_Object *sobj); /**< 'Virtual' function handling sub objects being removed */ -} Elm_Widget_Smart_Class; - -/** - * Base widget smart data. This is data bound to an Elementary object - * @b instance, so its particular to that specific object and not - * shared between all objects in its class. It is here, though, that - * we got a pointer to the object's class, the first field -- @c - * 'api'. - */ -typedef struct _Elm_Widget_Smart_Data -{ - const Elm_Widget_Smart_Class *api; /**< This is the pointer to the object's class, from where we can reach/call its class functions */ - - Evas_Object *obj; - Evas_Object *parent_obj; - Evas_Object *parent2; - Evas_Coord x, y, w, h; - Eina_List *subobjs; - Evas_Object *resize_obj; - Evas_Object *hover_obj; - Eina_List *tooltips, *cursors; - - Evas_Coord rx, ry, rw, rh; - int scroll_hold; - int scroll_freeze; - double scale; - Elm_Theme *theme; - const char *style; - const char *access_info; - unsigned int focus_order; - Eina_Bool focus_order_on_calc; - - int child_drag_x_locked; - int child_drag_y_locked; - - Eina_List *translate_strings; - Eina_List *focus_chain; - Eina_List *event_cb; - - /* subject to later analysis: to be changed by something different */ - void *on_show_region_data; - void (*on_show_region)(void *data, - Evas_Object *obj); - - Eina_Bool drag_x_locked : 1; - Eina_Bool drag_y_locked : 1; - - Eina_Bool can_focus : 1; - Eina_Bool child_can_focus : 1; - Eina_Bool focused : 1; - Eina_Bool top_win_focused : 1; - Eina_Bool tree_unfocusable : 1; - Eina_Bool highlight_ignore : 1; - Eina_Bool highlight_in_theme : 1; - Eina_Bool disabled : 1; - Eina_Bool is_mirrored : 1; - Eina_Bool mirrored_auto_mode : 1; /* This is - * TRUE by - * default */ - Eina_Bool still_in : 1; -} Elm_Widget_Smart_Data; - -/** - * @} - */ - typedef struct _Elm_Tooltip Elm_Tooltip; typedef struct _Elm_Cursor Elm_Cursor; @@ -617,8 +326,9 @@ EAPI void elm_widget_content_unset_hook_set(Evas_Object *obj, Elm_Wi EAPI void elm_widget_on_focus_region_hook_set(Evas_Object *obj, void (*func)(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)); EAPI void elm_widget_data_set(Evas_Object *obj, void *data); EAPI void *elm_widget_data_get(const Evas_Object *obj); -EAPI Eina_Bool elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj); -EAPI Eina_Bool elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj); +EAPI void elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj); +EAPI void elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj); +EAPI const Eina_List *elm_widget_sub_object_list_get(const Evas_Object *obj); EAPI void elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj); EAPI void elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj); EAPI void elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source); @@ -657,7 +367,6 @@ EAPI Evas_Object *elm_widget_parent_get(const Evas_Object *obj); EAPI Evas_Object *elm_widget_parent2_get(const Evas_Object *obj); EAPI void elm_widget_parent2_set(Evas_Object *obj, Evas_Object *parent); EAPI void elm_widget_focus_steal(Evas_Object *obj); -EAPI const Elm_Widget_Smart_Class *elm_widget_smart_class_get(void); /** * @internal diff --git a/src/lib/elm_widget_button.h b/src/lib/elm_widget_button.h deleted file mode 100644 index d120e2e30..000000000 --- a/src/lib/elm_widget_button.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef ELM_WIDGET_BUTTON_H -#define ELM_WIDGET_BUTTON_H - -#include "elm_widget_layout.h" - -/** - * @addtogroup Widget - * @{ - * - * @section elm-button-class The Elementary Button Class - * - * Elementary, besides having the @ref Button widget, exposes its - * foundation -- the Elementary Button Class -- in order to create - * other widgets which are, basically, a button with some more logic - * on top. - */ - -/** - * @def ELM_BUTTON_CLASS - * - * Use this macro to cast whichever subclass of - * #Elm_Button_Smart_Class into it, so to acess its fields. - * - * @ingroup Button - */ -#define ELM_BUTTON_CLASS(x) ((Elm_Button_Smart_Class *) x) - -/** - * @def ELM_BUTTON_DATA - * - * Use this macro to cast whichever subdata of - * #Elm_Button_Smart_Data into it, so to acess its fields. - * - * @ingroup Button - */ -#define ELM_BUTTON_DATA(x) ((Elm_Button_Smart_Data *) x) - -/** - * @def ELM_BUTTON_SMART_CLASS_VERSION - * - * Current version for Elementary button @b base smart class, a value - * which goes to _Elm_Button_Smart_Class::version. - * - * @ingroup Widget - */ -#define ELM_BUTTON_SMART_CLASS_VERSION 1 - -/** - * @def ELM_BUTTON_SMART_CLASS_INIT - * - * Initializer for a whole #Elm_Button_Smart_Class structure, with - * @c NULL values on its specific fields. - * - * @param smart_class_init initializer to use for the "base" field - * (#Evas_Smart_Class). - * - * @see EVAS_SMART_CLASS_INIT_NULL - * @see EVAS_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_BUTTON_SMART_CLASS_INIT_NULL - * @see ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION - * - * @ingroup Widget - */ -#define ELM_BUTTON_SMART_CLASS_INIT(smart_class_init) \ - {smart_class_init, ELM_BUTTON_SMART_CLASS_VERSION, EINA_TRUE} - -/** - * @def ELM_BUTTON_SMART_CLASS_INIT_NULL - * - * Initializer to zero out a whole #Elm_Button_Smart_Class structure. - * - * @see ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_BUTTON_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_BUTTON_SMART_CLASS_INIT_NULL \ - ELM_BUTTON_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL) - -/** - * @def ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION - * - * Initializer to zero out a whole #Elm_Button_Smart_Class structure and - * set its name and version. - * - * This is similar to #ELM_BUTTON_SMART_CLASS_INIT_NULL, but it will - * also set the version field of #Elm_Button_Smart_Class (base field) - * to the latest #ELM_BUTTON_SMART_CLASS_VERSION and name it to the - * specific value. - * - * It will keep a reference to the name field as a <c>"const char *"</c>, - * i.e., the name must be available while the structure is - * used (hint: static or global variable!) and must not be modified. - * - * @see ELM_BUTTON_SMART_CLASS_INIT_NULL - * @see ELM_BUTTON_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_BUTTON_SMART_CLASS_INIT_NAME_VERSION(name) \ - ELM_BUTTON_SMART_CLASS_INIT(ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION(name)) - -/** - * Elementary button base smart class. This inherits directly from - * #Elm_Layout_Smart_Class and is meant to build widgets extending the - * behavior of a button. - * - * All of the functions listed on @ref Button namespace will work for - * objects deriving from #Elm_Button_Smart_Class. - */ -typedef struct _Elm_Button_Smart_Class -{ - Elm_Layout_Smart_Class base; /**< Layout widget class struct, since we're inheriting from it */ - - int version; /**< Version of this smart class definition */ - - Eina_Bool admits_autorepeat : 1; /**< Whether the button objects of this class admit auto-repetition of click events, when one holds the click on them. This is true by default. */ -} Elm_Button_Smart_Class; - -/** - * Base widget smart data extended with button widget data. - */ -typedef struct _Elm_Button_Smart_Data -{ - Elm_Layout_Smart_Data base; /**< Base widget smart data as first member obligatory, as we're inheriting from it */ - - /* auto-repeat stuff */ - double ar_threshold; /**< Time to wait until first auto-repeated click is generated */ - double ar_interval; /**< Time frame for subsequent auto-repeated clicks, after the first automatic one is triggerred */ - - Ecore_Timer *timer; /**< Internal timer object for auto-repeat behavior */ - - Eina_Bool autorepeat : 1; /**< Whether auto-repetition of clicks is enabled or not (bound to _Elm_Button_Smart_Class::admits_autorepeat) */ - Eina_Bool repeating : 1; /**< Whether auto-repetition is going on */ -} Elm_Button_Smart_Data; - -/** - * @} - */ - -EAPI const Elm_Button_Smart_Class *elm_button_smart_class_get(void); - -#endif diff --git a/src/lib/elm_widget_container.h b/src/lib/elm_widget_container.h deleted file mode 100644 index c0ba21e14..000000000 --- a/src/lib/elm_widget_container.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef ELM_WIDGET_CONTAINER_H -#define ELM_WIDGET_CONTAINER_H - -/** - * @addtogroup Widget - * @{ - * - * @section elm-container-class The Elementary Container Class - * - * This class defines a common interface for objects acting like - * containers, i.e. objects parenting others and displaying their - * childs "inside" of them somehow. - * - * The container must define "parts" (or spots) into which child - * objects will be placed, inside of it. This is a way of handling - * more the one content object, by naming content locations - * properly. This is the role of the @c name argument of the virtual - * functions in the class. - * - * The following object functions are meant to be used with all - * container objects and derived ones: - * - * - elm_object_part_content_set() - * - elm_object_part_content_get() - * - elm_object_part_content_unset() - */ - - /** - * @def ELM_CONTAINER_CLASS - * - * Use this macro to cast whichever subclass of - * #Elm_Container_Smart_Class into it, so to acess its fields. - * - * @ingroup Container - */ - #define ELM_CONTAINER_CLASS(x) ((Elm_Container_Smart_Class *) x) - -/** - * @def ELM_CONTAINER_SMART_CLASS_VERSION - * - * Current version for Elementary container @b base smart class, a value - * which goes to _Elm_Container_Smart_Class::version. - * - * @ingroup Widget - */ -#define ELM_CONTAINER_SMART_CLASS_VERSION 1 - -/** - * @def ELM_CONTAINER_SMART_CLASS_INIT - * - * Initializer for a whole #Elm_Container_Smart_Class structure, with - * @c NULL values on its specific fields. - * - * @param smart_class_init initializer to use for the "base" field - * (#Evas_Smart_Class). - * - * @see EVAS_SMART_CLASS_INIT_NULL - * @see EVAS_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_CONTAINER_SMART_CLASS_INIT_NULL - * @see ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION - * - * @ingroup Widget - */ -#define ELM_CONTAINER_SMART_CLASS_INIT(smart_class_init) \ - {smart_class_init, ELM_CONTAINER_SMART_CLASS_VERSION, NULL, NULL, NULL} - -/** - * @def ELM_CONTAINER_SMART_CLASS_INIT_NULL - * - * Initializer to zero out a whole #Elm_Container_Smart_Class structure. - * - * @see ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_CONTAINER_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_CONTAINER_SMART_CLASS_INIT_NULL \ - ELM_CONTAINER_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL) - -/** - * @def ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION - * - * Initializer to zero out a whole #Elm_Container_Smart_Class structure and - * set its name and version. - * - * This is similar to #ELM_CONTAINER_SMART_CLASS_INIT_NULL, but it will - * also set the version field of #Elm_Container_Smart_Class (base field) - * to the latest #ELM_CONTAINER_SMART_CLASS_VERSION and name it to the - * specific value. - * - * It will keep a reference to the name field as a <c>"const char *"</c>, - * i.e., the name must be available while the structure is - * used (hint: static or global variable!) and must not be modified. - * - * @see ELM_CONTAINER_SMART_CLASS_INIT_NULL - * @see ELM_CONTAINER_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(name) \ - ELM_CONTAINER_SMART_CLASS_INIT(ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(name)) - -/** - * Elementary container base smart class. This inherits directly from - * #Elm_Widget_Smart_Class and is meant to build widgets relying on an - * Edje container as a building block of its visuals. - * - * For instance, the elm_container @b widget itself is just a realization - * of this smart class (see the code for elm_container_add()). All of the - * functions listed on @ref Container namespace will work for objects - * deriving from #Elm_Container_Smart_Class. - */ - -typedef struct _Elm_Container_Smart_Class -{ - Elm_Widget_Smart_Class base; /**< Base Elementary widget class struct, since we're inheriting from it */ - - int version; /**< Version of this smart class definition */ - Eina_Bool (*content_set)(Evas_Object *obj, - const char *part, - Evas_Object *content); /* 'Virtual' function on setting content on the object, at the given @a part part */ - Evas_Object *(*content_get)(const Evas_Object * obj, - const char *part); /* 'Virtual' function on retrieving content from the object, at the given @a part part */ - Evas_Object *(*content_unset)(Evas_Object * obj, - const char *part); /* 'Virtual' function on unsetting content from the object, at the given @a part part. Meant to return the content's pointer. */ -} Elm_Container_Smart_Class; - -/** - * @} - */ - -EAPI const Elm_Container_Smart_Class *elm_container_smart_class_get(void); - -#endif diff --git a/src/lib/elm_widget_layout.h b/src/lib/elm_widget_layout.h deleted file mode 100644 index 2b14c18ef..000000000 --- a/src/lib/elm_widget_layout.h +++ /dev/null @@ -1,257 +0,0 @@ -#ifndef ELM_WIDGET_LAYOUT_H -#define ELM_WIDGET_LAYOUT_H - -#include "elm_widget_container.h" - -/** - * @addtogroup Widget - * @{ - * - * @section elm-layout-class The Elementary Layout Class - * - * Elementary, besides having the @ref Layout widget, exposes its - * foundation -- the Elementary Layout Class -- in order to create - * other widgets which are, basically, a certain layout with some more - * logic on top. - * - * The idea is make the creation of that widgets as easy as possible, - * factorizing code on this common base. For example, a button is a - * layout (that looks like push button) that happens to react on - * clicks and keyboard events in a special manner, calling its user - * back on those events. That's no surprise, then, that the @ref - * Button implementation relies on #Elm_Layout_Smart_Class, if you go - * to check it. - * - * The Layout class inherits from - * #Elm_Container_Smart_Class. Container parts, here, map directly to - * Edje parts from the layout's Edje group. Besides that, there's a whole - * infrastructure around Edje files: - * - intefacing by signals, - * - setting/retrieving text part values, - * - dealing with table and box parts directly, - * - etc. - * - * Take a look at #Elm_Layout_Smart_Class's 'virtual' functions to - * understand the whole interface. Finally, layout objects will do - * <b>part aliasing</b> for you, if you set it up properly. For that, - * take a look at #Elm_Layout_Part_Alias_Description, where it's - * explained in detail. - */ - -/** - * @def ELM_LAYOUT_CLASS - * - * Use this macro to cast whichever subclass of - * #Elm_Layout_Smart_Class into it, so to acess its fields. - * - * @ingroup Widget - */ -#define ELM_LAYOUT_CLASS(x) ((Elm_Layout_Smart_Class *) x) - -/** - * @def ELM_LAYOUT_DATA - * - * Use this macro to cast whichever subdata of - * #Elm_Layout_Smart_Data into it, so to acess its fields. - * - * @ingroup Widget - */ -#define ELM_LAYOUT_DATA(x) ((Elm_Layout_Smart_Data *) x) - -/** - * @def ELM_LAYOUT_SMART_CLASS_VERSION - * - * Current version for Elementary layout @b base smart class, a value - * which goes to _Elm_Layout_Smart_Class::version. - * - * @ingroup Widget - */ -#define ELM_LAYOUT_SMART_CLASS_VERSION 1 - -/** - * @def ELM_LAYOUT_SMART_CLASS_INIT - * - * Initializer for a whole #Elm_Layout_Smart_Class structure, with - * @c NULL values on its specific fields. - * - * @param smart_class_init initializer to use for the "base" field - * (#Evas_Smart_Class). - * - * @see EVAS_SMART_CLASS_INIT_NULL - * @see EVAS_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_LAYOUT_SMART_CLASS_INIT_NULL - * @see ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION - * - * @ingroup Widget - */ -#define ELM_LAYOUT_SMART_CLASS_INIT(smart_class_init) \ - {smart_class_init, ELM_LAYOUT_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL} - -/** - * @def ELM_LAYOUT_SMART_CLASS_INIT_NULL - * - * Initializer to zero out a whole #Elm_Layout_Smart_Class structure. - * - * @see ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION - * @see ELM_LAYOUT_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_LAYOUT_SMART_CLASS_INIT_NULL \ - ELM_LAYOUT_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL) - -/** - * @def ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION - * - * Initializer to zero out a whole #Elm_Layout_Smart_Class structure and - * set its name and version. - * - * This is similar to #ELM_LAYOUT_SMART_CLASS_INIT_NULL, but it will - * also set the version field of #Elm_Layout_Smart_Class (base field) - * to the latest #ELM_LAYOUT_SMART_CLASS_VERSION and name it to the - * specific value. - * - * It will keep a reference to the name field as a <c>"const char *"</c>, - * i.e., the name must be available while the structure is - * used (hint: static or global variable!) and must not be modified. - * - * @see ELM_LAYOUT_SMART_CLASS_INIT_NULL - * @see ELM_LAYOUT_SMART_CLASS_INIT - * - * @ingroup Widget - */ -#define ELM_LAYOUT_SMART_CLASS_INIT_NAME_VERSION(name) \ - ELM_LAYOUT_SMART_CLASS_INIT \ - (ELM_CONTAINER_SMART_CLASS_INIT_NAME_VERSION(name)) - -/** - * @typedef Elm_Layout_Part_Alias_Description - * - * A layout part aliasing (proxying) description, used to get part - * names aliasing independently of a widgets theme. - * - * @ingroup Widget - */ -typedef struct _Elm_Layout_Part_Alias_Description Elm_Layout_Part_Alias_Description; - -/** - * @struct _Elm_Layout_Part_Alias_Description - * - * Elementary Layout-based widgets may declare part proxies, i.e., aliases - * for real theme part names to expose to the API calls: - * - elm_layout_text_set() - * - elm_layout_text_get() - * - elm_layout_content_set() - * - elm_layout_content_get() - * - elm_layout_content_unset() - * and their equivalents. This list must be set on the - * @c "_smart_set_user()" function of inheriting widgets, so that part - * aliasing is handled automatically for them. - * - * @ingroup Widget - */ -struct _Elm_Layout_Part_Alias_Description -{ - const char *alias; /**< Alternate name for a given (real) part. Calls receiving this string as a part name will be translated to the string at _Elm_Layout_Part_Proxies_Description::real_part */ - - const char *real_part; /**< Target part name for the alias set on @ref _Elm_Layout_Part_Proxies_Description::real_part. An example of usage would be @c "default" on that field, with @c "elm.content.swallow" on this one */ -}; - -/** - * Elementary layout base smart class. This inherits directly from - * #Elm_Container_Smart_Class and is meant to build widgets relying on - * an Edje layout as a building block of its visuals. - * - * For instance, the elm_layout @b widget itself is just a realization - * of this smart class (see the code for elm_layout_add()). All of the - * functions listed on @ref Layout namespace will work for objects - * deriving from #Elm_Layout_Smart_Class. - */ -typedef struct _Elm_Layout_Smart_Class -{ - Elm_Container_Smart_Class base; /**< Elementary container widget class struct, since we're inheriting from it */ - - int version; /**< Version of this smart class definition */ - - void (*sizing_eval)(Evas_Object *obj); /* 'Virtual' function on evalutating the object's final geometry, accounting for its sub-objects */ - void (*signal)(Evas_Object *obj, - const char *emission, - const char *source); /* 'Virtual' function on emitting an (Edje) signal to the object, acting on its internal layout */ - void (*callback_add)(Evas_Object *obj, - const char *emission, - const char *source, - Edje_Signal_Cb func, - void *data); /* 'Virtual' function on adding an (Edje) signal callback to the object, proxyed from its internal layout */ - void * (*callback_del)(Evas_Object * obj, - const char *emission, - const char *source, - Edje_Signal_Cb func); /* 'Virtual' function on deleting an (Edje) signal callback on the object, proxyed from its internal layout */ - Eina_Bool (*text_set)(Evas_Object *obj, - const char *part, - const char *text); /* 'Virtual' function on setting text on an (Edje) part of the object, from its internal layout */ - const char *(*text_get)(const Evas_Object * obj, - const char *part); /* 'Virtual' function on fetching text from an (Edje) part of the object, on its internal layout */ - - Eina_Bool (*box_append)(Evas_Object *obj, - const char *part, - Evas_Object *child); /* 'Virtual' function on appending an object to an (Edje) box part of the object, from its internal layout */ - Eina_Bool (*box_prepend)(Evas_Object *obj, - const char *part, - Evas_Object *child); /* 'Virtual' function on prepending an object to an (Edje) box part of the object, from its internal layout */ - Eina_Bool (*box_insert_before)(Evas_Object *obj, - const char *part, - Evas_Object *child, - const Evas_Object *reference); /* 'Virtual' function on inserting an object to an (Edje) box part of the object, from its internal layout. The new child's position in the box is be prior to the one of a relative child already in the box */ - Eina_Bool (*box_insert_at)(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned int pos); /* 'Virtual' function on inserting an object to an (Edje) box part of the object, from its internal layout. The new child's position number is passed explicitly */ - Evas_Object *(*box_remove)(Evas_Object * obj, - const char *part, - Evas_Object * child); /* 'Virtual' function on removing an object from an (Edje) box part of the object, on its internal layout */ - Eina_Bool (*box_remove_all)(Evas_Object *obj, - const char *part, - Eina_Bool clear); /* 'Virtual' function on removing @b all objects from an (Edje) box part of the object, on its internal layout */ - Eina_Bool (*table_pack)(Evas_Object *obj, - const char *part, - Evas_Object *child, - unsigned short col, - unsigned short row, - unsigned short colspan, - unsigned short rowspan); /* 'Virtual' function on inserting an object to an (Edje) table part of the object, from its internal layout */ - Evas_Object *(*table_unpack)(Evas_Object * obj, - const char *part, - Evas_Object * child); /* 'Virtual' function on removing an object from an (Edje) table part of the object, on its internal layout */ - Eina_Bool (*table_clear)(Evas_Object *obj, - const char *part, - Eina_Bool clear); /* 'Virtual' function on removing @b all objects from an (Edje) table part of the object, on its internal layout */ - - const Elm_Layout_Part_Alias_Description *content_aliases; /**< List of (@c 'SWALLOW') part aliases, <b>@c NULL terminated</b>. If @c NULL is passed as part name, it will be translated to the 1st _Elm_Layout_Part_Proxies_Description::real_part field in the list. */ - - const Elm_Layout_Part_Alias_Description *text_aliases; /**< List of (@c 'TEXT' or 'TEXTBLOCK') part aliases, <b>@c NULL terminated</b>. If @c NULL is passed as part name, it will be translated to the 1st _Elm_Layout_Part_Proxies_Description::real_part field in the list. */ -} Elm_Layout_Smart_Class; - -/** - * Base widget smart data extended with layout widget data. - */ -typedef struct _Elm_Layout_Smart_Data -{ - Elm_Widget_Smart_Data base; /**< Base widget smart data as first member obligatory */ - - Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects */ - Eina_List *edje_signals; - Eina_List *parts_cursors; - const char *klass, *group; - - Eina_Bool needs_size_calc : 1; -} Elm_Layout_Smart_Data; - -/** - * @} - */ - -EAPI const Elm_Layout_Smart_Class *elm_layout_smart_class_get(void); - -#endif diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index 833cace2a..400d6691e 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -1,125 +1,124 @@ #include <Elementary.h> #include "elm_priv.h" -#include "elm_widget_layout.h" /* for inwin */ - -static const char WIN_SMART_NAME[] = "elm_win"; - -#define ELM_WIN_DATA_GET(o, sd) \ - Elm_Win_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_WIN_DATA_GET_OR_RETURN(o, ptr) \ - ELM_WIN_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_WIN_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_WIN_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define ELM_WIN_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), WIN_SMART_NAME, __func__)) \ - return - -typedef struct _Elm_Win_Smart_Data Elm_Win_Smart_Data; - -struct _Elm_Win_Smart_Data -{ - Elm_Widget_Smart_Data base; /* base widget smart data as - * first member obligatory, as - * we're inheriting from it */ - - Ecore_Evas *ee; - Evas *evas; - Evas_Object *parent; /* parent *window* object*/ - Evas_Object *img_obj, *frame_obj; - Eina_List *resize_objs; /* a window may have - * *multiple* resize - * objects */ + +typedef struct _Elm_Win Elm_Win; + +struct _Elm_Win +{ + Ecore_Evas *ee; + Evas *evas; + Evas_Object *parent, *win_obj, *img_obj, *frame_obj; + Eina_List *subobjs; #ifdef HAVE_ELEMENTARY_X - Ecore_X_Window xwin; - Ecore_Event_Handler *client_message_handler; + Ecore_X_Window xwin; + Ecore_Event_Handler *client_message_handler; #endif - Ecore_Job *deferred_resize_job; - Ecore_Job *deferred_child_eval_job; + Ecore_Job *deferred_resize_job; + Ecore_Job *deferred_child_eval_job; - Elm_Win_Type type; - Elm_Win_Keyboard_Mode kbdmode; - Elm_Win_Indicator_Mode indmode; + Elm_Win_Type type; + Elm_Win_Keyboard_Mode kbdmode; + Elm_Win_Indicator_Mode indmode; Elm_Win_Indicator_Opacity_Mode ind_o_mode; struct - { - const char *info; - Ecore_Timer *timer; - int repeat_count; - int shot_counter; - } shot; - int resize_location; - int *autodel_clear, rot; - int show_count; + { + const char *info; + Ecore_Timer *timer; + int repeat_count; + int shot_counter; + } shot; + int resize_location; + int *autodel_clear, rot; + int show_count; struct - { - int x, y; - } screen; + { + int x, y; + } screen; struct - { - Ecore_Evas *ee; - Evas *evas; - Evas_Object *obj, *hot_obj; - int hot_x, hot_y; - } pointer; + { + Ecore_Evas *ee; + Evas *evas; + Evas_Object *obj, *hot_obj; + int hot_x, hot_y; + } pointer; struct - { - Evas_Object *top; + { + Evas_Object *top; - struct - { - Evas_Object *target; - Eina_Bool visible : 1; - Eina_Bool handled : 1; - } cur, prev; + struct + { + Evas_Object *target; + Eina_Bool visible : 1; + Eina_Bool handled : 1; + } cur, prev; - const char *style; - Ecore_Job *reconf_job; + const char *style; + Ecore_Job *reconf_job; - Eina_Bool enabled : 1; - Eina_Bool changed_theme : 1; - Eina_Bool top_animate : 1; - Eina_Bool geometry_changed : 1; - } focus_highlight; + Eina_Bool enabled : 1; + Eina_Bool changed_theme : 1; + Eina_Bool top_animate : 1; + Eina_Bool geometry_changed : 1; + } focus_highlight; Evas_Object *icon; - const char *title; - const char *icon_name; - const char *role; - - double aspect; - Eina_Bool urgent : 1; - Eina_Bool modal : 1; - Eina_Bool demand_attention : 1; - Eina_Bool autodel : 1; - Eina_Bool constrain : 1; - Eina_Bool resizing : 1; - Eina_Bool iconified : 1; - Eina_Bool withdrawn : 1; - Eina_Bool sticky : 1; - Eina_Bool fullscreen : 1; - Eina_Bool maximized : 1; - Eina_Bool skip_focus : 1; + const char *title; + const char *icon_name; + const char *role; + + double aspect; + Eina_Bool urgent : 1; + Eina_Bool modal : 1; + Eina_Bool demand_attention : 1; + Eina_Bool autodel : 1; + Eina_Bool constrain : 1; + Eina_Bool resizing : 1; + Eina_Bool iconified : 1; + Eina_Bool withdrawn : 1; + Eina_Bool sticky : 1; + Eina_Bool fullscreen : 1; + Eina_Bool maximized : 1; + Eina_Bool skip_focus : 1; }; +static const char *widtype = NULL; +static void _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_win_obj_callback_img_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_win_obj_callback_parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _elm_win_obj_intercept_show(void *data, Evas_Object *obj); +static void _elm_win_move(Ecore_Evas *ee); +static void _elm_win_resize(Ecore_Evas *ee); +static void _elm_win_delete_request(Ecore_Evas *ee); +static void _elm_win_resize_job(void *data); +#ifdef HAVE_ELEMENTARY_X +static void _elm_win_xwin_update(Elm_Win *win); +#endif +static void _elm_win_eval_subobjs(Evas_Object *obj); +static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _elm_win_focus_highlight_init(Elm_Win *win); +static void _elm_win_focus_highlight_shutdown(Elm_Win *win); +static void _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible); +static void _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win); +static void _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win); +static void _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _elm_win_focus_highlight_reconfigure(Elm_Win *win); + +static void _elm_win_frame_add(Elm_Win *win, const char *style); +static void _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__); +static void _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source); +static void _elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__); +static void _elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__); +static void _elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__); + +//static void _elm_win_pointer_add(Elm_Win *win, const char *style); + static const char SIG_DELETE_REQUEST[] = "delete,request"; static const char SIG_FOCUS_OUT[] = "focus,out"; static const char SIG_FOCUS_IN[] = "focus,in"; static const char SIG_MOVED[] = "moved"; +static const char SIG_THEME_CHANGED[] = "theme,changed"; static const char SIG_WITHDRAWN[] = "withdrawn"; static const char SIG_ICONIFIED[] = "iconified"; static const char SIG_NORMAL[] = "normal"; @@ -130,7 +129,7 @@ static const char SIG_UNFULLSCREEN[] = "unfullscreen"; static const char SIG_MAXIMIZED[] = "maximized"; static const char SIG_UNMAXIMIZED[] = "unmaximized"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { +static const Evas_Smart_Cb_Description _signals[] = { {SIG_DELETE_REQUEST, ""}, {SIG_FOCUS_OUT, ""}, {SIG_FOCUS_IN, ""}, @@ -147,9 +146,7 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { {NULL, NULL} }; -EVAS_SMART_SUBCLASS_NEW - (WIN_SMART_NAME, _elm_win, Elm_Widget_Smart_Class, - Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks); + Eina_List *_elm_win_list = NULL; int _elm_win_deferred_free = 0; @@ -158,13 +155,13 @@ int _elm_win_deferred_free = 0; // ELM_ENGINE="shot:delay=0.1:file=my-window.png" static double -_shot_delay_get(Elm_Win_Smart_Data *sd) +_shot_delay_get(Elm_Win *win) { char *p, *pd; - char *d = strdup(sd->shot.info); + char *d = strdup(win->shot.info); if (!d) return 0.5; - for (p = (char *)sd->shot.info; *p; p++) + for (p = (char *)win->shot.info; *p; p++) { if (!strncmp(p, "delay=", 6)) { @@ -181,36 +178,34 @@ _shot_delay_get(Elm_Win_Smart_Data *sd) } } free(d); - return 0.5; } static char * -_shot_file_get(Elm_Win_Smart_Data *sd) +_shot_file_get(Elm_Win *win) { char *p; - char *tmp = strdup(sd->shot.info); + char *tmp = strdup(win->shot.info); char *repname = NULL; if (!tmp) return NULL; - for (p = (char *)sd->shot.info; *p; p++) + for (p = (char *)win->shot.info; *p; p++) { if (!strncmp(p, "file=", 5)) { strcpy(tmp, p + 5); - if (!sd->shot.repeat_count) return tmp; + if (!win->shot.repeat_count) return tmp; else { char *dotptr = strrchr(tmp, '.'); if (dotptr) { - size_t size = sizeof(char) * (strlen(tmp) + 16); + size_t size = sizeof(char)*(strlen(tmp) + 16); repname = malloc(size); strncpy(repname, tmp, dotptr - tmp); - snprintf(repname + (dotptr - tmp), size - - (dotptr - tmp), "%03i", - sd->shot.shot_counter + 1); + snprintf(repname + (dotptr - tmp), size - (dotptr - tmp), "%03i", + win->shot.shot_counter + 1); strcat(repname, dotptr); free(tmp); return repname; @@ -219,23 +214,21 @@ _shot_file_get(Elm_Win_Smart_Data *sd) } } free(tmp); - if (!sd->shot.repeat_count) return strdup("out.png"); + if (!win->shot.repeat_count) return strdup("out.png"); repname = malloc(sizeof(char) * 24); - snprintf(repname, sizeof(char) * 24, "out%03i.png", - sd->shot.shot_counter + 1); - + snprintf(repname, sizeof(char) * 24, "out%03i.png", win->shot.shot_counter + 1); return repname; } static int -_shot_repeat_count_get(Elm_Win_Smart_Data *sd) +_shot_repeat_count_get(Elm_Win *win) { char *p, *pd; - char *d = strdup(sd->shot.info); + char *d = strdup(win->shot.info); if (!d) return 0; - for (p = (char *)sd->shot.info; *p; p++) + for (p = (char *)win->shot.info; *p; p++) { if (!strncmp(p, "repeat=", 7)) { @@ -254,24 +247,23 @@ _shot_repeat_count_get(Elm_Win_Smart_Data *sd) } } free(d); - return 0; } static char * -_shot_key_get(Elm_Win_Smart_Data *sd __UNUSED__) +_shot_key_get(Elm_Win *win __UNUSED__) { return NULL; } static char * -_shot_flags_get(Elm_Win_Smart_Data *sd __UNUSED__) +_shot_flags_get(Elm_Win *win __UNUSED__) { return NULL; } static void -_shot_do(Elm_Win_Smart_Data *sd) +_shot_do(Elm_Win *win) { Ecore_Evas *ee; Evas_Object *o; @@ -279,21 +271,18 @@ _shot_do(Elm_Win_Smart_Data *sd) int w, h; char *file, *key, *flags; - ecore_evas_manual_render(sd->ee); - pixels = (void *)ecore_evas_buffer_pixels_get(sd->ee); + ecore_evas_manual_render(win->ee); + pixels = (void *)ecore_evas_buffer_pixels_get(win->ee); if (!pixels) return; - - ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h); + ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h); if ((w < 1) || (h < 1)) return; - - file = _shot_file_get(sd); + file = _shot_file_get(win); if (!file) return; - - key = _shot_key_get(sd); - flags = _shot_flags_get(sd); + key = _shot_key_get(win); + flags = _shot_flags_get(win); ee = ecore_evas_buffer_new(1, 1); o = evas_object_image_add(ecore_evas_get(ee)); - evas_object_image_alpha_set(o, ecore_evas_alpha_get(sd->ee)); + evas_object_image_alpha_set(o, ecore_evas_alpha_get(win->ee)); evas_object_image_size_set(o, w, h); evas_object_image_data_set(o, pixels); if (!evas_object_image_save(o, file, key, flags)) @@ -305,303 +294,104 @@ _shot_do(Elm_Win_Smart_Data *sd) if (key) free(key); if (flags) free(flags); ecore_evas_free(ee); - if (sd->shot.repeat_count) sd->shot.shot_counter++; + if (win->shot.repeat_count) win->shot.shot_counter++; } static Eina_Bool _shot_delay(void *data) { - Elm_Win_Smart_Data *sd = data; - - _shot_do(sd); - if (sd->shot.repeat_count) + Elm_Win *win = data; + _shot_do(win); + if (win->shot.repeat_count) { - int remainshot = (sd->shot.repeat_count - sd->shot.shot_counter); + int remainshot = (win->shot.repeat_count - win->shot.shot_counter); if (remainshot > 0) return EINA_TRUE; } - sd->shot.timer = NULL; + win->shot.timer = NULL; elm_exit(); - return EINA_FALSE; } static void -_shot_init(Elm_Win_Smart_Data *sd) +_shot_init(Elm_Win *win) { - if (!sd->shot.info) return; - - sd->shot.repeat_count = _shot_repeat_count_get(sd); - sd->shot.shot_counter = 0; + if (!win->shot.info) return; + win->shot.repeat_count = _shot_repeat_count_get(win); + win->shot.shot_counter = 0; } static void -_shot_handle(Elm_Win_Smart_Data *sd) +_shot_handle(Elm_Win *win) { - if (!sd->shot.info) return; - - sd->shot.timer = ecore_timer_add(_shot_delay_get(sd), _shot_delay, sd); + if (!win->shot.info) return; + win->shot.timer = ecore_timer_add(_shot_delay_get(win), _shot_delay, win); } static void _elm_win_move(Ecore_Evas *ee) { Evas_Object *obj = ecore_evas_object_associate_get(ee); + Elm_Win *win; int x, y; if (!obj) return; - - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + win = elm_widget_data_get(obj); + if (!win) return; ecore_evas_geometry_get(ee, &x, &y, NULL, NULL); - sd->screen.x = x; - sd->screen.y = y; - evas_object_smart_callback_call(obj, SIG_MOVED, NULL); -} - -static void -_elm_win_resize_job(void *data) -{ - Elm_Win_Smart_Data *sd = data; - const Eina_List *l; - Evas_Object *obj; - int w, h; - - sd->deferred_resize_job = NULL; - ecore_evas_request_geometry_get(sd->ee, NULL, NULL, &w, &h); - if (sd->constrain) - { - int sw, sh; - ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh); - w = MIN(w, sw); - h = MIN(h, sh); - } - if (sd->frame_obj) - { - evas_object_resize(sd->frame_obj, w, h); - } - else if (sd->img_obj) - { - } - evas_object_resize(ELM_WIDGET_DATA(sd)->obj, w, h); - EINA_LIST_FOREACH (sd->resize_objs, l, obj) - { - evas_object_move(obj, 0, 0); - evas_object_resize(obj, w, h); - } + win->screen.x = x; + win->screen.y = y; + evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL); } static void _elm_win_resize(Ecore_Evas *ee) { Evas_Object *obj = ecore_evas_object_associate_get(ee); + Elm_Win *win; if (!obj) return; - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->deferred_resize_job) ecore_job_del(sd->deferred_resize_job); - sd->deferred_resize_job = ecore_job_add(_elm_win_resize_job, sd); + win = elm_widget_data_get(obj); + if (!win) return; + if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job); + win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win); } static void _elm_win_mouse_in(Ecore_Evas *ee) { Evas_Object *obj; + Elm_Win *win; if (!(obj = ecore_evas_object_associate_get(ee))) return; - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->resizing) sd->resizing = EINA_FALSE; -} - -static void -_elm_win_focus_highlight_reconfigure_job_stop(Elm_Win_Smart_Data *sd) -{ - if (sd->focus_highlight.reconf_job) - ecore_job_del(sd->focus_highlight.reconf_job); - sd->focus_highlight.reconf_job = NULL; -} - -static void -_elm_win_focus_highlight_visible_set(Elm_Win_Smart_Data *sd, - Eina_Bool visible) -{ - Evas_Object *top; - - top = sd->focus_highlight.top; - if (visible) - { - if (top) - { - evas_object_show(top); - edje_object_signal_emit(top, "elm,action,focus,show", "elm"); - } - } - else - { - if (top) - edje_object_signal_emit(top, "elm,action,focus,hide", "elm"); - } -} - -static void -_elm_win_focus_highlight_anim_setup(Elm_Win_Smart_Data *sd, - Evas_Object *obj) -{ - Evas_Coord tx, ty, tw, th; - Evas_Coord w, h, px, py, pw, ph; - Edje_Message_Int_Set *m; - Evas_Object *previous = sd->focus_highlight.prev.target; - Evas_Object *target = sd->focus_highlight.cur.target; - - evas_object_geometry_get(ELM_WIDGET_DATA(sd)->obj, NULL, NULL, &w, &h); - evas_object_geometry_get(target, &tx, &ty, &tw, &th); - evas_object_geometry_get(previous, &px, &py, &pw, &ph); - evas_object_move(obj, 0, 0); - evas_object_resize(obj, tw, th); - evas_object_clip_unset(obj); - - m = alloca(sizeof(*m) + (sizeof(int) * 8)); - m->count = 8; - m->val[0] = px; - m->val[1] = py; - m->val[2] = pw; - m->val[3] = ph; - m->val[4] = tx; - m->val[5] = ty; - m->val[6] = tw; - m->val[7] = th; - edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m); -} - -static void -_elm_win_focus_highlight_simple_setup(Elm_Win_Smart_Data *sd, - Evas_Object *obj) -{ - Evas_Object *clip, *target = sd->focus_highlight.cur.target; - Evas_Coord x, y, w, h; - - clip = evas_object_clip_get(target); - evas_object_geometry_get(target, &x, &y, &w, &h); - - evas_object_move(obj, x, y); - evas_object_resize(obj, w, h); - evas_object_clip_set(obj, clip); -} - -static void -_elm_win_focus_highlight_reconfigure(Elm_Win_Smart_Data *sd) -{ - Evas_Object *target = sd->focus_highlight.cur.target; - Evas_Object *previous = sd->focus_highlight.prev.target; - Evas_Object *top = sd->focus_highlight.top; - Eina_Bool visible_changed; - Eina_Bool common_visible; - const char *sig = NULL; - - _elm_win_focus_highlight_reconfigure_job_stop(sd); - - visible_changed = (sd->focus_highlight.cur.visible != - sd->focus_highlight.prev.visible); - - if ((target == previous) && (!visible_changed) && - (!sd->focus_highlight.geometry_changed)) - return; - - if ((previous) && (sd->focus_highlight.prev.handled)) - elm_widget_signal_emit - (previous, "elm,action,focus_highlight,hide", "elm"); - - if (!target) - common_visible = EINA_FALSE; - else if (sd->focus_highlight.cur.handled) - { - common_visible = EINA_FALSE; - if (sd->focus_highlight.cur.visible) - sig = "elm,action,focus_highlight,show"; - else - sig = "elm,action,focus_highlight,hide"; - } - else - common_visible = sd->focus_highlight.cur.visible; - - _elm_win_focus_highlight_visible_set(sd, common_visible); - if (sig) - elm_widget_signal_emit(target, sig, "elm"); - - if ((!target) || (!common_visible) || (sd->focus_highlight.cur.handled)) - goto the_end; - - if (sd->focus_highlight.changed_theme) - { - const char *str; - if (sd->focus_highlight.style) - str = sd->focus_highlight.style; - else - str = "default"; - elm_widget_theme_object_set - (ELM_WIDGET_DATA(sd)->obj, top, "focus_highlight", "top", str); - sd->focus_highlight.changed_theme = EINA_FALSE; - - if (_elm_config->focus_highlight_animate) - { - str = edje_object_data_get(sd->focus_highlight.top, "animate"); - sd->focus_highlight.top_animate = ((str) && (!strcmp(str, "on"))); - } - } - - if ((sd->focus_highlight.top_animate) && (previous) && - (!sd->focus_highlight.prev.handled)) - _elm_win_focus_highlight_anim_setup(sd, top); - else - _elm_win_focus_highlight_simple_setup(sd, top); - evas_object_raise(top); - -the_end: - sd->focus_highlight.geometry_changed = EINA_FALSE; - sd->focus_highlight.prev = sd->focus_highlight.cur; -} - -static void -_elm_win_focus_highlight_reconfigure_job(void *data) -{ - _elm_win_focus_highlight_reconfigure((Elm_Win_Smart_Data *)data); -} - -static void -_elm_win_focus_highlight_reconfigure_job_start(Elm_Win_Smart_Data *sd) -{ - if (sd->focus_highlight.reconf_job) - ecore_job_del(sd->focus_highlight.reconf_job); - - sd->focus_highlight.reconf_job = ecore_job_add( - _elm_win_focus_highlight_reconfigure_job, sd); + if (!(win = elm_widget_data_get(obj))) return; + if (win->resizing) win->resizing = EINA_FALSE; } static void _elm_win_focus_in(Ecore_Evas *ee) { Evas_Object *obj = ecore_evas_object_associate_get(ee); + Elm_Win *win; if (!obj) return; - - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - _elm_widget_top_win_focused_set(obj, EINA_TRUE); + win = elm_widget_data_get(obj); + if (!win) return; + _elm_widget_top_win_focused_set(win->win_obj, EINA_TRUE); if (!elm_widget_focus_order_get(obj)) { - elm_widget_focus_steal(obj); - sd->show_count++; + elm_widget_focus_steal(win->win_obj); + win->show_count++; } else - elm_widget_focus_restore(obj); - evas_object_smart_callback_call(obj, SIG_FOCUS_IN, NULL); - sd->focus_highlight.cur.visible = EINA_TRUE; - _elm_win_focus_highlight_reconfigure_job_start(sd); - if (sd->frame_obj) + elm_widget_focus_restore(win->win_obj); + evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_IN, NULL); + win->focus_highlight.cur.visible = EINA_TRUE; + _elm_win_focus_highlight_reconfigure_job_start(win); + if (win->frame_obj) { - edje_object_signal_emit(sd->frame_obj, "elm,action,focus", "elm"); + edje_object_signal_emit(win->frame_obj, "elm,action,focus", "elm"); } - else if (sd->img_obj) + else if (win->img_obj) { /* do nothing */ } @@ -611,21 +401,21 @@ static void _elm_win_focus_out(Ecore_Evas *ee) { Evas_Object *obj = ecore_evas_object_associate_get(ee); + Elm_Win *win; if (!obj) return; - - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - elm_object_focus_set(obj, EINA_FALSE); - _elm_widget_top_win_focused_set(obj, EINA_FALSE); - evas_object_smart_callback_call(obj, SIG_FOCUS_OUT, NULL); - sd->focus_highlight.cur.visible = EINA_FALSE; - _elm_win_focus_highlight_reconfigure_job_start(sd); - if (sd->frame_obj) + win = elm_widget_data_get(obj); + if (!win) return; + elm_object_focus_set(win->win_obj, EINA_FALSE); + _elm_widget_top_win_focused_set(win->win_obj, EINA_FALSE); + evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_OUT, NULL); + win->focus_highlight.cur.visible = EINA_FALSE; + _elm_win_focus_highlight_reconfigure_job_start(win); + if (win->frame_obj) { - edje_object_signal_emit(sd->frame_obj, "elm,action,unfocus", "elm"); + edje_object_signal_emit(win->frame_obj, "elm,action,unfocus", "elm"); } - else if (sd->img_obj) + else if (win->img_obj) { /* do nothing */ } @@ -635,6 +425,7 @@ static void _elm_win_state_change(Ecore_Evas *ee) { Evas_Object *obj; + Elm_Win *win; Eina_Bool ch_withdrawn = EINA_FALSE; Eina_Bool ch_sticky = EINA_FALSE; Eina_Bool ch_iconified = EINA_FALSE; @@ -643,84 +434,83 @@ _elm_win_state_change(Ecore_Evas *ee) if (!(obj = ecore_evas_object_associate_get(ee))) return; - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); + if (!(win = elm_widget_data_get(obj))) return; - if (sd->withdrawn != ecore_evas_withdrawn_get(sd->ee)) + if (win->withdrawn != ecore_evas_withdrawn_get(win->ee)) { - sd->withdrawn = ecore_evas_withdrawn_get(sd->ee); + win->withdrawn = ecore_evas_withdrawn_get(win->ee); ch_withdrawn = EINA_TRUE; } - if (sd->sticky != ecore_evas_sticky_get(sd->ee)) + if (win->sticky != ecore_evas_sticky_get(win->ee)) { - sd->sticky = ecore_evas_sticky_get(sd->ee); + win->sticky = ecore_evas_sticky_get(win->ee); ch_sticky = EINA_TRUE; } - if (sd->iconified != ecore_evas_iconified_get(sd->ee)) + if (win->iconified != ecore_evas_iconified_get(win->ee)) { - sd->iconified = ecore_evas_iconified_get(sd->ee); + win->iconified = ecore_evas_iconified_get(win->ee); ch_iconified = EINA_TRUE; } - if (sd->fullscreen != ecore_evas_fullscreen_get(sd->ee)) + if (win->fullscreen != ecore_evas_fullscreen_get(win->ee)) { - sd->fullscreen = ecore_evas_fullscreen_get(sd->ee); + win->fullscreen = ecore_evas_fullscreen_get(win->ee); ch_fullscreen = EINA_TRUE; } - if (sd->maximized != ecore_evas_maximized_get(sd->ee)) + if (win->maximized != ecore_evas_maximized_get(win->ee)) { - sd->maximized = ecore_evas_maximized_get(sd->ee); + win->maximized = ecore_evas_maximized_get(win->ee); ch_maximized = EINA_TRUE; } if ((ch_withdrawn) || (ch_iconified)) { - if (sd->withdrawn) - evas_object_smart_callback_call(obj, SIG_WITHDRAWN, NULL); - else if (sd->iconified) - evas_object_smart_callback_call(obj, SIG_ICONIFIED, NULL); + if (win->withdrawn) + evas_object_smart_callback_call(win->win_obj, SIG_WITHDRAWN, NULL); + else if (win->iconified) + evas_object_smart_callback_call(win->win_obj, SIG_ICONIFIED, NULL); else - evas_object_smart_callback_call(obj, SIG_NORMAL, NULL); + evas_object_smart_callback_call(win->win_obj, SIG_NORMAL, NULL); } if (ch_sticky) { - if (sd->sticky) - evas_object_smart_callback_call(obj, SIG_STICK, NULL); + if (win->sticky) + evas_object_smart_callback_call(win->win_obj, SIG_STICK, NULL); else - evas_object_smart_callback_call(obj, SIG_UNSTICK, NULL); + evas_object_smart_callback_call(win->win_obj, SIG_UNSTICK, NULL); } if (ch_fullscreen) { - if (sd->fullscreen) - evas_object_smart_callback_call(obj, SIG_FULLSCREEN, NULL); + if (win->fullscreen) + evas_object_smart_callback_call(win->win_obj, SIG_FULLSCREEN, NULL); else - evas_object_smart_callback_call(obj, SIG_UNFULLSCREEN, NULL); + evas_object_smart_callback_call(win->win_obj, SIG_UNFULLSCREEN, NULL); } if (ch_maximized) { - if (sd->maximized) - evas_object_smart_callback_call(obj, SIG_MAXIMIZED, NULL); + if (win->maximized) + evas_object_smart_callback_call(win->win_obj, SIG_MAXIMIZED, NULL); else - evas_object_smart_callback_call(obj, SIG_UNMAXIMIZED, NULL); + evas_object_smart_callback_call(win->win_obj, SIG_UNMAXIMIZED, NULL); } } static Eina_Bool -_elm_win_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - ELM_WIN_DATA_GET(obj, sd); - + Elm_Win *wd = elm_widget_data_get(obj); const Eina_List *items; - void *(*list_data_get)(const Eina_List *list); + const Eina_List *list; + void *(*list_data_get) (const Eina_List *list); + + if (!wd) + return EINA_FALSE; + list = elm_widget_sub_object_list_get(obj); /* Focus chain */ - if (ELM_WIDGET_DATA(sd)->subobjs) + if (list) { if (!(items = elm_widget_focus_custom_chain_get(obj))) - { - items = ELM_WIDGET_DATA(sd)->subobjs; - if (!items) - return EINA_FALSE; - } + items = list; + list_data_get = eina_list_data_get; elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next); @@ -732,63 +522,53 @@ _elm_win_smart_focus_next(const Evas_Object *obj, return EINA_FALSE; } -static Eina_Bool -_elm_win_smart_on_focus(Evas_Object *obj) +static void +_elm_win_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) { - ELM_WIN_DATA_GET(obj, sd); + Elm_Win *win = elm_widget_data_get(obj); + if (!win) return; - if (sd->img_obj) - evas_object_focus_set(sd->img_obj, elm_widget_focus_get(obj)); + if (win->img_obj) + evas_object_focus_set(win->img_obj, elm_widget_focus_get(obj)); else - evas_object_focus_set(obj, elm_widget_focus_get(obj)); - - return EINA_TRUE; + evas_object_focus_set(obj, elm_widget_focus_get(obj)); } static Eina_Bool -_elm_win_smart_event(Evas_Object *obj, - Evas_Object *src __UNUSED__, - Evas_Callback_Type type, - void *event_info) +_elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info) { - Evas_Event_Key_Down *ev; - - if (elm_widget_disabled_get(obj)) return EINA_FALSE; - - if (type != EVAS_CALLBACK_KEY_DOWN) - return EINA_FALSE; - - ev = event_info; - if (!strcmp(ev->keyname, "Tab")) - { - if (evas_key_modifier_is_set(ev->modifiers, "Shift")) - elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS); - else - elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT); - - ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; - - return EINA_TRUE; - } - else if ((!strcmp(ev->keyname, "Left")) || - ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) + if (type == EVAS_CALLBACK_KEY_DOWN) { - //TODO : woohyun jung - } - else if ((!strcmp(ev->keyname, "Right")) || - ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) - { - //TODO : woohyun jung - } - else if ((!strcmp(ev->keyname, "Up")) || - ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) - { - //TODO : woohyun jung - } - else if ((!strcmp(ev->keyname, "Down")) || - ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) - { - //TODO : woohyun jung + Evas_Event_Key_Down *ev = event_info; + if (!strcmp(ev->keyname, "Tab")) + { + if (evas_key_modifier_is_set(ev->modifiers, "Shift")) + elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS); + else + elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT); + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; + } + else if ((!strcmp(ev->keyname, "Left")) || + ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string))) + { + //TODO : woohyun jung + } + else if ((!strcmp(ev->keyname, "Right")) || + ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string))) + { + //TODO : woohyun jung + } + else if ((!strcmp(ev->keyname, "Up")) || + ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string))) + { + //TODO : woohyun jung + } + else if ((!strcmp(ev->keyname, "Down")) || + ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string))) + { + //TODO : woohyun jung + } } return EINA_FALSE; @@ -802,300 +582,166 @@ _deferred_ecore_evas_free(void *data) } static void -_elm_win_smart_show(Evas_Object *obj) +_elm_win_obj_callback_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIN_DATA_GET(obj, sd); - - _elm_win_parent_sc->base.show(obj); + Elm_Win *win = data; - if (!sd->show_count) sd->show_count++; - if (sd->shot.info) _shot_handle(sd); + if (!win->show_count) win->show_count++; + if (win->shot.info) _shot_handle(win); } static void -_elm_win_smart_hide(Evas_Object *obj) +_elm_win_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - ELM_WIN_DATA_GET(obj, sd); + Elm_Win *win = data; - _elm_win_parent_sc->base.hide(obj); - - if (sd->frame_obj) + if (win->frame_obj) { - evas_object_hide(sd->frame_obj); + evas_object_hide(win->frame_obj); } - else if (sd->img_obj) + else if (win->img_obj) { - evas_object_hide(sd->img_obj); + evas_object_hide(win->img_obj); } - if (sd->pointer.obj) + if (win->pointer.obj) { - evas_object_hide(sd->pointer.obj); - ecore_evas_hide(sd->pointer.ee); + evas_object_hide(win->pointer.obj); + ecore_evas_hide(win->pointer.ee); } } static void -_elm_win_on_parent_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) -{ - Elm_Win_Smart_Data *sd = data; - - if (obj == sd->parent) sd->parent = NULL; -} - -static void -_elm_win_focus_target_move(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Elm_Win_Smart_Data *sd = data; - - sd->focus_highlight.geometry_changed = EINA_TRUE; - _elm_win_focus_highlight_reconfigure_job_start(sd); -} - -static void -_elm_win_focus_target_resize(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Elm_Win_Smart_Data *sd = data; - - sd->focus_highlight.geometry_changed = EINA_TRUE; - _elm_win_focus_highlight_reconfigure_job_start(sd); -} - -static void -_elm_win_focus_target_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - Elm_Win_Smart_Data *sd = data; - - sd->focus_highlight.cur.target = NULL; - - _elm_win_focus_highlight_reconfigure_job_start(sd); -} - -static Evas_Object * -_elm_win_focus_target_get(Evas_Object *obj) -{ - Evas_Object *o = obj; - - do - { - if (elm_widget_is(o)) +_elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__) +{ + Elm_Win *win = data; + Evas_Object *child, *child2 = NULL; + + if (win->parent) + { + evas_object_event_callback_del_full(win->parent, EVAS_CALLBACK_DEL, + _elm_win_obj_callback_parent_del, win); + win->parent = NULL; + } + if (win->autodel_clear) *(win->autodel_clear) = -1; + _elm_win_list = eina_list_remove(_elm_win_list, win->win_obj); + while (win->subobjs) elm_win_resize_object_del(obj, win->subobjs->data); + if (win->ee) + { + ecore_evas_callback_delete_request_set(win->ee, NULL); + ecore_evas_callback_resize_set(win->ee, NULL); + } + if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job); + if (win->deferred_child_eval_job) ecore_job_del(win->deferred_child_eval_job); + if (win->shot.info) eina_stringshare_del(win->shot.info); + if (win->shot.timer) ecore_timer_del(win->shot.timer); + evas_object_event_callback_del_full(win->win_obj, EVAS_CALLBACK_DEL, + _elm_win_obj_callback_del, win); + child = evas_object_bottom_get(win->evas); + while (child) + { + /* if the object we see *IS* the window object (because we are + * faking a parent object inside the canvas), then skip it and + * go to the next one */ + if (child == obj) { - if (!elm_widget_highlight_ignore_get(o)) - break; - o = elm_widget_parent_get(o); - if (!o) - o = evas_object_smart_parent_get(o); + child = evas_object_above_get(child); + if (!child) break; + } + /* if we are using the next object above from the previous loop */ + if (child == child2) + { + /* this object has refcounts from the previous loop */ + child2 = evas_object_above_get(child); + if (child2) evas_object_ref(child2); + evas_object_del(child); + /* so unref from previous loop */ + evas_object_unref(child); + child = child2; } else { - o = elm_widget_parent_widget_get(o); - if (!o) - o = evas_object_smart_parent_get(o); + /* just delete as normal (probably only first object */ + child2 = evas_object_above_get(child); + if (child2) evas_object_ref(child2); + evas_object_del(child); + child = child2; } } - while (o); - - return o; -} - -static void -_elm_win_focus_target_callbacks_add(Elm_Win_Smart_Data *sd) -{ - Evas_Object *obj = sd->focus_highlight.cur.target; - - evas_object_event_callback_add - (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd); -} - -static void -_elm_win_focus_target_callbacks_del(Elm_Win_Smart_Data *sd) -{ - Evas_Object *obj = sd->focus_highlight.cur.target; - - evas_object_event_callback_del_full - (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd); - evas_object_event_callback_del_full - (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd); - evas_object_event_callback_del_full - (obj, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd); -} - -static void -_elm_win_object_focus_in(void *data, - Evas *e __UNUSED__, - void *event_info) -{ - Evas_Object *obj = event_info, *target; - Elm_Win_Smart_Data *sd = data; - - if (sd->focus_highlight.cur.target == obj) - return; - - target = _elm_win_focus_target_get(obj); - sd->focus_highlight.cur.target = target; - if (elm_widget_highlight_in_theme_get(target)) - sd->focus_highlight.cur.handled = EINA_TRUE; - else - _elm_win_focus_target_callbacks_add(sd); - - _elm_win_focus_highlight_reconfigure_job_start(sd); -} - -static void -_elm_win_object_focus_out(void *data, - Evas *e __UNUSED__, - void *event_info __UNUSED__) -{ - Elm_Win_Smart_Data *sd = data; - - if (!sd->focus_highlight.cur.target) - return; - - if (!sd->focus_highlight.cur.handled) - _elm_win_focus_target_callbacks_del(sd); - - sd->focus_highlight.cur.target = NULL; - sd->focus_highlight.cur.handled = EINA_FALSE; - - _elm_win_focus_highlight_reconfigure_job_start(sd); -} - -static void -_elm_win_focus_highlight_shutdown(Elm_Win_Smart_Data *sd) -{ - _elm_win_focus_highlight_reconfigure_job_stop(sd); - if (sd->focus_highlight.cur.target) - { - _elm_win_focus_target_callbacks_del(sd); - sd->focus_highlight.cur.target = NULL; - } - if (sd->focus_highlight.top) - { - evas_object_del(sd->focus_highlight.top); - sd->focus_highlight.top = NULL; - } - - evas_event_callback_del_full - (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, - _elm_win_object_focus_in, sd); - evas_event_callback_del_full - (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT, - _elm_win_object_focus_out, sd); -} - -static void -_elm_win_smart_del(Evas_Object *obj) -{ - ELM_WIN_DATA_GET(obj, sd); - - /* NB: child deletion handled by parent's smart del */ - - if (sd->parent) - { - evas_object_event_callback_del_full - (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, sd); - sd->parent = NULL; - } - - if (sd->autodel_clear) *(sd->autodel_clear) = -1; - - _elm_win_list = eina_list_remove(_elm_win_list, obj); - - if (sd->ee) - { - ecore_evas_callback_delete_request_set(sd->ee, NULL); - ecore_evas_callback_resize_set(sd->ee, NULL); - } - if (sd->deferred_resize_job) ecore_job_del(sd->deferred_resize_job); - if (sd->deferred_child_eval_job) ecore_job_del(sd->deferred_child_eval_job); - if (sd->shot.info) eina_stringshare_del(sd->shot.info); - if (sd->shot.timer) ecore_timer_del(sd->shot.timer); - #ifdef HAVE_ELEMENTARY_X - if (sd->client_message_handler) - ecore_event_handler_del(sd->client_message_handler); + if (win->client_message_handler) + ecore_event_handler_del(win->client_message_handler); #endif + // FIXME: Why are we flushing edje on every window destroy ?? + // edje_file_cache_flush(); + // edje_collection_cache_flush(); + // evas_image_cache_flush(win->evas); + // evas_font_cache_flush(win->evas); + // FIXME: we are in the del handler for the object and delete the canvas + // that lives under it from the handler... nasty. deferring doesn't help either - if (sd->img_obj) + if (win->img_obj) { - sd->img_obj = NULL; + win->img_obj = NULL; } else { - if (sd->ee) + if (win->ee) { - ecore_job_add(_deferred_ecore_evas_free, sd->ee); + ecore_job_add(_deferred_ecore_evas_free, win->ee); _elm_win_deferred_free++; } } - _elm_win_focus_highlight_shutdown(sd); - eina_stringshare_del(sd->focus_highlight.style); + _elm_win_focus_highlight_shutdown(win); + eina_stringshare_del(win->focus_highlight.style); - if (sd->title) eina_stringshare_del(sd->title); - if (sd->icon_name) eina_stringshare_del(sd->icon_name); - if (sd->role) eina_stringshare_del(sd->role); - if (sd->icon) evas_object_del(sd->icon); + if (win->title) eina_stringshare_del(win->title); + if (win->icon_name) eina_stringshare_del(win->icon_name); + if (win->role) eina_stringshare_del(win->role); + if (win->icon) evas_object_del(win->icon); - _elm_win_parent_sc->base.del(obj); /* handles freeing sd */ + free(win); if ((!_elm_win_list) && (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)) { edje_file_cache_flush(); edje_collection_cache_flush(); - evas_image_cache_flush(evas_object_evas_get(obj)); - evas_font_cache_flush(evas_object_evas_get(obj)); + evas_image_cache_flush(e); + evas_font_cache_flush(e); elm_exit(); } } static void -_elm_win_on_img_obj_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Win_Smart_Data *sd = data; - - if (!sd->img_obj) return; - + Elm_Win *win = data; + if (!win->img_obj) return; evas_object_event_callback_del_full - (sd->img_obj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, sd); + (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win); + evas_object_del(win->img_obj); +} - evas_object_del(sd->img_obj); +static void +_elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + Elm_Win *win = data; + if (obj == win->parent) win->parent = NULL; } static void -_elm_win_obj_intercept_move(void *data, - Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +_elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) { - Elm_Win_Smart_Data *sd = data; + Elm_Win *win = data; - if (sd->img_obj) + if (win->img_obj) { - if ((x != sd->screen.x) || (y != sd->screen.y)) + if ((x != win->screen.x) || (y != win->screen.y)) { - sd->screen.x = x; - sd->screen.y = y; - evas_object_smart_callback_call(obj, SIG_MOVED, NULL); + win->screen.x = x; + win->screen.y = y; + evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL); } } else @@ -1105,82 +751,88 @@ _elm_win_obj_intercept_move(void *data, } static void -_elm_win_obj_intercept_show(void *data, - Evas_Object *obj) +_elm_win_obj_intercept_show(void *data, Evas_Object *obj) { - Elm_Win_Smart_Data *sd = data; - + Elm_Win *win = data; // this is called to make sure all smart containers have calculated their // sizes BEFORE we show the window to make sure it initially appears at // our desired size (ie min size is known first) evas_smart_objects_calculate(evas_object_evas_get(obj)); - if (sd->frame_obj) + if (win->frame_obj) { - evas_object_show(sd->frame_obj); + evas_object_show(win->frame_obj); } - else if (sd->img_obj) + else if (win->img_obj) { - evas_object_show(sd->img_obj); + evas_object_show(win->img_obj); } - if (sd->pointer.obj) + if (win->pointer.obj) { - ecore_evas_show(sd->pointer.ee); - evas_object_show(sd->pointer.obj); + ecore_evas_show(win->pointer.ee); + evas_object_show(win->pointer.obj); + /* ecore_evas_wayland_pointer_set(win->pointer.ee, 10, 10); */ } evas_object_show(obj); } static void -_elm_win_smart_move(Evas_Object *obj, - Evas_Coord x, - Evas_Coord y) +_elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_WIN_DATA_GET(obj, sd); + Elm_Win *win = data; - _elm_win_parent_sc->base.move(obj, x, y); - - if (ecore_evas_override_get(sd->ee)) + if (ecore_evas_override_get(win->ee)) { - sd->screen.x = x; - sd->screen.y = y; - evas_object_smart_callback_call(obj, SIG_MOVED, NULL); + Evas_Coord x, y; + + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + win->screen.x = x; + win->screen.y = y; + evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL); } - if (sd->frame_obj) + if (win->frame_obj) { - sd->screen.x = x; - sd->screen.y = y; + Evas_Coord x, y; + + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + win->screen.x = x; + win->screen.y = y; + + /* FIXME: We should update ecore_wl_window_location here !! */ } - /* FIXME: We should update ecore_wl_window_location here !! */ - else if (sd->img_obj) + else if (win->img_obj) { - sd->screen.x = x; - sd->screen.y = y; + Evas_Coord x, y; + + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + win->screen.x = x; + win->screen.y = y; +// evas_object_move(win->img_obj, x, y); } } static void -_elm_win_smart_resize(Evas_Object *obj, - Evas_Coord w, - Evas_Coord h) +_elm_win_obj_callback_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_WIN_DATA_GET(obj, sd); - - _elm_win_parent_sc->base.resize(obj, w, h); + Elm_Win *win = data; - if (sd->img_obj) + if (win->frame_obj) { - if (sd->constrain) + } + else if (win->img_obj) + { + Evas_Coord w = 1, h = 1; + + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + if (win->constrain) { int sw, sh; - - ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh); + ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &sw, &sh); w = MIN(w, sw); h = MIN(h, sh); } if (w < 1) w = 1; if (h < 1) h = 1; - - evas_object_image_size_set(sd->img_obj, w, h); + evas_object_image_size_set(win->img_obj, w, h); } } @@ -1188,30 +840,63 @@ static void _elm_win_delete_request(Ecore_Evas *ee) { Evas_Object *obj = ecore_evas_object_associate_get(ee); + Elm_Win *win; + if (strcmp(elm_widget_type_get(obj), "win")) return; + + win = elm_widget_data_get(obj); + if (!win) return; + int autodel = win->autodel; + win->autodel_clear = &autodel; + evas_object_ref(win->win_obj); + evas_object_smart_callback_call(win->win_obj, SIG_DELETE_REQUEST, NULL); + // FIXME: if above callback deletes - then the below will be invalid + if (autodel) evas_object_del(win->win_obj); + else win->autodel_clear = NULL; + evas_object_unref(win->win_obj); +} - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); +static void +_elm_win_resize_job(void *data) +{ + Elm_Win *win = data; + const Eina_List *l; + Evas_Object *obj; + int w, h; - int autodel = sd->autodel; - sd->autodel_clear = &autodel; - evas_object_ref(obj); - evas_object_smart_callback_call(obj, SIG_DELETE_REQUEST, NULL); - // FIXME: if above callback deletes - then the below will be invalid - if (autodel) evas_object_del(obj); - else sd->autodel_clear = NULL; - evas_object_unref(obj); + win->deferred_resize_job = NULL; + ecore_evas_request_geometry_get(win->ee, NULL, NULL, &w, &h); + if (win->constrain) + { + int sw, sh; + ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &sw, &sh); + w = MIN(w, sw); + h = MIN(h, sh); + } + if (win->frame_obj) + { + evas_object_resize(win->frame_obj, w, h); + } + else if (win->img_obj) + { + } + evas_object_resize(win->win_obj, w, h); + EINA_LIST_FOREACH(win->subobjs, l, obj) + { + evas_object_move(obj, 0, 0); + evas_object_resize(obj, w, h); + } } #ifdef HAVE_ELEMENTARY_X static void -_elm_win_xwindow_get(Elm_Win_Smart_Data *sd) +_elm_win_xwindow_get(Elm_Win *win) { - sd->xwin = 0; + win->xwin = 0; #define ENGINE_COMPARE(name) (!strcmp(_elm_preferred_engine, name)) if (ENGINE_COMPARE(ELM_SOFTWARE_X11)) { - if (sd->ee) sd->xwin = ecore_evas_software_x11_window_get(sd->ee); + if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee); } else if (ENGINE_COMPARE(ELM_SOFTWARE_X11) || ENGINE_COMPARE(ELM_SOFTWARE_FB) || @@ -1219,65 +904,72 @@ _elm_win_xwindow_get(Elm_Win_Smart_Data *sd) ENGINE_COMPARE(ELM_SOFTWARE_SDL) || ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) || ENGINE_COMPARE(ELM_OPENGL_SDL) || - ENGINE_COMPARE(ELM_OPENGL_COCOA)) + ENGINE_COMPARE(ELM_OPENGL_COCOA)) { } else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11)) { - if (sd->ee) sd->xwin = ecore_evas_software_x11_16_window_get(sd->ee); + if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee); } else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11)) { - if (sd->ee) sd->xwin = ecore_evas_software_x11_8_window_get(sd->ee); + if (win->ee) win->xwin = ecore_evas_software_x11_8_window_get(win->ee); + } +/* killed + else if (ENGINE_COMPARE(ELM_XRENDER_X11)) + { + if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee); } + */ else if (ENGINE_COMPARE(ELM_OPENGL_X11)) { - if (sd->ee) sd->xwin = ecore_evas_gl_x11_window_get(sd->ee); + if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee); } else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32)) { - if (sd->ee) sd->xwin = (long)ecore_evas_win32_window_get(sd->ee); + if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee); } #undef ENGINE_COMPARE } - #endif #ifdef HAVE_ELEMENTARY_X static void -_elm_win_xwin_update(Elm_Win_Smart_Data *sd) +_elm_win_xwin_update(Elm_Win *win) { const char *s; - _elm_win_xwindow_get(sd); - if (sd->parent) + _elm_win_xwindow_get(win); + if (win->parent) { - ELM_WIN_DATA_GET(sd->parent, sdp); - if (sdp) + Elm_Win *win2; + + win2 = elm_widget_data_get(win->parent); + if (win2) { - if (sd->xwin) - ecore_x_icccm_transient_for_set(sd->xwin, sdp->xwin); + if (win->xwin) + ecore_x_icccm_transient_for_set(win->xwin, win2->xwin); } } - if (!sd->xwin) return; /* nothing more to do */ + if (!win->xwin) return; /* nothing more to do */ - s = sd->title; + s = win->title; if (!s) s = _elm_appname; if (!s) s = ""; - if (sd->icon_name) s = sd->icon_name; - ecore_x_icccm_icon_name_set(sd->xwin, s); - ecore_x_netwm_icon_name_set(sd->xwin, s); + if (win->icon_name) s = win->icon_name; + ecore_x_icccm_icon_name_set(win->xwin, s); + ecore_x_netwm_icon_name_set(win->xwin, s); - s = sd->role; - if (s) ecore_x_icccm_window_role_set(sd->xwin, s); + s = win->role; + if (s) ecore_x_icccm_window_role_set(win->xwin, s); // set window icon - if (sd->icon) + if (win->icon) { void *data; - data = evas_object_image_data_get(sd->icon, EINA_FALSE); + data = evas_object_image_data_get(win->icon, EINA_FALSE); if (data) { Ecore_X_Icon ic; @@ -1285,8 +977,8 @@ _elm_win_xwin_update(Elm_Win_Smart_Data *sd) unsigned char *p; unsigned int *p2; - evas_object_image_size_get(sd->icon, &w, &h); - stride = evas_object_image_stride_get(sd->icon); + evas_object_image_size_get(win->icon, &w, &h); + stride = evas_object_image_stride_get(win->icon); if ((w > 0) && (h > 0) && (stride >= (int)(w * sizeof(unsigned int)))) { @@ -1308,102 +1000,84 @@ _elm_win_xwin_update(Elm_Win_Smart_Data *sd) } p += (stride - (w * sizeof(unsigned int))); } - ecore_x_netwm_icons_set(sd->xwin, &ic, 1); + ecore_x_netwm_icons_set(win->xwin, &ic, 1); free(ic.data); } } - evas_object_image_data_set(sd->icon, data); + evas_object_image_data_set(win->icon, data); } } - switch (sd->type) + switch (win->type) { case ELM_WIN_BASIC: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_NORMAL); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NORMAL); + break; case ELM_WIN_DIALOG_BASIC: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_DIALOG); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DIALOG); + break; case ELM_WIN_DESKTOP: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_DESKTOP); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DESKTOP); + break; case ELM_WIN_DOCK: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_DOCK); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DOCK); + break; case ELM_WIN_TOOLBAR: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR); + break; case ELM_WIN_MENU: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_MENU); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_MENU); + break; case ELM_WIN_UTILITY: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_UTILITY); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_UTILITY); + break; case ELM_WIN_SPLASH: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_SPLASH); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_SPLASH); + break; case ELM_WIN_DROPDOWN_MENU: - ecore_x_netwm_window_type_set - (sd->xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU); + break; case ELM_WIN_POPUP_MENU: - ecore_x_netwm_window_type_set - (sd->xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU); + break; case ELM_WIN_TOOLTIP: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_TOOLTIP); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLTIP); + break; case ELM_WIN_NOTIFICATION: - ecore_x_netwm_window_type_set - (sd->xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION); + break; case ELM_WIN_COMBO: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_COMBO); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_COMBO); + break; case ELM_WIN_DND: - ecore_x_netwm_window_type_set(sd->xwin, ECORE_X_WINDOW_TYPE_DND); - break; - + ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DND); + break; default: - break; + break; } ecore_x_e_virtual_keyboard_state_set - (sd->xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode); - if (sd->indmode == ELM_WIN_INDICATOR_SHOW) + (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode); + if (win->indmode == ELM_WIN_INDICATOR_SHOW) ecore_x_e_illume_indicator_state_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON); - else if (sd->indmode == ELM_WIN_INDICATOR_HIDE) + (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON); + else if (win->indmode == ELM_WIN_INDICATOR_HIDE) ecore_x_e_illume_indicator_state_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF); + (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF); } - #endif static void -_elm_win_resize_objects_eval(Evas_Object *obj) +_elm_win_eval_subobjs(Evas_Object *obj) { const Eina_List *l; const Evas_Object *child; - ELM_WIN_DATA_GET(obj, sd); + Elm_Win *win = elm_widget_data_get(obj); Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1; int xx = 1, xy = 1; double wx, wy; - EINA_LIST_FOREACH (sd->resize_objs, l, child) + EINA_LIST_FOREACH(win->subobjs, l, child) { evas_object_size_hint_weight_get(child, &wx, &wy); if (wx == 0.0) xx = 0; @@ -1419,11 +1093,9 @@ _elm_win_resize_objects_eval(Evas_Object *obj) if (w < 1) w = -1; if (h < 1) h = -1; if (maxw == -1) maxw = w; - else if ((w > 0) && (w < maxw)) - maxw = w; + else if ((w > 0) && (w < maxw)) maxw = w; if (maxh == -1) maxh = h; - else if ((h > 0) && (h < maxh)) - maxh = h; + else if ((h > 0) && (h < maxh)) maxh = h; } if (!xx) maxw = minw; else maxw = 32767; @@ -1440,25 +1112,17 @@ _elm_win_resize_objects_eval(Evas_Object *obj) } static void -_elm_win_on_resize_obj_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - ELM_WIN_DATA_GET(data, sd); - - sd->resize_objs = eina_list_remove(sd->resize_objs, obj); - - _elm_win_resize_objects_eval(data); + Elm_Win *win = elm_widget_data_get(data); + win->subobjs = eina_list_remove(win->subobjs, obj); + _elm_win_eval_subobjs(win->win_obj); } static void -_elm_win_on_resize_obj_changed_size_hints(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) +_elm_win_subobj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - _elm_win_resize_objects_eval(data); + _elm_win_eval_subobjs(data); } void @@ -1469,20 +1133,19 @@ _elm_win_shutdown(void) } void -_elm_win_rescale(Elm_Theme *th, - Eina_Bool use_theme) +_elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme) { const Eina_List *l; Evas_Object *obj; if (!use_theme) { - EINA_LIST_FOREACH (_elm_win_list, l, obj) + EINA_LIST_FOREACH(_elm_win_list, l, obj) elm_widget_theme(obj); } else { - EINA_LIST_FOREACH (_elm_win_list, l, obj) + EINA_LIST_FOREACH(_elm_win_list, l, obj) elm_widget_theme_specific(obj, th, EINA_FALSE); } } @@ -1493,25 +1156,23 @@ _elm_win_translate(void) const Eina_List *l; Evas_Object *obj; - EINA_LIST_FOREACH (_elm_win_list, l, obj) - elm_widget_translate(obj); + EINA_LIST_FOREACH(_elm_win_list, l, obj) + elm_widget_translate(obj); } #ifdef HAVE_ELEMENTARY_X static Eina_Bool -_elm_win_client_message(void *data, - int type __UNUSED__, - void *event) +_elm_win_client_message(void *data, int type __UNUSED__, void *event) { - Elm_Win_Smart_Data *sd = data; + Elm_Win *win = data; Ecore_X_Event_Client_Message *e = event; if (e->format != 32) return ECORE_CALLBACK_PASS_ON; if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH) { - if ((unsigned)e->data.l[0] == sd->xwin) + if ((unsigned)e->data.l[0] == win->xwin) { - Evas *evas = evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj); + Evas *evas = evas_object_evas_get(win->win_obj); if (evas) { edje_file_cache_flush(); @@ -1523,9 +1184,9 @@ _elm_win_client_message(void *data, } else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP) { - if ((unsigned)e->data.l[0] == sd->xwin) + if ((unsigned)e->data.l[0] == win->xwin) { - Evas *evas = evas_object_evas_get(ELM_WIDGET_DATA(sd)->obj); + Evas *evas = evas_object_evas_get(win->win_obj); if (evas) { edje_file_cache_flush(); @@ -1538,183 +1199,470 @@ _elm_win_client_message(void *data, } return ECORE_CALLBACK_PASS_ON; } - #endif static void -_elm_win_focus_highlight_hide(void *data __UNUSED__, - Evas_Object *obj, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_elm_win_focus_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - evas_object_hide(obj); + Elm_Win *win = data; + + win->focus_highlight.geometry_changed = EINA_TRUE; + _elm_win_focus_highlight_reconfigure_job_start(win); } static void -_elm_win_focus_highlight_anim_end(void *data, - Evas_Object *obj, - const char *emission __UNUSED__, - const char *source __UNUSED__) +_elm_win_focus_target_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - Elm_Win_Smart_Data *sd = data; + Elm_Win *win = data; - _elm_win_focus_highlight_simple_setup(sd, obj); + win->focus_highlight.geometry_changed = EINA_TRUE; + _elm_win_focus_highlight_reconfigure_job_start(win); } static void -_elm_win_focus_highlight_init(Elm_Win_Smart_Data *sd) +_elm_win_focus_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { - evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, - _elm_win_object_focus_in, sd); - evas_event_callback_add(sd->evas, + Elm_Win *win = data; + + win->focus_highlight.cur.target = NULL; + + _elm_win_focus_highlight_reconfigure_job_start(win); +} + +static void +_elm_win_focus_target_callbacks_add(Elm_Win *win) +{ + Evas_Object *obj = win->focus_highlight.cur.target; + + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, + _elm_win_focus_target_move, win); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, + _elm_win_focus_target_resize, win); + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, + _elm_win_focus_target_del, win); +} + +static void +_elm_win_focus_target_callbacks_del(Elm_Win *win) +{ + Evas_Object *obj = win->focus_highlight.cur.target; + + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, + _elm_win_focus_target_move, win); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, + _elm_win_focus_target_resize, win); + evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL, + _elm_win_focus_target_del, win); +} + +static Evas_Object * +_elm_win_focus_target_get(Evas_Object *obj) +{ + Evas_Object *o = obj; + + do + { + if (elm_widget_is(o)) + { + if (!elm_widget_highlight_ignore_get(o)) + break; + o = elm_widget_parent_get(o); + if (!o) + o = evas_object_smart_parent_get(o); + } + else + { + o = elm_widget_parent_widget_get(o); + if (!o) + o = evas_object_smart_parent_get(o); + } + } + while (o); + + return o; +} + +static void +_elm_win_object_focus_in(void *data, Evas *e __UNUSED__, void *event_info) +{ + Evas_Object *obj = event_info, *target; + Elm_Win *win = data; + + if (win->focus_highlight.cur.target == obj) + return; + + target = _elm_win_focus_target_get(obj); + win->focus_highlight.cur.target = target; + if (elm_widget_highlight_in_theme_get(target)) + win->focus_highlight.cur.handled = EINA_TRUE; + else + _elm_win_focus_target_callbacks_add(win); + + _elm_win_focus_highlight_reconfigure_job_start(win); +} + +static void +_elm_win_object_focus_out(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__) +{ + Elm_Win *win = data; + + if (!win->focus_highlight.cur.target) + return; + + if (!win->focus_highlight.cur.handled) + _elm_win_focus_target_callbacks_del(win); + win->focus_highlight.cur.target = NULL; + win->focus_highlight.cur.handled = EINA_FALSE; + + _elm_win_focus_highlight_reconfigure_job_start(win); +} + +static void +_elm_win_focus_highlight_hide(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__) +{ + evas_object_hide(obj); +} + +static void +_elm_win_focus_highlight_init(Elm_Win *win) +{ + evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, + _elm_win_object_focus_in, win); + evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT, - _elm_win_object_focus_out, sd); + _elm_win_object_focus_out, win); - sd->focus_highlight.cur.target = evas_focus_get(sd->evas); + win->focus_highlight.cur.target = evas_focus_get(win->evas); - sd->focus_highlight.top = edje_object_add(sd->evas); - sd->focus_highlight.changed_theme = EINA_TRUE; - edje_object_signal_callback_add(sd->focus_highlight.top, + win->focus_highlight.top = edje_object_add(win->evas); + win->focus_highlight.changed_theme = EINA_TRUE; + edje_object_signal_callback_add(win->focus_highlight.top, "elm,action,focus,hide,end", "", _elm_win_focus_highlight_hide, NULL); - edje_object_signal_callback_add(sd->focus_highlight.top, + edje_object_signal_callback_add(win->focus_highlight.top, "elm,action,focus,anim,end", "", - _elm_win_focus_highlight_anim_end, sd); - _elm_win_focus_highlight_reconfigure_job_start(sd); + _elm_win_focus_highlight_anim_end, win); + _elm_win_focus_highlight_reconfigure_job_start(win); +} + +static void +_elm_win_focus_highlight_shutdown(Elm_Win *win) +{ + _elm_win_focus_highlight_reconfigure_job_stop(win); + if (win->focus_highlight.cur.target) + { + _elm_win_focus_target_callbacks_del(win); + win->focus_highlight.cur.target = NULL; + } + if (win->focus_highlight.top) + { + evas_object_del(win->focus_highlight.top); + win->focus_highlight.top = NULL; + } + + evas_event_callback_del_full(win->evas, + EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, + _elm_win_object_focus_in, win); + evas_event_callback_del_full(win->evas, + EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT, + _elm_win_object_focus_out, win); } static void -_elm_win_frame_cb_move_start(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *source __UNUSED__) +_elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible) { - Elm_Win_Smart_Data *sd; + Evas_Object *top; - if (!(sd = data)) return; - /* FIXME: Change mouse pointer */ + top = win->focus_highlight.top; + if (visible) + { + if (top) + { + evas_object_show(top); + edje_object_signal_emit(top, "elm,action,focus,show", "elm"); + } + } + else + { + if (top) + edje_object_signal_emit(top, "elm,action,focus,hide", "elm"); + } +} + +static void +_elm_win_focus_highlight_reconfigure_job(void *data) +{ + _elm_win_focus_highlight_reconfigure((Elm_Win *)data); +} + +static void +_elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win) +{ + if (win->focus_highlight.reconf_job) + ecore_job_del(win->focus_highlight.reconf_job); + win->focus_highlight.reconf_job = ecore_job_add( + _elm_win_focus_highlight_reconfigure_job, win); +} + +static void +_elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win) +{ + if (win->focus_highlight.reconf_job) + ecore_job_del(win->focus_highlight.reconf_job); + win->focus_highlight.reconf_job = NULL; +} + +static void +_elm_win_focus_highlight_simple_setup(Elm_Win *win, Evas_Object *obj) +{ + Evas_Object *clip, *target = win->focus_highlight.cur.target; + Evas_Coord x, y, w, h; + + clip = evas_object_clip_get(target); + evas_object_geometry_get(target, &x, &y, &w, &h); + + evas_object_move(obj, x, y); + evas_object_resize(obj, w, h); + evas_object_clip_set(obj, clip); +} + +static void +_elm_win_focus_highlight_anim_setup(Elm_Win *win, Evas_Object *obj) +{ + Evas_Coord tx, ty, tw, th; + Evas_Coord w, h, px, py, pw, ph; + Edje_Message_Int_Set *m; + Evas_Object *previous = win->focus_highlight.prev.target; + Evas_Object *target = win->focus_highlight.cur.target; - /* NB: Wayland handles moving surfaces by itself so we cannot - * specify a specific x/y we want. Instead, we will pass in the - * existing x/y values so they can be recorded as 'previous' - * position. The new position will get updated automatically when - * the move is finished */ + evas_object_geometry_get(win->win_obj, NULL, NULL, &w, &h); + evas_object_geometry_get(target, &tx, &ty, &tw, &th); + evas_object_geometry_get(previous, &px, &py, &pw, &ph); + evas_object_move(obj, 0, 0); + evas_object_resize(obj, tw, th); + evas_object_clip_unset(obj); - ecore_evas_wayland_move(sd->ee, sd->screen.x, sd->screen.y); + m = alloca(sizeof(*m) + (sizeof(int) * 8)); + m->count = 8; + m->val[0] = px; + m->val[1] = py; + m->val[2] = pw; + m->val[3] = ph; + m->val[4] = tx; + m->val[5] = ty; + m->val[6] = tw; + m->val[7] = th; + edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m); } static void -_elm_win_frame_cb_resize_start(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *source) +_elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__) { - Elm_Win_Smart_Data *sd; + Elm_Win *win = data; + _elm_win_focus_highlight_simple_setup(win, obj); +} + +static void +_elm_win_focus_highlight_reconfigure(Elm_Win *win) +{ + Evas_Object *target = win->focus_highlight.cur.target; + Evas_Object *previous = win->focus_highlight.prev.target; + Evas_Object *top = win->focus_highlight.top; + Eina_Bool visible_changed; + Eina_Bool common_visible; + const char *sig = NULL; - if (!(sd = data)) return; - if (sd->resizing) return; + _elm_win_focus_highlight_reconfigure_job_stop(win); - sd->resizing = EINA_TRUE; + visible_changed = (win->focus_highlight.cur.visible != + win->focus_highlight.prev.visible); + + if ((target == previous) && (!visible_changed) && + (!win->focus_highlight.geometry_changed)) + return; + + if ((previous) && (win->focus_highlight.prev.handled)) + elm_widget_signal_emit(previous, "elm,action,focus_highlight,hide", "elm"); + + if (!target) + common_visible = EINA_FALSE; + else if (win->focus_highlight.cur.handled) + { + common_visible = EINA_FALSE; + if (win->focus_highlight.cur.visible) + sig = "elm,action,focus_highlight,show"; + else + sig = "elm,action,focus_highlight,hide"; + } + else + common_visible = win->focus_highlight.cur.visible; + + _elm_win_focus_highlight_visible_set(win, common_visible); + if (sig) + elm_widget_signal_emit(target, sig, "elm"); + + if ((!target) || (!common_visible) || (win->focus_highlight.cur.handled)) + goto the_end; + + if (win->focus_highlight.changed_theme) + { + const char *str; + if (win->focus_highlight.style) + str = win->focus_highlight.style; + else + str = "default"; + _elm_theme_object_set(win->win_obj, top, "focus_highlight", "top", + str); + win->focus_highlight.changed_theme = EINA_FALSE; + + if (_elm_config->focus_highlight_animate) + { + str = edje_object_data_get(win->focus_highlight.top, "animate"); + win->focus_highlight.top_animate = ((str) && (!strcmp(str, "on"))); + } + } + + if ((win->focus_highlight.top_animate) && (previous) && + (!win->focus_highlight.prev.handled)) + _elm_win_focus_highlight_anim_setup(win, top); + else + _elm_win_focus_highlight_simple_setup(win, top); + evas_object_raise(top); + +the_end: + win->focus_highlight.geometry_changed = EINA_FALSE; + win->focus_highlight.prev = win->focus_highlight.cur; +} + +static void +_elm_win_frame_add(Elm_Win *win, const char *style) +{ + evas_output_framespace_set(win->evas, 0, 22, 0, 26); + + win->frame_obj = edje_object_add(win->evas); + _elm_theme_set(NULL, win->frame_obj, "border", "base", style); + evas_object_is_frame_object_set(win->frame_obj, EINA_TRUE); + evas_object_move(win->frame_obj, 0, 0); + evas_object_resize(win->frame_obj, 1, 1); + + edje_object_signal_callback_add(win->frame_obj, "elm,action,move,start", + "elm", _elm_win_frame_cb_move_start, win); + edje_object_signal_callback_add(win->frame_obj, "elm,action,resize,start", + "*", _elm_win_frame_cb_resize_start, win); + edje_object_signal_callback_add(win->frame_obj, "elm,action,minimize", + "elm", _elm_win_frame_cb_minimize, win); + edje_object_signal_callback_add(win->frame_obj, "elm,action,maximize", + "elm", _elm_win_frame_cb_maximize, win); + edje_object_signal_callback_add(win->frame_obj, "elm,action,close", + "elm", _elm_win_frame_cb_close, win); +} + +static void +_elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__) +{ + Elm_Win *win; + + if (!(win = data)) return; + /* FIXME: Change mouse pointer */ + + /* NB: Wayland handles moving surfaces by itself so we cannot + * specify a specific x/y we want. Instead, we will pass in the + * existing x/y values so they can be recorded as 'previous' position. + * The new position will get updated automatically when the move is + * finished */ + + ecore_evas_wayland_move(win->ee, win->screen.x, win->screen.y); +} + +static void +_elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source) +{ + Elm_Win *win; + + if (!(win = data)) return; + if (win->resizing) return; + win->resizing = EINA_TRUE; /* FIXME: Change mouse pointer */ if (!strcmp(source, "elm.event.resize.t")) - sd->resize_location = 1; + win->resize_location = 1; else if (!strcmp(source, "elm.event.resize.b")) - sd->resize_location = 2; + win->resize_location = 2; else if (!strcmp(source, "elm.event.resize.l")) - sd->resize_location = 4; + win->resize_location = 4; else if (!strcmp(source, "elm.event.resize.r")) - sd->resize_location = 8; + win->resize_location = 8; else if (!strcmp(source, "elm.event.resize.tl")) - sd->resize_location = 5; + win->resize_location = 5; else if (!strcmp(source, "elm.event.resize.tr")) - sd->resize_location = 9; + win->resize_location = 9; else if (!strcmp(source, "elm.event.resize.bl")) - sd->resize_location = 6; + win->resize_location = 6; else if (!strcmp(source, "elm.event.resize.br")) - sd->resize_location = 10; + win->resize_location = 10; else - sd->resize_location = 0; + win->resize_location = 0; - if (sd->resize_location > 0) - ecore_evas_wayland_resize(sd->ee, sd->resize_location); + if (win->resize_location > 0) + ecore_evas_wayland_resize(win->ee, win->resize_location); } static void -_elm_win_frame_cb_minimize(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *source __UNUSED__) +_elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__) { - Elm_Win_Smart_Data *sd; + Elm_Win *win; - if (!(sd = data)) return; - sd->iconified = EINA_TRUE; - ecore_evas_iconified_set(sd->ee, EINA_TRUE); + if (!(win = data)) return; + win->iconified = EINA_TRUE; + ecore_evas_iconified_set(win->ee, EINA_TRUE); } static void -_elm_win_frame_cb_maximize(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *source __UNUSED__) +_elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__) { - Elm_Win_Smart_Data *sd; + Elm_Win *win; - if (!(sd = data)) return; - if (sd->maximized) sd->maximized = EINA_FALSE; - else sd->maximized = EINA_TRUE; - ecore_evas_maximized_set(sd->ee, sd->maximized); + if (!(win = data)) return; + if (win->maximized) win->maximized = EINA_FALSE; + else win->maximized = EINA_TRUE; + ecore_evas_maximized_set(win->ee, win->maximized); } static void -_elm_win_frame_cb_close(void *data, - Evas_Object *obj __UNUSED__, - const char *sig __UNUSED__, - const char *source __UNUSED__) +_elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__) { - Elm_Win_Smart_Data *sd; + Elm_Win *win; - if (!(sd = data)) return; - evas_object_del(ELM_WIDGET_DATA(sd)->obj); + if (!(win = data)) return; + evas_object_del(win->win_obj); } +/* static void -_elm_win_frame_add(Elm_Win_Smart_Data *sd, - const char *style) +_elm_win_pointer_add(Elm_Win *win, const char *style) { - evas_output_framespace_set(sd->evas, 0, 22, 0, 26); + int mw, mh; + + return; + + win->pointer.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 32, 32, 0); + ecore_evas_resize(win->pointer.ee, 32, 32); - sd->frame_obj = edje_object_add(sd->evas); - elm_widget_theme_object_set - (ELM_WIDGET_DATA(sd)->obj, sd->frame_obj, "border", "base", style); - evas_object_is_frame_object_set(sd->frame_obj, EINA_TRUE); - evas_object_move(sd->frame_obj, 0, 0); - evas_object_resize(sd->frame_obj, 1, 1); + win->pointer.evas = ecore_evas_get(win->ee); - edje_object_signal_callback_add - (sd->frame_obj, "elm,action,move,start", "elm", - _elm_win_frame_cb_move_start, sd); - edje_object_signal_callback_add - (sd->frame_obj, "elm,action,resize,start", "*", - _elm_win_frame_cb_resize_start, sd); - edje_object_signal_callback_add - (sd->frame_obj, "elm,action,minimize", "elm", - _elm_win_frame_cb_minimize, sd); - edje_object_signal_callback_add - (sd->frame_obj, "elm,action,maximize", "elm", - _elm_win_frame_cb_maximize, sd); - edje_object_signal_callback_add - (sd->frame_obj, "elm,action,close", "elm", _elm_win_frame_cb_close, sd); + win->pointer.obj = edje_object_add(win->pointer.evas); + _elm_theme_set(NULL, win->pointer.obj, "pointer", "base", style); + edje_object_size_min_calc(win->pointer.obj, &mw, &mh); + evas_object_move(win->pointer.obj, 0, 0); + evas_object_resize(win->pointer.obj, 32, 32); + evas_object_show(win->pointer.obj); } +*/ #ifdef ELM_DEBUG static void -_debug_key_down(void *data __UNUSED__, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info) +_debug_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info) { Evas_Event_Key_Down *ev = event_info; @@ -1728,191 +1676,187 @@ _debug_key_down(void *data __UNUSED__, printf("Tree graph generated.\n"); elm_object_tree_dot_dump(obj, "./dump.dot"); } - #endif static void -_win_img_hide(void *data, - Evas *e __UNUSED__, +_win_img_hide(void *data, + Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) + void *event_info __UNUSED__) { - Elm_Win_Smart_Data *sd = data; + Elm_Win *win = data; - elm_widget_focus_hide_handle(ELM_WIDGET_DATA(sd)->obj); + elm_widget_focus_hide_handle(win->win_obj); } static void -_win_img_mouse_up(void *data, - Evas *e __UNUSED__, +_win_img_mouse_up(void *data, + Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, - void *event_info) + void *event_info) { - Elm_Win_Smart_Data *sd = data; + Elm_Win *win = data; Evas_Event_Mouse_Up *ev = event_info; if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)) - elm_widget_focus_mouse_up_handle(ELM_WIDGET_DATA(sd)->obj); + elm_widget_focus_mouse_up_handle(win->win_obj); } static void -_win_img_focus_in(void *data, - Evas *e __UNUSED__, +_win_img_focus_in(void *data, + Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) + void *event_info __UNUSED__) { - Elm_Win_Smart_Data *sd = data; - elm_widget_focus_steal(ELM_WIDGET_DATA(sd)->obj); + Elm_Win *win = data; + elm_widget_focus_steal(win->win_obj); } static void -_win_img_focus_out(void *data, - Evas *e __UNUSED__, +_win_img_focus_out(void *data, + Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) + void *event_info __UNUSED__) { - Elm_Win_Smart_Data *sd = data; - elm_widget_focused_object_clear(ELM_WIDGET_DATA(sd)->obj); + Elm_Win *win = data; + elm_widget_focused_object_clear(win->win_obj); } static void -_win_inlined_image_set(Elm_Win_Smart_Data *sd) +_win_inlined_image_set(Elm_Win *win) { - evas_object_image_alpha_set(sd->img_obj, EINA_FALSE); - evas_object_image_filled_set(sd->img_obj, EINA_TRUE); + evas_object_image_alpha_set(win->img_obj, EINA_FALSE); + evas_object_image_filled_set(win->img_obj, EINA_TRUE); + evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_DEL, + _elm_win_obj_callback_img_obj_del, win); - evas_object_event_callback_add - (sd->img_obj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, sd); - evas_object_event_callback_add - (sd->img_obj, EVAS_CALLBACK_HIDE, _win_img_hide, sd); - evas_object_event_callback_add - (sd->img_obj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, sd); - evas_object_event_callback_add - (sd->img_obj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, sd); - evas_object_event_callback_add - (sd->img_obj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, sd); + evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_HIDE, + _win_img_hide, win); + evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_MOUSE_UP, + _win_img_mouse_up, win); + evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_IN, + _win_img_focus_in, win); + evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_OUT, + _win_img_focus_out, win); } static void -_elm_win_on_icon_del(void *data, - Evas *e __UNUSED__, - Evas_Object *obj, - void *event_info __UNUSED__) +_subobj_del(Elm_Win *win, Evas_Object *obj, Evas_Object *subobj) { - Elm_Win_Smart_Data *sd = data; - - if (sd->icon == obj) sd->icon = NULL; + evas_object_event_callback_del_full(subobj, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _elm_win_subobj_callback_changed_size_hints, + obj); + evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL, + _elm_win_subobj_callback_del, obj); + win->subobjs = eina_list_remove(win->subobjs, subobj); + _elm_win_eval_subobjs(obj); } static void -_elm_win_smart_add(Evas_Object *obj) +_elm_win_obj_icon_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Win_Smart_Data); - - _elm_win_parent_sc->base.add(obj); - - elm_widget_can_focus_set(obj, EINA_TRUE); - - elm_widget_highlight_ignore_set(obj, EINA_TRUE); -} - -static void -_elm_win_smart_set_user(Elm_Widget_Smart_Class *sc) -{ - sc->base.add = _elm_win_smart_add; - sc->base.del = _elm_win_smart_del; - sc->base.show = _elm_win_smart_show; - sc->base.hide = _elm_win_smart_hide; - sc->base.move = _elm_win_smart_move; - sc->base.resize = _elm_win_smart_resize; - - sc->focus_next = _elm_win_smart_focus_next; - sc->on_focus = _elm_win_smart_on_focus; - sc->event = _elm_win_smart_event; + Elm_Win *win = data; + if (win->icon == obj) win->icon = NULL; } EAPI Evas_Object * -elm_win_add(Evas_Object *parent, - const char *name, - Elm_Win_Type type) +elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type) { - Evas *e; - Evas_Object *obj; + Elm_Win *win; const Eina_List *l; const char *fontpath; - Elm_Win_Smart_Data tmp_sd; + win = ELM_NEW(Elm_Win); - /* just to store some data while trying out to create a canvas */ - memset(&tmp_sd, 0, sizeof(Elm_Win_Smart_Data)); +#define FALLBACK_TRY(engine) \ + if (!win->ee) \ + do { \ + CRITICAL(engine " engine creation failed. Trying default."); \ + win->ee = ecore_evas_new(NULL, 0, 0, 1, 1, NULL); \ + if (win->ee) \ + elm_config_preferred_engine_set(ecore_evas_engine_name_get(win->ee)); \ + } while (0) +#define ENGINE_COMPARE(name) (_elm_preferred_engine && !strcmp(_elm_preferred_engine, name)) -#define FALLBACK_TRY(engine) \ - if (!tmp_sd.ee) \ - do { \ - CRITICAL(engine " engine creation failed. Trying default."); \ - tmp_sd.ee = ecore_evas_new(NULL, 0, 0, 1, 1, NULL); \ - if (tmp_sd.ee) \ - elm_config_preferred_engine_set \ - (ecore_evas_engine_name_get(tmp_sd.ee)); \ - } while (0) - -#define ENGINE_COMPARE(name) \ - (_elm_preferred_engine && !strcmp(_elm_preferred_engine, name)) + win->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN; + win->indmode = ELM_WIN_INDICATOR_UNKNOWN; switch (type) { case ELM_WIN_INLINED_IMAGE: if (!parent) break; { - e = evas_object_evas_get(parent); + Evas *e = evas_object_evas_get(parent); Ecore_Evas *ee; - if (!e) break; - ee = ecore_evas_ecore_evas_get(e); if (!ee) break; - - tmp_sd.img_obj = ecore_evas_object_image_new(ee); - if (!tmp_sd.img_obj) break; - - tmp_sd.ee = ecore_evas_object_ecore_evas_get(tmp_sd.img_obj); - if (!tmp_sd.ee) + win->img_obj = ecore_evas_object_image_new(ee); + if (!win->img_obj) break; + win->ee = ecore_evas_object_ecore_evas_get(win->img_obj); + if (win->ee) { - evas_object_del(tmp_sd.img_obj); - tmp_sd.img_obj = NULL; + _win_inlined_image_set(win); + break; } + evas_object_del(win->img_obj); + win->img_obj = NULL; } break; case ELM_WIN_SOCKET_IMAGE: - tmp_sd.ee = ecore_evas_extn_socket_new(1, 1); + win->ee = ecore_evas_extn_socket_new(1, 1); break; default: if (ENGINE_COMPARE(ELM_SOFTWARE_X11)) { - tmp_sd.ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1); + win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1); +#ifdef HAVE_ELEMENTARY_X + win->client_message_handler = ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win); +#endif FALLBACK_TRY("Sofware X11"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_FB)) { - tmp_sd.ee = ecore_evas_fb_new(NULL, 0, 1, 1); + win->ee = ecore_evas_fb_new(NULL, 0, 1, 1); FALLBACK_TRY("Sofware FB"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_DIRECTFB)) { - tmp_sd.ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1); + win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1); FALLBACK_TRY("Sofware DirectFB"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11)) { - tmp_sd.ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1); + win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1); FALLBACK_TRY("Sofware-16"); - } +#ifdef HAVE_ELEMENTARY_X + win->client_message_handler = ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win); +#endif + } else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11)) { - tmp_sd.ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1); + win->ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1); FALLBACK_TRY("Sofware-8"); +#ifdef HAVE_ELEMENTARY_X + win->client_message_handler = ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win); +#endif + } +/* killed + else if (ENGINE_COMPARE(ELM_XRENDER_X11)) + { + win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1); + FALLBACK_TRY("XRender"); +#ifdef HAVE_ELEMENTARY_X + win->client_message_handler = ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win); +#endif } + */ else if (ENGINE_COMPARE(ELM_OPENGL_X11)) { int opt[10]; @@ -1926,232 +1870,207 @@ elm_win_add(Evas_Object *parent, opt_i++; } if (opt_i > 0) - tmp_sd.ee = ecore_evas_gl_x11_options_new - (NULL, 0, 0, 0, 1, 1, opt); + win->ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt); else - tmp_sd.ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1); + win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1); FALLBACK_TRY("OpenGL"); +#ifdef HAVE_ELEMENTARY_X + win->client_message_handler = ecore_event_handler_add + (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win); +#endif } else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32)) { - tmp_sd.ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1); + win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1); FALLBACK_TRY("Sofware Win32"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE)) { - tmp_sd.ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1); + win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1); FALLBACK_TRY("Sofware-16-WinCE"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_PSL1GHT)) { - tmp_sd.ee = ecore_evas_psl1ght_new(NULL, 1, 1); + win->ee = ecore_evas_psl1ght_new(NULL, 1, 1); FALLBACK_TRY("PSL1GHT"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_SDL)) { - tmp_sd.ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1); + win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1); FALLBACK_TRY("Sofware SDL"); } else if (ENGINE_COMPARE(ELM_SOFTWARE_16_SDL)) { - tmp_sd.ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1); + win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1); FALLBACK_TRY("Sofware-16-SDL"); } else if (ENGINE_COMPARE(ELM_OPENGL_SDL)) { - tmp_sd.ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0); + win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0); FALLBACK_TRY("OpenGL SDL"); } else if (ENGINE_COMPARE(ELM_OPENGL_COCOA)) { - tmp_sd.ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0); + win->ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0); FALLBACK_TRY("OpenGL Cocoa"); } else if (ENGINE_COMPARE(ELM_BUFFER)) { - tmp_sd.ee = ecore_evas_buffer_new(1, 1); + win->ee = ecore_evas_buffer_new(1, 1); } else if (ENGINE_COMPARE(ELM_EWS)) { - tmp_sd.ee = ecore_evas_ews_new(0, 0, 1, 1); + win->ee = ecore_evas_ews_new(0, 0, 1, 1); } else if (ENGINE_COMPARE(ELM_WAYLAND_SHM)) { - tmp_sd.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 1, 1, 0); + win->ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 1, 1, 0); + win->evas = ecore_evas_get(win->ee); + + _elm_win_frame_add(win, "default"); +// _elm_win_pointer_add(win, "default"); } else if (ENGINE_COMPARE(ELM_WAYLAND_EGL)) { - tmp_sd.ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 1, 1, 0); + win->ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 1, 1, 0); + win->evas = ecore_evas_get(win->ee); + + _elm_win_frame_add(win, "default"); +// _elm_win_pointer_add(win, "default"); } else if (!strncmp(_elm_preferred_engine, "shot:", 5)) { - tmp_sd.ee = ecore_evas_buffer_new(1, 1); - ecore_evas_manual_render_set(tmp_sd.ee, EINA_TRUE); - tmp_sd.shot.info = eina_stringshare_add - (_elm_preferred_engine + 5); + win->ee = ecore_evas_buffer_new(1, 1); + ecore_evas_manual_render_set(win->ee, EINA_TRUE); + win->shot.info = eina_stringshare_add(_elm_preferred_engine + 5); + _shot_init(win); } #undef FALLBACK_TRY break; } - if (!tmp_sd.ee) + if (!win->ee) { ERR("Cannot create window."); + free(win); return NULL; } - - obj = evas_object_smart_add - (ecore_evas_get(tmp_sd.ee), _elm_win_smart_class_new()); - - ELM_WIN_DATA_GET(obj, sd); - - /* copying possibly altered fields back */ -#define SD_CPY(_field) \ - do \ - { \ - sd->_field = tmp_sd._field; \ - } while (0) - - SD_CPY(ee); - SD_CPY(img_obj); - SD_CPY(shot.info); -#undef SD_CPY - - /* complementary actions, which depend on final smart data - * pointer */ - if (type == ELM_WIN_INLINED_IMAGE) - _win_inlined_image_set(sd); - -#ifdef HAVE_ELEMENTARY_X - else if (ENGINE_COMPARE(ELM_SOFTWARE_X11)) - sd->client_message_handler = ecore_event_handler_add - (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, sd); - else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11)) - sd->client_message_handler = ecore_event_handler_add - (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, sd); - else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11)) - sd->client_message_handler = ecore_event_handler_add - (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, sd); - else if (ENGINE_COMPARE(ELM_OPENGL_X11)) - sd->client_message_handler = ecore_event_handler_add - (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, sd); -#endif - - else if (ENGINE_COMPARE(ELM_WAYLAND_SHM)) - _elm_win_frame_add(sd, "default"); - else if (ENGINE_COMPARE(ELM_WAYLAND_EGL)) - _elm_win_frame_add(sd, "default"); - else if (!strncmp(_elm_preferred_engine, "shot:", 5)) - _shot_init(sd); - - sd->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN; - sd->indmode = ELM_WIN_INDICATOR_UNKNOWN; - #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); + _elm_win_xwindow_get(win); #endif - if ((_elm_config->bgpixmap) && (!_elm_config->compositing)) - ecore_evas_avoid_damage_set(sd->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE); + ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE); // bg pixmap done by x - has other issues like can be redrawn by x before it // is filled/ready by app - // ecore_evas_avoid_damage_set(sd->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN); - - sd->type = type; - sd->parent = parent; - - if (sd->parent) - evas_object_event_callback_add - (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, sd); - - sd->evas = ecore_evas_get(sd->ee); - - evas_object_color_set(obj, 0, 0, 0, 0); - evas_object_move(obj, 0, 0); - evas_object_resize(obj, 1, 1); - evas_object_layer_set(obj, 50); - evas_object_pass_events_set(obj, EINA_TRUE); - - if (sd->frame_obj) - { - evas_object_clip_set(obj, sd->frame_obj); - evas_object_stack_below(sd->frame_obj, obj); + // ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN); + + win->type = type; + win->parent = parent; + if (win->parent) + evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL, + _elm_win_obj_callback_parent_del, win); + + win->evas = ecore_evas_get(win->ee); + win->win_obj = elm_widget_add(win->evas); + elm_widget_type_set(win->win_obj, "win"); + ELM_SET_WIDTYPE(widtype, "win"); + elm_widget_data_set(win->win_obj, win); + elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb); + elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL); + elm_widget_can_focus_set(win->win_obj, EINA_TRUE); + elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE); + elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook); + evas_object_color_set(win->win_obj, 0, 0, 0, 0); + evas_object_move(win->win_obj, 0, 0); + evas_object_resize(win->win_obj, 1, 1); + evas_object_layer_set(win->win_obj, 50); + evas_object_pass_events_set(win->win_obj, EINA_TRUE); + + if (win->frame_obj) + { + evas_object_clip_set(win->win_obj, win->frame_obj); + evas_object_stack_below(win->frame_obj, win->win_obj); } if (type == ELM_WIN_INLINED_IMAGE) - elm_widget_parent2_set(obj, parent); - - ecore_evas_object_associate - (sd->ee, obj, ECORE_EVAS_OBJECT_ASSOCIATE_BASE | - ECORE_EVAS_OBJECT_ASSOCIATE_STACK | ECORE_EVAS_OBJECT_ASSOCIATE_LAYER); - - if (sd->img_obj) - evas_object_intercept_move_callback_add - (obj, _elm_win_obj_intercept_move, sd); - - evas_object_intercept_show_callback_add - (obj, _elm_win_obj_intercept_show, sd); - - ecore_evas_name_class_set(sd->ee, name, _elm_appname); - ecore_evas_callback_delete_request_set(sd->ee, _elm_win_delete_request); - ecore_evas_callback_resize_set(sd->ee, _elm_win_resize); - ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in); - ecore_evas_callback_focus_in_set(sd->ee, _elm_win_focus_in); - ecore_evas_callback_focus_out_set(sd->ee, _elm_win_focus_out); - ecore_evas_callback_move_set(sd->ee, _elm_win_move); - ecore_evas_callback_state_change_set(sd->ee, _elm_win_state_change); - - evas_image_cache_set(sd->evas, (_elm_config->image_cache * 1024)); - evas_font_cache_set(sd->evas, (_elm_config->font_cache * 1024)); - - EINA_LIST_FOREACH (_elm_config->font_dirs, l, fontpath) - evas_font_path_append(sd->evas, fontpath); - + elm_widget_parent2_set(win->win_obj, parent); + ecore_evas_object_associate(win->ee, win->win_obj, + ECORE_EVAS_OBJECT_ASSOCIATE_BASE | + ECORE_EVAS_OBJECT_ASSOCIATE_STACK | + ECORE_EVAS_OBJECT_ASSOCIATE_LAYER); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW, + _elm_win_obj_callback_show, win); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_HIDE, + _elm_win_obj_callback_hide, win); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL, + _elm_win_obj_callback_del, win); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_MOVE, + _elm_win_obj_callback_move, win); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_RESIZE, + _elm_win_obj_callback_resize, win); + if (win->img_obj) + evas_object_intercept_move_callback_add(win->win_obj, + _elm_win_obj_intercept_move, win); + evas_object_intercept_show_callback_add(win->win_obj, + _elm_win_obj_intercept_show, win); + + evas_object_smart_callback_add(win->win_obj, "sub-object-del", (Evas_Smart_Cb)_subobj_del, win); + ecore_evas_name_class_set(win->ee, name, _elm_appname); + ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request); + ecore_evas_callback_resize_set(win->ee, _elm_win_resize); + ecore_evas_callback_mouse_in_set(win->ee, _elm_win_mouse_in); + ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in); + ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out); + ecore_evas_callback_move_set(win->ee, _elm_win_move); + ecore_evas_callback_state_change_set(win->ee, _elm_win_state_change); + evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024)); + evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024)); + EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath) + evas_font_path_append(win->evas, fontpath); if (!_elm_config->font_hinting) - evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_NONE); + evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE); else if (_elm_config->font_hinting == 1) - evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_AUTO); + evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO); else if (_elm_config->font_hinting == 2) - evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_BYTECODE); + evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif - _elm_win_list = eina_list_append(_elm_win_list, obj); + _elm_win_list = eina_list_append(_elm_win_list, win->win_obj); if (ENGINE_COMPARE(ELM_SOFTWARE_FB)) { - ecore_evas_fullscreen_set(sd->ee, 1); + ecore_evas_fullscreen_set(win->ee, 1); } #undef ENGINE_COMPARE if (_elm_config->focus_highlight_enable) - elm_win_focus_highlight_enabled_set(obj, EINA_TRUE); + elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE); #ifdef ELM_DEBUG - Evas_Modifier_Mask mask = evas_key_modifier_mask_get(sd->evas, "Control"); - evas_object_event_callback_add - (obj, EVAS_CALLBACK_KEY_DOWN, _debug_key_down, sd); + Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control"); + evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN, + _debug_key_down, win); - if (evas_object_key_grab(obj, "F12", mask, 0, EINA_TRUE)) - INF("Ctrl+F12 key combination exclusive for dot tree generation\n"); - else - ERR("failed to grab F12 key to elm widgets (dot) tree generation"); + Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0, + EINA_TRUE); + printf("Ctrl+F12 key combination exclusive for dot tree generation\n"); #endif - return obj; + evas_object_smart_callbacks_descriptions_set(win->win_obj, _signals); + + return win->win_obj; } EAPI Evas_Object * -elm_win_util_standard_add(const char *name, - const char *title) +elm_win_util_standard_add(const char *name, const char *title) { Evas_Object *win, *bg; win = elm_win_add(NULL, name, ELM_WIN_BASIC); if (!win) return NULL; - elm_win_title_set(win, title); bg = elm_bg_add(win); if (!bg) @@ -2162,356 +2081,349 @@ elm_win_util_standard_add(const char *name, evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(win, bg); evas_object_show(bg); - return win; } EAPI void -elm_win_resize_object_add(Evas_Object *obj, - Evas_Object *subobj) +elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj) { Evas_Coord w, h; - - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (eina_list_data_find(sd->resize_objs, subobj)) return; - - if (!ELM_WIDGET_DATA(sd)->api->sub_object_add(obj, subobj)) - ERR("could not add %p as sub object of %p", subobj, obj); - - sd->resize_objs = eina_list_append(sd->resize_objs, subobj); - - evas_object_event_callback_add - (subobj, EVAS_CALLBACK_DEL, _elm_win_on_resize_obj_del, obj); - evas_object_event_callback_add - (subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _elm_win_on_resize_obj_changed_size_hints, obj); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (eina_list_data_find(win->subobjs, subobj)) return; + win->subobjs = eina_list_append(win->subobjs, subobj); + elm_widget_sub_object_add(obj, subobj); + evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL, + _elm_win_subobj_callback_del, obj); + evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _elm_win_subobj_callback_changed_size_hints, + obj); evas_object_geometry_get(obj, NULL, NULL, &w, &h); evas_object_move(subobj, 0, 0); evas_object_resize(subobj, w, h); - - _elm_win_resize_objects_eval(obj); + _elm_win_eval_subobjs(obj); } EAPI void -elm_win_resize_object_del(Evas_Object *obj, - Evas_Object *subobj) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (!ELM_WIDGET_DATA(sd)->api->sub_object_del(obj, subobj)) - ERR("could not remove sub object %p from %p", subobj, obj); - - sd->resize_objs = eina_list_remove(sd->resize_objs, subobj); - - evas_object_event_callback_del_full - (subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _elm_win_on_resize_obj_changed_size_hints, obj); - evas_object_event_callback_del_full - (subobj, EVAS_CALLBACK_DEL, _elm_win_on_resize_obj_del, obj); - - _elm_win_resize_objects_eval(obj); +elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + evas_object_event_callback_del_full(subobj, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _elm_win_subobj_callback_changed_size_hints, + obj); + evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL, + _elm_win_subobj_callback_del, obj); + win->subobjs = eina_list_remove(win->subobjs, subobj); + elm_widget_sub_object_del(obj, subobj); + _elm_win_eval_subobjs(obj); } EAPI void -elm_win_title_set(Evas_Object *obj, - const char *title) +elm_win_title_set(Evas_Object *obj, const char *title) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (!title) return; - eina_stringshare_replace(&(sd->title), title); - ecore_evas_title_set(sd->ee, sd->title); - if (sd->frame_obj) - edje_object_part_text_escaped_set - (sd->frame_obj, "elm.text.title", sd->title); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win || !title) return; + eina_stringshare_replace(&(win->title), title); + ecore_evas_title_set(win->ee, win->title); + if (win->frame_obj) + edje_object_part_text_escaped_set(win->frame_obj, "elm.text.title", win->title); } EAPI const char * elm_win_title_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->title; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + return win->title; } EAPI void -elm_win_icon_name_set(Evas_Object *obj, - const char *icon_name) +elm_win_icon_name_set(Evas_Object *obj, const char *icon_name) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (!icon_name) return; - eina_stringshare_replace(&(sd->icon_name), icon_name); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win || !icon_name) return; + eina_stringshare_replace(&(win->icon_name), icon_name); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI const char * elm_win_icon_name_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->icon_name; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + return win->icon_name; } EAPI void elm_win_role_set(Evas_Object *obj, const char *role) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (!role) return; - eina_stringshare_replace(&(sd->role), role); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win || !role) return; + eina_stringshare_replace(&(win->role), role); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI const char * elm_win_role_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->role; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + return win->role; } EAPI void -elm_win_icon_object_set(Evas_Object *obj, - Evas_Object *icon) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->icon) - evas_object_event_callback_del_full - (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, sd); - sd->icon = icon; - if (sd->icon) - evas_object_event_callback_add - (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, sd); +elm_win_icon_object_set(Evas_Object *obj, Evas_Object *icon) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (win->icon) + evas_object_event_callback_del_full(win->icon, EVAS_CALLBACK_DEL, + _elm_win_obj_icon_callback_del, win); + win->icon = icon; + if (win->icon) + evas_object_event_callback_add(win->icon, EVAS_CALLBACK_DEL, + _elm_win_obj_icon_callback_del, win); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI const Evas_Object * elm_win_icon_object_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->icon; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + return win->icon; } EAPI void -elm_win_autodel_set(Evas_Object *obj, - Eina_Bool autodel) +elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->autodel = autodel; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->autodel = autodel; } EAPI Eina_Bool elm_win_autodel_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->autodel; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->autodel; } EAPI void elm_win_activate(Evas_Object *obj) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_activate(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_activate(win->ee); } EAPI void elm_win_lower(Evas_Object *obj) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_lower(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_lower(win->ee); } EAPI void elm_win_raise(Evas_Object *obj) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_raise(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_raise(win->ee); } EAPI void -elm_win_center(Evas_Object *obj, - Eina_Bool h, - Eina_Bool v) +elm_win_center(Evas_Object *obj, Eina_Bool h, Eina_Bool v) { + Elm_Win *win; int win_w, win_h, screen_w, screen_h, nx, ny; - - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &screen_w, &screen_h); + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &screen_w, &screen_h); if ((!screen_w) || (!screen_h)) return; - evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h); if ((!win_w) || (!win_h)) return; - if (h) nx = win_w >= screen_w ? 0 : (screen_w / 2) - (win_w / 2); - else nx = sd->screen.x; + else nx = win->screen.x; if (v) ny = win_h >= screen_h ? 0 : (screen_h / 2) - (win_h / 2); - else ny = sd->screen.y; + else ny = win->screen.y; if (nx < 0) nx = 0; if (ny < 0) ny = 0; - evas_object_move(obj, nx, ny); } EAPI void -elm_win_borderless_set(Evas_Object *obj, - Eina_Bool borderless) +elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_borderless_set(sd->ee, borderless); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_borderless_set(win->ee, borderless); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_borderless_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ecore_evas_borderless_get(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return ecore_evas_borderless_get(win->ee); } EAPI void -elm_win_shaped_set(Evas_Object *obj, - Eina_Bool shaped) +elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_shaped_set(sd->ee, shaped); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_shaped_set(win->ee, shaped); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_shaped_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ecore_evas_shaped_get(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return ecore_evas_shaped_get(win->ee); } EAPI void -elm_win_alpha_set(Evas_Object *obj, - Eina_Bool alpha) +elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->frame_obj) + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (win->frame_obj) { } - else if (sd->img_obj) + else if (win->img_obj) { - evas_object_image_alpha_set(sd->img_obj, alpha); - ecore_evas_alpha_set(sd->ee, alpha); + evas_object_image_alpha_set(win->img_obj, alpha); + ecore_evas_alpha_set(win->ee, alpha); } else { #ifdef HAVE_ELEMENTARY_X - if (sd->xwin) + if (win->xwin) { if (alpha) { if (!_elm_config->compositing) - elm_win_shaped_set(obj, alpha); + elm_win_shaped_set(obj, alpha); else - ecore_evas_alpha_set(sd->ee, alpha); + ecore_evas_alpha_set(win->ee, alpha); } else - ecore_evas_alpha_set(sd->ee, alpha); - _elm_win_xwin_update(sd); + ecore_evas_alpha_set(win->ee, alpha); + _elm_win_xwin_update(win); } else #endif - ecore_evas_alpha_set(sd->ee, alpha); + ecore_evas_alpha_set(win->ee, alpha); } } EAPI Eina_Bool elm_win_alpha_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - if (sd->frame_obj) + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + if (win->frame_obj) { } - else if (sd->img_obj) + else if (win->img_obj) { - return evas_object_image_alpha_get(sd->img_obj); + return evas_object_image_alpha_get(win->img_obj); } - - return ecore_evas_alpha_get(sd->ee); + return ecore_evas_alpha_get(win->ee); } EAPI void -elm_win_override_set(Evas_Object *obj, - Eina_Bool override) +elm_win_override_set(Evas_Object *obj, Eina_Bool override) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_override_set(sd->ee, override); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_override_set(win->ee, override); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_override_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ecore_evas_override_get(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return ecore_evas_override_get(win->ee); } EAPI void -elm_win_fullscreen_set(Evas_Object *obj, - Eina_Bool fullscreen) +elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - // YYY: handle if sd->img_obj + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + // YYY: handle if win->img_obj #define ENGINE_COMPARE(name) (!strcmp(_elm_preferred_engine, name)) if (ENGINE_COMPARE(ELM_SOFTWARE_FB) || ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE)) @@ -2521,10 +2433,10 @@ elm_win_fullscreen_set(Evas_Object *obj, } else { - sd->fullscreen = fullscreen; - ecore_evas_fullscreen_set(sd->ee, fullscreen); + win->fullscreen = fullscreen; + ecore_evas_fullscreen_set(win->ee, fullscreen); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } #undef ENGINE_COMPARE @@ -2533,9 +2445,10 @@ elm_win_fullscreen_set(Evas_Object *obj, EAPI Eina_Bool elm_win_fullscreen_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; #define ENGINE_COMPARE(name) (!strcmp(_elm_preferred_engine, name)) if (ENGINE_COMPARE(ELM_SOFTWARE_FB) || ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE)) @@ -2545,343 +2458,354 @@ elm_win_fullscreen_get(const Evas_Object *obj) } else { - return sd->fullscreen; + return win->fullscreen; } #undef ENGINE_COMPARE } EAPI void -elm_win_maximized_set(Evas_Object *obj, - Eina_Bool maximized) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->maximized = maximized; - // YYY: handle if sd->img_obj - ecore_evas_maximized_set(sd->ee, maximized); +elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->maximized = maximized; + // YYY: handle if win->img_obj + ecore_evas_maximized_set(win->ee, maximized); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_maximized_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->maximized; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->maximized; } EAPI void -elm_win_iconified_set(Evas_Object *obj, - Eina_Bool iconified) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->iconified = iconified; - ecore_evas_iconified_set(sd->ee, iconified); +elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->iconified = iconified; + ecore_evas_iconified_set(win->ee, iconified); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_iconified_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->iconified; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->iconified; } EAPI void -elm_win_withdrawn_set(Evas_Object *obj, - Eina_Bool withdrawn) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->withdrawn = withdrawn; - ecore_evas_withdrawn_set(sd->ee, withdrawn); +elm_win_withdrawn_set(Evas_Object *obj, Eina_Bool withdrawn) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->withdrawn = withdrawn; + ecore_evas_withdrawn_set(win->ee, withdrawn); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_withdrawn_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->withdrawn; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->withdrawn; } EAPI void -elm_win_urgent_set(Evas_Object *obj, - Eina_Bool urgent) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->urgent = urgent; - ecore_evas_urgent_set(sd->ee, urgent); +elm_win_urgent_set(Evas_Object *obj, Eina_Bool urgent) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->urgent = urgent; + ecore_evas_urgent_set(win->ee, urgent); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_urgent_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->urgent; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->urgent; } EAPI void -elm_win_demand_attention_set(Evas_Object *obj, - Eina_Bool demand_attention) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->demand_attention = demand_attention; - ecore_evas_demand_attention_set(sd->ee, demand_attention); +elm_win_demand_attention_set(Evas_Object *obj, Eina_Bool demand_attention) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->demand_attention = demand_attention; + ecore_evas_demand_attention_set(win->ee, demand_attention); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_demand_attention_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->demand_attention; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->demand_attention; } EAPI void -elm_win_modal_set(Evas_Object *obj, - Eina_Bool modal) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->modal = modal; - ecore_evas_modal_set(sd->ee, modal); +elm_win_modal_set(Evas_Object *obj, Eina_Bool modal) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->modal = modal; + ecore_evas_modal_set(win->ee, modal); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_modal_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->modal; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->modal; } EAPI void -elm_win_aspect_set(Evas_Object *obj, - double aspect) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->aspect = aspect; - ecore_evas_aspect_set(sd->ee, aspect); +elm_win_aspect_set(Evas_Object *obj, double aspect) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->aspect = aspect; + ecore_evas_aspect_set(win->ee, aspect); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI double elm_win_aspect_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->aspect; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->aspect; } EAPI void -elm_win_layer_set(Evas_Object *obj, - int layer) +elm_win_layer_set(Evas_Object *obj, int layer) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_layer_set(sd->ee, layer); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_layer_set(win->ee, layer); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI int elm_win_layer_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) - 1; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1); - - return ecore_evas_layer_get(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + win = elm_widget_data_get(obj); + if (!win) return -1; + return ecore_evas_layer_get(win->ee); } EAPI void -elm_win_rotation_set(Evas_Object *obj, - int rotation) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->rot == rotation) return; - sd->rot = rotation; - ecore_evas_rotation_set(sd->ee, rotation); +elm_win_rotation_set(Evas_Object *obj, int rotation) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (win->rot == rotation) return; + win->rot = rotation; + ecore_evas_rotation_set(win->ee, rotation); evas_object_size_hint_min_set(obj, -1, -1); evas_object_size_hint_max_set(obj, -1, -1); - _elm_win_resize_objects_eval(obj); + _elm_win_eval_subobjs(obj); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI void -elm_win_rotation_with_resize_set(Evas_Object *obj, - int rotation) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (sd->rot == rotation) return; - sd->rot = rotation; - ecore_evas_rotation_with_resize_set(sd->ee, rotation); +elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (win->rot == rotation) return; + win->rot = rotation; + ecore_evas_rotation_with_resize_set(win->ee, rotation); evas_object_size_hint_min_set(obj, -1, -1); evas_object_size_hint_max_set(obj, -1, -1); - _elm_win_resize_objects_eval(obj); - + _elm_win_eval_subobjs(obj); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI int elm_win_rotation_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) - 1; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1); - - return sd->rot; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + win = elm_widget_data_get(obj); + if (!win) return -1; + return win->rot; } EAPI void -elm_win_sticky_set(Evas_Object *obj, - Eina_Bool sticky) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->sticky = sticky; - ecore_evas_sticky_set(sd->ee, sticky); +elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->sticky = sticky; + ecore_evas_sticky_set(win->ee, sticky); #ifdef HAVE_ELEMENTARY_X - _elm_win_xwin_update(sd); + _elm_win_xwin_update(win); #endif } EAPI Eina_Bool elm_win_sticky_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->sticky; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->sticky; } EAPI void -elm_win_keyboard_mode_set(Evas_Object *obj, - Elm_Win_Keyboard_Mode mode) +elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (mode == sd->kbdmode) return; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (mode == win->kbdmode) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); + _elm_win_xwindow_get(win); #endif - sd->kbdmode = mode; + win->kbdmode = mode; #ifdef HAVE_ELEMENTARY_X - if (sd->xwin) + if (win->xwin) ecore_x_e_virtual_keyboard_state_set - (sd->xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode); + (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode); #endif } EAPI Elm_Win_Keyboard_Mode elm_win_keyboard_mode_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) ELM_WIN_KEYBOARD_UNKNOWN; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_WIN_KEYBOARD_UNKNOWN); - - return sd->kbdmode; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN; + win = elm_widget_data_get(obj); + if (!win) return ELM_WIN_KEYBOARD_UNKNOWN; + return win->kbdmode; } EAPI void -elm_win_keyboard_win_set(Evas_Object *obj, - Eina_Bool is_keyboard) +elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - ecore_x_e_virtual_keyboard_set(sd->xwin, is_keyboard); + _elm_win_xwindow_get(win); + if (win->xwin) + ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard); #else - (void)is_keyboard; + (void) is_keyboard; #endif } EAPI Eina_Bool elm_win_keyboard_win_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_virtual_keyboard_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_virtual_keyboard_get(win->xwin); #endif return EINA_FALSE; } EAPI void -elm_win_indicator_mode_set(Evas_Object *obj, - Elm_Win_Indicator_Mode mode) +elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (mode == sd->indmode) return; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (mode == win->indmode) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); + _elm_win_xwindow_get(win); #endif - sd->indmode = mode; + win->indmode = mode; #ifdef HAVE_ELEMENTARY_X - if (sd->xwin) + if (win->xwin) { - if (sd->indmode == ELM_WIN_INDICATOR_SHOW) + if (win->indmode == ELM_WIN_INDICATOR_SHOW) ecore_x_e_illume_indicator_state_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON); - else if (sd->indmode == ELM_WIN_INDICATOR_HIDE) + (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON); + else if (win->indmode == ELM_WIN_INDICATOR_HIDE) ecore_x_e_illume_indicator_state_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF); + (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF); } #endif } @@ -2889,34 +2813,36 @@ elm_win_indicator_mode_set(Evas_Object *obj, EAPI Elm_Win_Indicator_Mode elm_win_indicator_mode_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) ELM_WIN_INDICATOR_UNKNOWN; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_WIN_INDICATOR_UNKNOWN); - - return sd->indmode; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_INDICATOR_UNKNOWN; + win = elm_widget_data_get(obj); + if (!win) return ELM_WIN_INDICATOR_UNKNOWN; + return win->indmode; } EAPI void -elm_win_indicator_opacity_set(Evas_Object *obj, - Elm_Win_Indicator_Opacity_Mode mode) -{ - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (mode == sd->ind_o_mode) return; - sd->ind_o_mode = mode; +elm_win_indicator_opacity_set(Evas_Object *obj, Elm_Win_Indicator_Opacity_Mode mode) +{ + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (mode == win->ind_o_mode) return; + win->ind_o_mode = mode; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) + _elm_win_xwindow_get(win); + if (win->xwin) { - if (sd->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE) + if (win->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE) ecore_x_e_illume_indicator_opacity_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE); - else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT) + (win->xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE); + else if (win->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT) ecore_x_e_illume_indicator_opacity_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT); - else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT) + (win->xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT); + else if (win->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT) ecore_x_e_illume_indicator_opacity_set - (sd->xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); + (win->xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); + } #endif } @@ -2924,454 +2850,388 @@ elm_win_indicator_opacity_set(Evas_Object *obj, EAPI Elm_Win_Indicator_Opacity_Mode elm_win_indicator_opacity_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) ELM_WIN_INDICATOR_OPACITY_UNKNOWN; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, ELM_WIN_INDICATOR_OPACITY_UNKNOWN); - - return sd->ind_o_mode; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_INDICATOR_OPACITY_UNKNOWN; + win = elm_widget_data_get(obj); + if (!win) return ELM_WIN_INDICATOR_OPACITY_UNKNOWN; + return win->ind_o_mode; } EAPI void -elm_win_screen_position_get(const Evas_Object *obj, - int *x, - int *y) +elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - if (x) *x = sd->screen.x; - if (y) *y = sd->screen.y; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + if (x) *x = win->screen.x; + if (y) *y = win->screen.y; } EAPI Eina_Bool elm_win_focus_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return ecore_evas_focus_get(sd->ee); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return ecore_evas_focus_get(win->ee); } EAPI void -elm_win_screen_constrain_set(Evas_Object *obj, - Eina_Bool constrain) +elm_win_screen_constrain_set(Evas_Object *obj, Eina_Bool constrain) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->constrain = !!constrain; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->constrain = !!constrain; } EAPI Eina_Bool elm_win_screen_constrain_get(Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - return sd->constrain; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + return win->constrain; } EAPI void -elm_win_screen_size_get(const Evas_Object *obj, - int *x, - int *y, - int *w, - int *h) +elm_win_screen_size_get(const Evas_Object *obj, int *x, int *y, int *w, int *h) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - ecore_evas_screen_geometry_get(sd->ee, x, y, w, h); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + ecore_evas_screen_geometry_get(win->ee, x, y, w, h); } EAPI void -elm_win_conformant_set(Evas_Object *obj, - Eina_Bool conformant) +elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - ecore_x_e_illume_conformant_set(sd->xwin, conformant); + _elm_win_xwindow_get(win); + if (win->xwin) + ecore_x_e_illume_conformant_set(win->xwin, conformant); #else - (void)conformant; + (void) conformant; #endif } EAPI Eina_Bool elm_win_conformant_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_illume_conformant_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_illume_conformant_get(win->xwin); #endif return EINA_FALSE; } EAPI void -elm_win_quickpanel_set(Evas_Object *obj, - Eina_Bool quickpanel) +elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) + _elm_win_xwindow_get(win); + if (win->xwin) { - ecore_x_e_illume_quickpanel_set(sd->xwin, quickpanel); + ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel); if (quickpanel) { Ecore_X_Window_State states[2]; states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER; - ecore_x_netwm_window_state_set(sd->xwin, states, 2); - ecore_x_icccm_hints_set(sd->xwin, 0, 0, 0, 0, 0, 0, 0); + ecore_x_netwm_window_state_set(win->xwin, states, 2); + ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0); } } #else - (void)quickpanel; + (void) quickpanel; #endif } EAPI Eina_Bool elm_win_quickpanel_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_illume_quickpanel_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_illume_quickpanel_get(win->xwin); #endif return EINA_FALSE; } EAPI void -elm_win_quickpanel_priority_major_set(Evas_Object *obj, - int priority) +elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - ecore_x_e_illume_quickpanel_priority_major_set(sd->xwin, priority); + _elm_win_xwindow_get(win); + if (win->xwin) + ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority); #else - (void)priority; + (void) priority; #endif } EAPI int elm_win_quickpanel_priority_major_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) - 1; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + win = elm_widget_data_get(obj); + if (!win) return -1; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_illume_quickpanel_priority_major_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin); #endif return -1; } EAPI void -elm_win_quickpanel_priority_minor_set(Evas_Object *obj, - int priority) +elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - ecore_x_e_illume_quickpanel_priority_minor_set(sd->xwin, priority); + _elm_win_xwindow_get(win); + if (win->xwin) + ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority); #else - (void)priority; + (void) priority; #endif } EAPI int elm_win_quickpanel_priority_minor_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) - 1; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) -1; + win = elm_widget_data_get(obj); + if (!win) return -1; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_illume_quickpanel_priority_minor_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin); #endif return -1; } EAPI void -elm_win_quickpanel_zone_set(Evas_Object *obj, - int zone) +elm_win_quickpanel_zone_set(Evas_Object *obj, int zone) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - ecore_x_e_illume_quickpanel_zone_set(sd->xwin, zone); + _elm_win_xwindow_get(win); + if (win->xwin) + ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone); #else - (void)zone; + (void) zone; #endif } EAPI int elm_win_quickpanel_zone_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) 0; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, 0); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) 0; + win = elm_widget_data_get(obj); + if (!win) return 0; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) - return ecore_x_e_illume_quickpanel_zone_get(sd->xwin); + _elm_win_xwindow_get(win); + if (win->xwin) + return ecore_x_e_illume_quickpanel_zone_get(win->xwin); #endif return 0; } EAPI void -elm_win_prop_focus_skip_set(Evas_Object *obj, - Eina_Bool skip) +elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - - sd->skip_focus = skip; - ecore_evas_focus_skip_set(sd->ee, skip); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; + win->skip_focus = skip; + ecore_evas_focus_skip_set(win->ee, skip); } EAPI void -elm_win_illume_command_send(Evas_Object *obj, - Elm_Illume_Command command, - void *params __UNUSED__) +elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params __UNUSED__) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); - + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + win = elm_widget_data_get(obj); + if (!win) return; #ifdef HAVE_ELEMENTARY_X - _elm_win_xwindow_get(sd); - if (sd->xwin) + _elm_win_xwindow_get(win); + if (win->xwin) { switch (command) { case ELM_ILLUME_COMMAND_FOCUS_BACK: - ecore_x_e_illume_focus_back_send(sd->xwin); - break; - + ecore_x_e_illume_focus_back_send(win->xwin); + break; case ELM_ILLUME_COMMAND_FOCUS_FORWARD: - ecore_x_e_illume_focus_forward_send(sd->xwin); - break; - + ecore_x_e_illume_focus_forward_send(win->xwin); + break; case ELM_ILLUME_COMMAND_FOCUS_HOME: - ecore_x_e_illume_focus_home_send(sd->xwin); - break; - + ecore_x_e_illume_focus_home_send(win->xwin); + break; case ELM_ILLUME_COMMAND_CLOSE: - ecore_x_e_illume_close_send(sd->xwin); - break; - + ecore_x_e_illume_close_send(win->xwin); + break; default: - break; + break; } } #else - (void)command; + (void) command; #endif } EAPI Evas_Object * elm_win_inlined_image_object_get(Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return sd->img_obj; + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + return win->img_obj; } EAPI void -elm_win_focus_highlight_enabled_set(Evas_Object *obj, - Eina_Bool enabled) +elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); + Elm_Win *win; + ELM_CHECK_WIDTYPE(obj, widtype); + + win = elm_widget_data_get(obj); enabled = !!enabled; - if (sd->focus_highlight.enabled == enabled) + if (win->focus_highlight.enabled == enabled) return; - sd->focus_highlight.enabled = enabled; + win->focus_highlight.enabled = enabled; - if (sd->focus_highlight.enabled) - _elm_win_focus_highlight_init(sd); + if (win->focus_highlight.enabled) + _elm_win_focus_highlight_init(win); else - _elm_win_focus_highlight_shutdown(sd); + _elm_win_focus_highlight_shutdown(win); } EAPI Eina_Bool elm_win_focus_highlight_enabled_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); + Elm_Win *win; + + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; - return sd->focus_highlight.enabled; + win = elm_widget_data_get(obj); + return win->focus_highlight.enabled; } EAPI void -elm_win_focus_highlight_style_set(Evas_Object *obj, - const char *style) +elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style) { - ELM_WIN_CHECK(obj); - ELM_WIN_DATA_GET_OR_RETURN(obj, sd); + Elm_Win *win; + + ELM_CHECK_WIDTYPE(obj, widtype); - eina_stringshare_replace(&sd->focus_highlight.style, style); - sd->focus_highlight.changed_theme = EINA_TRUE; - _elm_win_focus_highlight_reconfigure_job_start(sd); + win = elm_widget_data_get(obj); + eina_stringshare_replace(&win->focus_highlight.style, style); + win->focus_highlight.changed_theme = EINA_TRUE; + _elm_win_focus_highlight_reconfigure_job_start(win); } EAPI const char * elm_win_focus_highlight_style_get(const Evas_Object *obj) { - ELM_WIN_CHECK(obj) NULL; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); + Elm_Win *win; - return sd->focus_highlight.style; -} - -EAPI Eina_Bool -elm_win_socket_listen(Evas_Object *obj, - const char *svcname, - int svcnum, - Eina_Bool svcsys) -{ - ELM_WIN_CHECK(obj) EINA_FALSE; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE); - - if (!sd->ee) return EINA_FALSE; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; - if (!ecore_evas_extn_socket_listen(sd->ee, svcname, svcnum, svcsys)) - return EINA_FALSE; - - return EINA_TRUE; + win = elm_widget_data_get(obj); + return win->focus_highlight.style; } -/* windowing specific calls - shall we do this differently? */ - -static Ecore_X_Window -_elm_ee_win_get(const Evas_Object *obj) -{ - if (!obj) return 0; -#ifdef HAVE_ELEMENTARY_X - Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); - if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee); -#endif - return 0; -} +typedef struct _Widget_Data Widget_Data; -EAPI Ecore_X_Window -elm_win_xwindow_get(const Evas_Object *obj) +struct _Widget_Data { - if (!obj) return 0; - - if (!evas_object_smart_type_check_ptr(obj, WIN_SMART_NAME)) - return _elm_ee_win_get(obj); - - ELM_WIN_CHECK(obj) 0; - ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, 0); - -#ifdef HAVE_ELEMENTARY_X - if (sd->xwin) return sd->xwin; - if (sd->parent) return elm_win_xwindow_get(sd->parent); -#endif - return 0; -} - -/* Elementary *inner* window widget, from now on */ - -static const char INWIN_SMART_NAME[] = "elm_inwin"; - -#define ELM_INWIN_DATA_GET(o, sd) \ - Elm_Layout_Smart_Data * sd = evas_object_smart_data_get(o) - -#define ELM_INWIN_DATA_GET_OR_RETURN(o, ptr) \ - ELM_INWIN_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define ELM_INWIN_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - ELM_INWIN_DATA_GET(o, ptr); \ - if (!ptr) \ - { \ - CRITICAL("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } + Evas_Object *frm; + Evas_Object *content; +}; -#define ELM_INWIN_CHECK(obj) \ - if (!obj || !elm_widget_type_check((obj), INWIN_SMART_NAME, __func__)) \ - return +static void _del_hook(Evas_Object *obj); +static void _theme_hook(Evas_Object *obj); +static void _sizing_eval(Evas_Object *obj); +static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _sub_del(void *data, Evas_Object *obj, void *event_info); -/* Inheriting from elm_layout. Besides, we need no more than what is - * there */ -EVAS_SMART_SUBCLASS_NEW - (INWIN_SMART_NAME, _elm_inwin, Elm_Layout_Smart_Class, - Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL); +static const char *widtype2 = NULL; -static const Elm_Layout_Part_Alias_Description _content_aliases[] = +static void +_del_hook(Evas_Object *obj) { - {"default", "elm.swallow.content"}, - {NULL, NULL} -}; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} static void -_elm_inwin_smart_sizing_eval(Evas_Object *obj) +_theme_hook(Evas_Object *obj) { - Evas_Object *content; - Evas_Coord minw = -1, minh = -1; - - ELM_INWIN_DATA_GET(obj, sd); - - content = elm_layout_content_get(obj, NULL); + Widget_Data *wd = elm_widget_data_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); - if (!content) return; - - evas_object_size_hint_min_get(content, &minw, &minh); - edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh); - - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, -1, -1); + evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL); } static Eina_Bool -_elm_inwin_smart_focus_next(const Evas_Object *obj, - Elm_Focus_Direction dir, - Evas_Object **next) +_elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next) { - Evas_Object *content; + Widget_Data *wd = elm_widget_data_get(obj); - content = elm_layout_content_get(obj, NULL); + if (!wd) + return EINA_FALSE; - /* attempt to follow focus cycle into sub-object */ - if (content) + /* Try Focus cycle in subitem */ + if (wd->content) { - elm_widget_focus_next_get(content, dir, next); + elm_widget_focus_next_get(wd->content, dir, next); if (*next) return EINA_TRUE; } @@ -3381,92 +3241,195 @@ _elm_inwin_smart_focus_next(const Evas_Object *obj, } static void -_elm_inwin_smart_add(Evas_Object *obj) +_elm_inwin_text_set_hook(Evas_Object *obj, const char *item, const char *text) { - EVAS_SMART_DATA_ALLOC(obj, Elm_Layout_Smart_Data); + Widget_Data *wd = elm_widget_data_get(obj); - ELM_WIDGET_CLASS(_elm_inwin_parent_sc)->base.add(obj); + if (!wd || !item) return; + edje_object_part_text_escaped_set(wd->frm, item, text); + _sizing_eval(obj); +} + +static const char * +_elm_inwin_text_get_hook(const Evas_Object *obj, const char *item) +{ + Widget_Data *wd = elm_widget_data_get(obj); - elm_widget_can_focus_set(obj, EINA_FALSE); - elm_widget_highlight_ignore_set(obj, EINA_TRUE); + if (!item || !wd || !wd->frm) return NULL; + return edje_object_part_text_get(wd->frm, item); } static void -_elm_inwin_smart_set_user(Elm_Layout_Smart_Class *sc) +_sizing_eval(Evas_Object *obj) { - ELM_WIDGET_CLASS(sc)->base.add = _elm_inwin_smart_add; + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Coord minw = -1, minh = -1; - ELM_WIDGET_CLASS(sc)->focus_next = _elm_inwin_smart_focus_next; + evas_object_size_hint_min_get(wd->content, &minw, &minh); + edje_object_size_min_calc(wd->frm, &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); +} - sc->sizing_eval = _elm_inwin_smart_sizing_eval; +static void +_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + _sizing_eval(data); +} - sc->content_aliases = _content_aliases; +static void +_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) +{ + Widget_Data *wd = elm_widget_data_get(obj); + Evas_Object *sub = event_info; + if (sub == wd->content) + { + evas_object_event_callback_del_full + (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj); + wd->content = NULL; + _sizing_eval(obj); + } } EAPI Evas_Object * -elm_win_inwin_add(Evas_Object *parent) +elm_win_inwin_add(Evas_Object *obj) { - Evas *e; - Evas_Object *obj; - - ELM_WIN_CHECK(parent) NULL; /* *has* to have a parent window */ - - e = evas_object_evas_get(parent); - if (!e) return NULL; - - obj = evas_object_smart_add(e, _elm_inwin_smart_class_new()); - - if (!elm_widget_sub_object_add(parent, obj)) - ERR("could not add %p as sub object of %p", obj, parent); - - evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_win_resize_object_add(parent, obj); - - elm_layout_theme_set(obj, "win", "inwin", elm_object_style_get(obj)); - - elm_layout_sizing_eval(obj); + Evas_Object *obj2; + Widget_Data *wd; + Elm_Win *win; - return obj; + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + win = elm_widget_data_get(obj); + if (!win) return NULL; + wd = ELM_NEW(Widget_Data); + obj2 = elm_widget_add(win->evas); + elm_widget_type_set(obj2, "inwin"); + ELM_SET_WIDTYPE(widtype2, "inwin"); + elm_widget_sub_object_add(obj, obj2); + evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add(obj, obj2); + + elm_widget_data_set(obj2, wd); + elm_widget_del_hook_set(obj2, _del_hook); + elm_widget_theme_hook_set(obj2, _theme_hook); + elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook); + elm_widget_text_set_hook_set(obj2, _elm_inwin_text_set_hook); + elm_widget_text_get_hook_set(obj2, _elm_inwin_text_get_hook); + elm_widget_can_focus_set(obj2, EINA_TRUE); + elm_widget_highlight_ignore_set(obj2, EINA_TRUE); + + wd->frm = edje_object_add(win->evas); + _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); + + _sizing_eval(obj2); + return obj2; } EAPI void elm_win_inwin_activate(Evas_Object *obj) { - ELM_INWIN_CHECK(obj); - ELM_INWIN_DATA_GET_OR_RETURN(obj, sd); - + ELM_CHECK_WIDTYPE(obj, widtype2); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; evas_object_raise(obj); evas_object_show(obj); - edje_object_signal_emit - (ELM_WIDGET_DATA(sd)->resize_obj, "elm,action,show", "elm"); + edje_object_signal_emit(wd->frm, "elm,action,show", "elm"); elm_object_focus_set(obj, EINA_TRUE); } EAPI void -elm_win_inwin_content_set(Evas_Object *obj, - Evas_Object *content) -{ - ELM_INWIN_CHECK(obj); - ELM_INWIN_DATA_GET_OR_RETURN(obj, sd); - - ELM_CONTAINER_CLASS(_elm_inwin_parent_sc)->content_set(obj, NULL, content); +elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content) +{ + ELM_CHECK_WIDTYPE(obj, widtype2); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->content == content) return; + if (wd->content) evas_object_del(wd->content); + wd->content = content; + if (content) + { + elm_widget_sub_object_add(obj, content); + evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_swallow(wd->frm, "elm.swallow.content", content); + } + _sizing_eval(obj); } EAPI Evas_Object * elm_win_inwin_content_get(const Evas_Object *obj) { - ELM_INWIN_CHECK(obj) NULL; - ELM_INWIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); - - return ELM_CONTAINER_CLASS(_elm_inwin_parent_sc)->content_get(obj, NULL); + ELM_CHECK_WIDTYPE(obj, widtype2) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + return wd->content; } EAPI Evas_Object * elm_win_inwin_content_unset(Evas_Object *obj) { - ELM_INWIN_CHECK(obj) NULL; - ELM_INWIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL); + ELM_CHECK_WIDTYPE(obj, widtype2) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + if (!wd->content) return NULL; + Evas_Object *content = wd->content; + elm_widget_sub_object_del(obj, wd->content); + evas_object_event_callback_del_full(wd->content, + EVAS_CALLBACK_CHANGED_SIZE_HINTS, + _changed_size_hints, obj); + edje_object_part_unswallow(wd->frm, wd->content); + wd->content = NULL; + return content; +} + +EAPI Eina_Bool +elm_win_socket_listen(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys) +{ + + Elm_Win *win; + + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + win = elm_widget_data_get(obj); + if (!win) return EINA_FALSE; + if (!win->ee) return EINA_FALSE; + + if (!ecore_evas_extn_socket_listen(win->ee, svcname, svcnum, svcsys)) + return EINA_FALSE; + + return EINA_TRUE; +} + +/* windowing specific calls - shall we do this differently? */ + +static Ecore_X_Window +_elm_ee_win_get(const Evas_Object *obj) +{ + if (!obj) return 0; +#ifdef HAVE_ELEMENTARY_X + Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); + if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee); +#endif + return 0; +} - return ELM_CONTAINER_CLASS(_elm_inwin_parent_sc)->content_unset(obj, NULL); +EAPI Ecore_X_Window +elm_win_xwindow_get(const Evas_Object *obj) +{ + Elm_Win *win; + const char *type; + + if (!obj) return 0; + type = elm_widget_type_get(obj); + if ((!type) || (type != widtype)) return _elm_ee_win_get(obj); + win = elm_widget_data_get(obj); + if (!win) return 0; +#ifdef HAVE_ELEMENTARY_X + if (win->xwin) return win->xwin; + if (win->parent) return elm_win_xwindow_get(win->parent); +#endif + return 0; } diff --git a/src/lib/elm_win.h b/src/lib/elm_win.h index d0c0e4d1c..0cf2810e7 100644 --- a/src/lib/elm_win.h +++ b/src/lib/elm_win.h @@ -1277,10 +1277,6 @@ EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj); * possible, but it's sized vertically the most it needs to fit its\ * contents. * - * This widget inherits from the @ref Layout one, so that all the - * functions acting on it also work for inner windown objects. It also - * emits the signals inherited from @ref Layout. - * * Some examples of Inwin can be found in the following: * @li @ref inwin_example_01 * |