From c3c65009e1d6036bf9365d69858cd6809e50614d Mon Sep 17 00:00:00 2001 From: Amitesh Singh Date: Wed, 16 Mar 2016 08:45:27 +0530 Subject: introduce nstate widget and inherit check & radio from it Test Plan: 1. elementary_test -to "check" 2. tristate check. Reviewers: yashu21985, raster, cedric, tasn, Hermet, seoz, smohanty, felipealmeida, JackDanielZ, jpeg, jypark, herdsman, woohyun Subscribers: saurabhbunty, seoz Differential Revision: https://phab.enlightenment.org/D3786 --- config/default/base.src.in | 23 ++ config/mobile/base.src.in | 23 ++ config/standard/base.src.in | 23 ++ data/themes/Makefile.am | 1 + data/themes/default.edc | 1 + data/themes/edc/elm/check.edc | 341 +++++++++++++++++++++++++++++- data/themes/edc/elm/nstate.edc | 10 + data/themes/img/sym_check_intmed_alum.png | Bin 0 -> 203 bytes src/bin/Makefile.am | 1 + src/bin/test.c | 4 + src/bin/test_check.c | 14 ++ src/bin/test_nstate.c | 42 ++++ src/lib/Elementary.h.in | 1 + src/lib/Makefile.am | 6 + src/lib/elm_check.c | 159 +++++--------- src/lib/elm_check.eo | 40 +--- src/lib/elm_check_legacy.h | 43 +++- src/lib/elm_nstate.c | 188 ++++++++++++++++ src/lib/elm_nstate.eo | 47 ++++ src/lib/elm_nstate.h | 7 + src/lib/elm_nstate_eo.h | 1 + src/lib/elm_nstate_legacy.h | 11 + src/lib/elm_widget_check.h | 1 - src/lib/elm_widget_nstate.h | 36 ++++ 24 files changed, 875 insertions(+), 148 deletions(-) create mode 100644 data/themes/edc/elm/nstate.edc create mode 100644 data/themes/img/sym_check_intmed_alum.png create mode 100644 src/bin/test_nstate.c create mode 100644 src/lib/elm_nstate.c create mode 100644 src/lib/elm_nstate.eo create mode 100644 src/lib/elm_nstate.h create mode 100644 src/lib/elm_nstate_eo.h create mode 100644 src/lib/elm_nstate_legacy.h create mode 100644 src/lib/elm_widget_nstate.h diff --git a/config/default/base.src.in b/config/default/base.src.in index 891a7b75b..e5933f870 100644 --- a/config/default/base.src.in +++ b/config/default/base.src.in @@ -621,6 +621,29 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Elm_Nstate"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } + } + } group "Elm_Config_Bindings_Widget" struct { value "name" string: "Elm_Calendar"; group "key_bindings" list { diff --git a/config/mobile/base.src.in b/config/mobile/base.src.in index b950c805c..7ba03bc87 100644 --- a/config/mobile/base.src.in +++ b/config/mobile/base.src.in @@ -625,6 +625,29 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Elm_Nstate"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } + } + } group "Elm_Config_Bindings_Widget" struct { value "name" string: "Elm_Calendar"; group "key_bindings" list { diff --git a/config/standard/base.src.in b/config/standard/base.src.in index 02344b083..ba0d70067 100644 --- a/config/standard/base.src.in +++ b/config/standard/base.src.in @@ -622,6 +622,29 @@ group "Elm_Config" struct { } } } + group "Elm_Config_Bindings_Widget" struct { + value "name" string: "Elm_Nstate"; + group "key_bindings" list { + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "Return"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "KP_Enter"; + value "action" string: "activate"; + value "params" string: ""; + } + group "Elm_Config_Binding_Key" struct { + value "context" int: 0; + value "key" string: "space"; + value "action" string: "activate"; + value "params" string: ""; + } + } + } group "Elm_Config_Bindings_Widget" struct { value "name" string: "Elm_Calendar"; group "key_bindings" list { diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am index 319125631..73f56adfc 100644 --- a/data/themes/Makefile.am +++ b/data/themes/Makefile.am @@ -613,6 +613,7 @@ img/split_v_glow.png \ img/split_v_hilight.png \ img/split_v_inset.png \ img/sym_check_alum.png \ +img/sym_check_intmed_alum.png \ img/sym_close_dark_normal.png \ img/sym_close_dark_selected.png \ img/sym_close_light_normal.png \ diff --git a/data/themes/default.edc b/data/themes/default.edc index 2ba757d02..08853113d 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -13,6 +13,7 @@ collections { // elm #include "edc/elm/bg.edc" #include "edc/elm/button.edc" +#include "edc/elm/nstate.edc" // XXX: mobile mode needs invisible scrollers... make signals that do this #include "edc/elm/scroller.edc" // XXX: mobile mode needs different entry setup diff --git a/data/themes/edc/elm/check.edc b/data/themes/edc/elm/check.edc index 10ecd0e10..a9fd4b860 100644 --- a/data/themes/edc/elm/check.edc +++ b/data/themes/edc/elm/check.edc @@ -331,7 +331,7 @@ group { name: "elm/check/base/toggle"; images.image: "vgrad_med_lighter.png" COMP; images.image: "shadow_square_tiny.png" COMP; images.image: "glow_small.png" COMP; - + #define ICON 1 #define LABEL 2 #define MASK 3 @@ -340,8 +340,8 @@ group { name: "elm/check/base/toggle"; public is_rtl; public is_drag; public was_drag; - public btmode; + public eval_mode(m) { new m1 = m & MASK; new d = m & DISABLE; @@ -935,3 +935,340 @@ group { name: "elm/check/base/toggle"; #undef MASK #undef DISABLE } + +group { name: "elm/check/base/tristate"; + images.image: "inset_shadow_tiny.png" COMP; + images.image: "bevel_in.png" COMP; + images.image: "sym_check_alum.png" COMP; + images.image: "sym_check_intmed_alum.png" COMP; +#define ICON 1 +#define LABEL 2 +#define MASK 3 +#define DISABLE 4 + script { + public btmode; + public eval_mode(m) { + new m1 = m & MASK; + new d = m & DISABLE; + if (m1 == (ICON | LABEL)) { + if (!d) { + set_state(PART:"elm.swallow.content", "visible", 0.0); + set_state(PART:"sizer.content", "visible", 0.0); + set_state(PART:"elm.text", "visible", 0.0); + set_state(PART:"shadow", "default", 0.0); + set_state(PART:"base", "default", 0.0); + set_state(PART:"clip", "default", 0.0); + set_state(PART:"event", "default", 0.0); + } else { + set_state(PART:"elm.swallow.content", "visible", 0.0); + set_state(PART:"sizer.content", "visible", 0.0); + set_state(PART:"elm.text", "disabled_visible", 0.0); + set_state(PART:"shadow", "disabled", 0.0); + set_state(PART:"base", "disabled", 0.0); + set_state(PART:"clip", "disabled", 0.0); + set_state(PART:"event", "disabled", 0.0); + } + } else if (m1 == (ICON)) { + if (!d) { + set_state(PART:"elm.swallow.content", "visible", 0.0); + set_state(PART:"sizer.content", "icononly", 0.0); + set_state(PART:"elm.text", "default", 0.0); + set_state(PART:"shadow", "default", 0.0); + set_state(PART:"base", "default", 0.0); + set_state(PART:"clip", "default", 0.0); + set_state(PART:"event", "default", 0.0); + } else { + set_state(PART:"elm.swallow.content", "visible", 0.0); + set_state(PART:"sizer.content", "icononly", 0.0); + set_state(PART:"elm.text", "disabled", 0.0); + set_state(PART:"shadow", "disabled", 0.0); + set_state(PART:"base", "disabled", 0.0); + set_state(PART:"clip", "disabled", 0.0); + set_state(PART:"event", "disabled", 0.0); + } + } else if (m1 == (LABEL)) { + if (!d) { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"sizer.content", "default", 0.0); + set_state(PART:"elm.text", "visible", 0.0); + set_state(PART:"shadow", "default", 0.0); + set_state(PART:"base", "default", 0.0); + set_state(PART:"clip", "default", 0.0); + set_state(PART:"event", "default", 0.0); + } else { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"sizer.content", "default", 0.0); + set_state(PART:"elm.text", "disabled_visible", 0.0); + set_state(PART:"shadow", "disabled", 0.0); + set_state(PART:"base", "disabled", 0.0); + set_state(PART:"clip", "disabled", 0.0); + set_state(PART:"event", "disabled", 0.0); + } + } else { + if (!d) { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"sizer.content", "default", 0.0); + set_state(PART:"elm.text", "default", 0.0); + set_state(PART:"shadow", "default", 0.0); + set_state(PART:"base", "default", 0.0); + set_state(PART:"clip", "default", 0.0); + set_state(PART:"event", "default", 0.0); + } else { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"sizer.content", "default", 0.0); + set_state(PART:"elm.text", "default", 0.0); + set_state(PART:"shadow", "disabled", 0.0); + set_state(PART:"base", "disabled", 0.0); + set_state(PART:"clip", "disabled", 0.0); + set_state(PART:"event", "disabled", 0.0); + } + } + } + } + parts { + part { name: "base"; type: RECT; + description { state: "default" 0.0; + rel1.offset: 1 1; + rel1.to: "inset"; + rel2.offset: -2 -2; + rel2.to: "inset"; + color: 24 24 24 255; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 64 64 64 255; + } + } + part { name: "shadow"; mouse_events: 0; + description { state: "default" 0.0; + image.normal: "inset_shadow_tiny.png"; + image.border: 4 4 4 4; + rel1.to: "base"; + rel2.to: "base"; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "inset"; mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 0; + rel1.offset: 2 2; + rel2.relative: 0.0 1.0; + rel2.offset: 2 -3; + align: 0.0 0.5; + min: 13 13; + max: 13 13; + image.normal: "bevel_in.png"; + image.border: 1 1 1 1; + image.middle: 0; + fill.smooth: 0; + } + } + part { name: "indicator"; mouse_events: 0; + scale: 1; + clip_to: "clip"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "base"; + rel2.to: "base"; + image.normal: "sym_check_alum.png"; + min: 11 11; + max: 11 11; + visible: 0; + } + description { state: "mid_selected" 0.0; + inherit: "default" 0.0; + image.normal: "sym_check_intmed_alum.png"; + visible: 1; + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "clip"; type: RECT; + description { state: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 64; + } + } + part { name: "elm.swallow.content"; type: SWALLOW; + scale: 1; + clip_to: "clip"; + description { state: "default" 0.0; + fixed: 1 0; + visible: 0; + align: 0.0 0.5; + max: 0 0; + rel1.to_x: "inset"; + rel1.relative: 1.0 0.0; + rel1.offset: 1 1; + rel2.to_x: "inset"; + rel2.offset: 1 -2; + rel2.relative: 1.0 1.0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + fixed: 0 0; + visible: 1; + aspect: 1.0 1.0; + min: 16 16; + } + } + part { name: "sizer.content"; type: TEXT; mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + visible: 0; + text { font: FN; size: 10; + min: 0 0; + text_class: "check_text"; + } + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + rel1.to: "elm.swallow.content"; + rel2.to: "elm.swallow.content"; + text { + min: 1 1; + ellipsis: -1; + text: "M"; + } + } + description { state: "icononly" 0.0; + inherit: "default" 0.0; + rel1.to: "elm.swallow.content"; + rel2.to: "elm.swallow.content"; + text { + min: 1 1; + ellipsis: -1; + text: "M"; + } + } + } + part { name: "elm.text"; type: TEXT; mouse_events: 0; + effect: SHADOW BOTTOM; + scale: 1; + description { state: "default" 0.0; + rel1.offset: 2 2; + rel1.to_x: "elm.swallow.content"; + rel1.relative: 1.0 0.0; + rel2.offset: -3 -3; + color: FN_COL_DEFAULT; + color_class: "check_text"; + text { font: FN; size: 10; + min: 0 0; + align: 0.0 0.5; + text_class: "check"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color_class: "check_text_disabled"; + color3: 255 255 255 255; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + text.min: 1 1; + text.ellipsis: -1; + } + description { state: "disabled_visible" 0.0; + inherit: "default" 0.0; + color_class: "check_text_disabled"; + color3: 255 255 255 255; + visible: 1; + text.min: 1 1; + text.ellipsis: -1; + } + } + part { name: "event"; type: RECT; + ignore_flags: ON_HOLD; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + } + programs { + program { + signal: "mouse,clicked,1"; source: "event"; + action: SIGNAL_EMIT "elm,action,state,changed" "elm"; + } + program { + signal: "elm,state,changed,0"; source: "elm"; + action: STATE_SET "default" 0.0; + target: "indicator"; + } + program { + signal: "elm,state,changed,1"; source: "elm"; + action: STATE_SET "mid_selected" 0.0; + target: "indicator"; + } + program { + signal: "elm,state,changed,2"; source: "elm"; + action: STATE_SET "selected" 0.0; + target: "indicator"; + } + program { + signal: "elm,state,text,visible"; source: "elm"; + script { + new m = get_int(btmode); + m |= LABEL; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "elm,state,text,hidden"; source: "elm"; + script { + new m = get_int(btmode); + m &= ~LABEL; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "elm,state,icon,visible"; source: "elm"; + script { + new m = get_int(btmode); + m |= ICON; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "elm,state,icon,hidden"; source: "elm"; + script { + new m = get_int(btmode); + m &= ~ICON; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "elm,state,disabled"; source: "elm"; + script { + new m = get_int(btmode); + m |= DISABLE; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "elm,state,enabled"; source: "elm"; + script { + new m = get_int(btmode); + m &= ~DISABLE; set_int(btmode, m); + eval_mode(m); + } + } + } +#undef ICON +#undef LABEL +#undef MASK +#undef DISABLE +} diff --git a/data/themes/edc/elm/nstate.edc b/data/themes/edc/elm/nstate.edc new file mode 100644 index 000000000..f05880699 --- /dev/null +++ b/data/themes/edc/elm/nstate.edc @@ -0,0 +1,10 @@ +group { name: "elm/nstate/base/default"; + inherit: "elm/button/base/default"; + programs { + program { + signal: "mouse,clicked,1"; source: "event"; + action: SIGNAL_EMIT "elm,action,state,changed" "elm"; + } + } +} + diff --git a/data/themes/img/sym_check_intmed_alum.png b/data/themes/img/sym_check_intmed_alum.png new file mode 100644 index 000000000..3b2c0eac9 Binary files /dev/null and b/data/themes/img/sym_check_intmed_alum.png differ diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 46db673e5..4a0382f47 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -99,6 +99,7 @@ test_multibuttonentry.c \ test_naviframe.c \ test_naviframe_complex.c \ test_notify.c \ +test_nstate.c \ test_panel.c \ test_panes.c \ test_photo.c \ diff --git a/src/bin/test.c b/src/bin/test.c index 3bad1c6d2..3e4676b87 100644 --- a/src/bin/test.c +++ b/src/bin/test.c @@ -49,6 +49,7 @@ void test_combobox(void *data, Evas_Object *obj, void *event_info); void test_combobox2(void *data, Evas_Object *obj, void *event_info); void test_check(void *data, Evas_Object *obj, void *event_info); void test_check_toggle(void *data, Evas_Object *obj, void *event_info); +void test_nstate(void *data, Evas_Object *obj, void *event_info); void test_radio(void *data, Evas_Object *obj, void *event_info); void test_layout(void *data, Evas_Object *obj, void *event_info); void test_layout2(void *data, Evas_Object *obj, void *event_info); @@ -781,6 +782,9 @@ add_tests: ADD_TEST(NULL, "Range Values", "Progressbar", test_progressbar); ADD_TEST(NULL, "Range Values", "Progressbar 2", test_progressbar2); + //------------------------------// + ADD_TEST(NULL, "Range Values", "Nstate", test_nstate); + //------------------------------// ADD_TEST(NULL, "Booleans", "Check", test_check); ADD_TEST(NULL, "Booleans", "Check Toggle", test_check_toggle); diff --git a/src/bin/test_check.c b/src/bin/test_check.c index 1ee3935cc..90a6eaa0d 100644 --- a/src/bin/test_check.c +++ b/src/bin/test_check.c @@ -14,6 +14,12 @@ changed_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) printf("ck2 %p is now %i\n", ck2, elm_check_state_get(ck2)); } +static void +_tristate_changed_cb(void *d EINA_UNUSED, Evas_Object *o, void *ei EINA_UNUSED) +{ + printf("tristate check state: %d\n", efl_ui_nstate_value_get(o)); +} + static void state_changed_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { @@ -106,6 +112,14 @@ test_check(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf evas_object_show(ck); evas_object_show(ic); + ck = elm_check_add(win); + efl_ui_nstate_count_set(ck, 3); + elm_object_style_set(ck, "tristate"); + elm_object_text_set(ck, "tristate"); + elm_box_pack_end(bx, ck); + evas_object_show(ck); + evas_object_smart_callback_add(ck, "state,changed", _tristate_changed_cb, NULL); + evas_object_show(win); } diff --git a/src/bin/test_nstate.c b/src/bin/test_nstate.c new file mode 100644 index 000000000..6f1e27ed5 --- /dev/null +++ b/src/bin/test_nstate.c @@ -0,0 +1,42 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + +static void +_state_changed_cb(void *d EINA_UNUSED, Evas_Object *o, void *ei EINA_UNUSED) +{ + char buf[100]; + int val; + + val = efl_ui_nstate_value_get(o); + + printf("nstate widget state: %d\n", val); + sprintf(buf, "nstate = %d", val); + elm_object_text_set(o, buf); +} + +void +test_nstate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *win, *bx, *nstate; + + win = elm_win_util_standard_add("nstate", "nstate"); + elm_win_autodel_set(win, EINA_TRUE); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + nstate = elm_nstate_add(win); + efl_ui_nstate_count_set(nstate, 5); + elm_object_text_set(nstate, "nstate = 0"); + elm_box_pack_end(bx, nstate); + evas_object_show(nstate); + evas_object_smart_callback_add(nstate, "state,changed", + _state_changed_cb, NULL); + + evas_object_resize(win, 100, 100); + evas_object_show(win); +} diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index b8fe89a2f..54dac8fdd 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -236,6 +236,7 @@ EAPI extern Elm_Version *elm_version; #include #include #include +#include #include #include diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 7ea2597f6..03e6d9049 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -87,6 +87,7 @@ elm_widget_menu.h \ elm_widget_multibuttonentry.h \ elm_widget_naviframe.h \ elm_widget_notify.h \ +elm_widget_nstate.h \ elm_widget_panel.h \ elm_widget_panes.h \ elm_widget_photo.h \ @@ -289,6 +290,9 @@ elm_notify.h \ elm_notify_common.h \ elm_notify_eo.h \ elm_notify_legacy.h \ +elm_nstate.h \ +elm_nstate_eo.h \ +elm_nstate_legacy.h \ elm_object.h \ elm_object_item.h \ elm_panel.h \ @@ -462,6 +466,7 @@ elm_mapbuf.c \ elm_menu.c \ elm_module.c \ elm_notify.c \ +elm_nstate.c \ elm_panel.c \ elm_panes.c \ elm_photo.c \ @@ -583,6 +588,7 @@ elm_menu.eo \ elm_multibuttonentry.eo \ elm_naviframe.eo \ elm_notify.eo \ +elm_nstate.eo \ elm_pan.eo \ elm_panel.eo \ elm_panes.eo \ diff --git a/src/lib/elm_check.c b/src/lib/elm_check.c index 024e3dacb..ea82c6963 100644 --- a/src/lib/elm_check.c +++ b/src/lib/elm_check.c @@ -8,19 +8,13 @@ #include #include "elm_priv.h" #include "elm_widget_check.h" -#include "elm_widget_layout.h" +#include "elm_widget_nstate.h" #define MY_CLASS ELM_CHECK_CLASS #define MY_CLASS_NAME "Elm_Check" #define MY_CLASS_NAME_LEGACY "elm_check" -static const Elm_Layout_Part_Alias_Description _content_aliases[] = -{ - {"icon", "elm.swallow.content"}, - {NULL, NULL} -}; - static const Elm_Layout_Part_Alias_Description _text_aliases[] = { {"default", "elm.text"}, @@ -53,9 +47,10 @@ _activate(Evas_Object *obj) { ELM_CHECK_DATA_GET(obj, sd); - sd->state = !sd->state; - if (sd->statep) *sd->statep = sd->state; - if (sd->state) + efl_ui_nstate_activate(obj); + if (sd->statep) *sd->statep = efl_ui_nstate_value_get(obj); + + if (efl_ui_nstate_value_get(obj) == 1) { // FIXME: to do animation during state change , we need different signal // so that we can distinguish between state change by user or state change @@ -66,7 +61,7 @@ _activate(Evas_Object *obj) if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF) _elm_access_say(E_("State: On")); } - else + else if (efl_ui_nstate_value_get(obj) == 0) { // FIXME: to do animation during state change , we need different signal // so that we can distinguish between state change by user or state change @@ -83,7 +78,7 @@ _activate(Evas_Object *obj) if (_elm_config->atspi_mode) elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_CHECKED, - sd->state); + efl_ui_nstate_value_get(obj)); } /* FIXME: replicated from elm_layout just because check's icon spot @@ -144,37 +139,6 @@ _elm_check_elm_widget_activate(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNU return EINA_TRUE; } -/* FIXME: replicated from elm_layout just because check's icon spot - * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we - * can changed the theme API */ -EOLIAN static Eina_Bool -_elm_check_elm_container_content_set(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content) -{ - Eina_Bool int_ret = EINA_FALSE; - - int_ret = elm_obj_container_content_set(eo_super(obj, MY_CLASS), part, content); - if (!int_ret) return EINA_FALSE; - - _icon_signal_emit(obj); - - elm_obj_layout_sizing_eval(obj); - - return EINA_TRUE; -} - -EOLIAN static void -_elm_check_elm_layout_sizing_eval(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED) -{ - Evas_Coord minw = -1, minh = -1; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - - elm_coords_finger_size_adjust(1, &minw, 1, &minh); - edje_object_size_min_restricted_calc - (wd->resize_obj, &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 _key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED) { @@ -199,17 +163,20 @@ _elm_check_elm_widget_event(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED, Evas_Objec } EOLIAN static Eina_Bool -_elm_check_elm_widget_theme_apply(Eo *obj, Elm_Check_Data *sd) +_elm_check_elm_widget_theme_apply(Eo *obj, Elm_Check_Data *sd EINA_UNUSED) { Eina_Bool int_ret = EINA_FALSE; ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); int_ret = elm_obj_widget_theme_apply(eo_super(obj, MY_CLASS)); + if (!int_ret) 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"); + if (efl_ui_nstate_value_get(obj) == 0) + elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); + else if (efl_ui_nstate_value_get(obj) == 1) + elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); edje_object_message_signal_process(wd->resize_obj); @@ -237,12 +204,11 @@ _access_info_cb(void *data EINA_UNUSED, Evas_Object *obj) static char * _access_state_cb(void *data, Evas_Object *obj) { - Elm_Check_Data *sd = eo_data_scope_get(data, MY_CLASS); const char *on_text, *off_text; if (elm_widget_disabled_get(obj)) return strdup(E_("State: Disabled")); - if (sd->state) + if (efl_ui_nstate_value_get(obj)) { on_text = elm_layout_text_get(data, "on"); @@ -279,8 +245,8 @@ _on_check_off(void *data, ELM_CHECK_DATA_GET(obj, sd); - sd->state = EINA_FALSE; - if (sd->statep) *sd->statep = sd->state; + efl_ui_nstate_value_set(obj, 0); + if (sd->statep) *sd->statep = efl_ui_nstate_value_get(obj); elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); eo_event_callback_call(obj, ELM_CHECK_EVENT_CHANGED, NULL); @@ -288,7 +254,7 @@ _on_check_off(void *data, if (_elm_config->atspi_mode) elm_interface_atspi_accessible_state_changed_signal_emit(data, ELM_ATSPI_STATE_CHECKED, - sd->state); + efl_ui_nstate_value_get(obj)); } static void @@ -301,15 +267,15 @@ _on_check_on(void *data, ELM_CHECK_DATA_GET(obj, sd); - sd->state = EINA_TRUE; - if (sd->statep) *sd->statep = sd->state; + efl_ui_nstate_value_set(obj, 1); + if (sd->statep) *sd->statep = efl_ui_nstate_value_get(obj); elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); eo_event_callback_call(obj, ELM_CHECK_EVENT_CHANGED, NULL); if (_elm_config->atspi_mode) - elm_interface_atspi_accessible_state_changed_signal_emit(data, - ELM_ATSPI_STATE_CHECKED, - sd->state); + elm_interface_atspi_accessible_state_changed_signal_emit(data, + ELM_ATSPI_STATE_CHECKED, + efl_ui_nstate_value_get(obj)); } static void @@ -329,6 +295,9 @@ _elm_check_evas_object_smart_add(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED) evas_obj_smart_add(eo_super(obj, MY_CLASS)); elm_widget_sub_object_parent_add(obj); + if (!elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj))) + CRI("Failed to set layout!"); + edje_object_signal_callback_add (wd->resize_obj, "elm,action,check,on", "*", _on_check_on, obj); @@ -348,19 +317,9 @@ _elm_check_evas_object_smart_add(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED) (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, obj); elm_widget_can_focus_set(obj, EINA_TRUE); - - if (!elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj))) - CRI("Failed to set layout!"); - elm_layout_sizing_eval(obj); } -EOLIAN static const Elm_Layout_Part_Alias_Description* -_elm_check_elm_layout_content_aliases_get(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED) -{ - return _content_aliases; -} - EOLIAN static const Elm_Layout_Part_Alias_Description* _elm_check_elm_layout_text_aliases_get(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED) { @@ -386,59 +345,49 @@ _elm_check_eo_base_constructor(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED) return obj; } -EOLIAN static void -_elm_check_state_set(Eo *obj, Elm_Check_Data *sd, Eina_Bool state) +EAPI void +elm_check_state_set(Evas_Object *obj, Eina_Bool state) { + ELM_CHECK_DATA_GET_OR_RETURN(obj, sd); ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - if (state != sd->state) - { - sd->state = state; - if (sd->statep) *sd->statep = sd->state; - if (sd->state) - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); - else - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); - } + if (state == efl_ui_nstate_value_get(obj)) return; + + efl_ui_nstate_value_set(obj, state); + if (sd->statep) *sd->statep = efl_ui_nstate_value_get(obj); + if (efl_ui_nstate_value_get(obj) == 1) + elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); + else if (efl_ui_nstate_value_get(obj) == 0) + elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); edje_object_message_signal_process(wd->resize_obj); } -EOLIAN static Eina_Bool -_elm_check_state_get(Eo *obj EINA_UNUSED, Elm_Check_Data *sd) +EAPI Eina_Bool +elm_check_state_get(const Evas_Object *obj) { - return sd->state; + return !!efl_ui_nstate_value_get(obj); } -EOLIAN static void -_elm_check_state_pointer_set(Eo *obj, Elm_Check_Data *sd, Eina_Bool *statep) +EAPI void +elm_check_state_pointer_set(Eo *obj, Eina_Bool *statep) { - if (statep) + ELM_CHECK_DATA_GET_OR_RETURN(obj, sd); + if (!statep) { - sd->statep = statep; - if (*sd->statep != sd->state) - { - sd->state = *sd->statep; - if (sd->state) - elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); - else - elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); - } + sd->statep = NULL; + return; } - else - sd->statep = NULL; -} -EOLIAN static Eina_Bool -_elm_check_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED) -{ - return EINA_FALSE; -} - -EOLIAN static Eina_Bool -_elm_check_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED) -{ - return EINA_FALSE; + sd->statep = statep; + if (*sd->statep != efl_ui_nstate_value_get(obj)) + { + efl_ui_nstate_value_set(obj, *sd->statep); + if (efl_ui_nstate_value_get(obj) == 1) + elm_layout_signal_emit(obj, "elm,state,check,on", "elm"); + else if (efl_ui_nstate_value_get(obj) == 0) + elm_layout_signal_emit(obj, "elm,state,check,off", "elm"); + } } EOLIAN const Elm_Atspi_Action * diff --git a/src/lib/elm_check.eo b/src/lib/elm_check.eo index 452ab93b9..0f8c5f4ba 100644 --- a/src/lib/elm_check.eo +++ b/src/lib/elm_check.eo @@ -1,55 +1,17 @@ -class Elm.Check (Elm.Layout, Elm.Interface_Atspi_Widget_Action) +class Elm.Check (Elm.Nstate, Elm.Interface_Atspi_Widget_Action) { eo_prefix: elm_obj_check; methods { - @property state { - set { - [[Set the on/off state of the check object - - This sets the state of the check. If set with - @.state_pointer.set, the state of that variable is also - changed. Calling this doesn't cause the "changed" signal to - be emitted. - ]] - } - get { - [[Get the state of the check object]] - } - values { - state: bool; [[The state to use (1 == on, 0 == off)]] - } - } - @property state_pointer { - set { - [[Set a convenience pointer to a boolean to change - - This sets a pointer to a boolean, that, in addition to the check - objects state will also be modified directly. To stop setting the - object pointed to simply use null as the "statep" parameter. - If "statep" is not null, then when this is called, the check - objects state will also be modified to reflect the value of the - boolean "statep" points to, just like calling @.state.set. - ]] - } - values { - statep: bool * @nullable; [[Pointer to the boolean to modify]] - } - } } implements { class.constructor; Eo.Base.constructor; Evas.Object_Smart.add; Elm.Widget.activate; - Elm.Widget.focus_next_manager_is; - Elm.Widget.focus_direction_manager_is; Elm.Widget.theme_apply; Elm.Widget.sub_object_del; Elm.Widget.event; - Elm.Container.content_set; Elm.Layout.text_aliases.get; - Elm.Layout.content_aliases.get; - Elm.Layout.sizing_eval; Elm.Interface_Atspi_Accessible.state_set.get; Elm.Interface_Atspi_Widget_Action.elm_actions.get; } diff --git a/src/lib/elm_check_legacy.h b/src/lib/elm_check_legacy.h index 742881d98..d28ea9172 100644 --- a/src/lib/elm_check_legacy.h +++ b/src/lib/elm_check_legacy.h @@ -8,4 +8,45 @@ */ EAPI Evas_Object * elm_check_add(Evas_Object *parent); -#include "elm_check.eo.legacy.h" \ No newline at end of file +/** + * @brief Get the state of the check object + * + * @param obj The check object + * + * @ingroup Check + */ +EAPI Eina_Bool elm_check_state_get(const Evas_Object *obj); + +/** + * @brief Set the on/off state of the check object + * + * This sets the state of the check. If set with + * @.state_pointer.set, the state of that variable is also + * changed. Calling this doesn't cause the "changed" signal to + * be emitted. + * + * @param obj The check object + * @param state The state to use (1 == on, 0 == off) + * + * @ingroup Check + */ +EAPI void elm_check_state_set(Evas_Object *obj, Eina_Bool state); + +/** + * @brief Set a convenience pointer to a boolean to change + * + * This sets a pointer to a boolean, that, in addition to the check + * objects state will also be modified directly. To stop setting the + * object pointed to simply use null as the "statep" parameter. + * If "statep" is not null, then when this is called, the check + * objects state will also be modified to reflect the value of the + * boolean "statep" points to, just like calling @.state.set. + * + * @param obj The check object + * @param statep pointer to the boolean to modify + * + * @ingroup Check + */ +EAPI void elm_check_state_pointer_set(Evas_Object *obj, Eina_Bool *statep); + +#include "elm_check.eo.legacy.h" diff --git a/src/lib/elm_nstate.c b/src/lib/elm_nstate.c new file mode 100644 index 000000000..16d383dce --- /dev/null +++ b/src/lib/elm_nstate.c @@ -0,0 +1,188 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include "elm_nstate_eo.h" +#include "elm_button_eo.h" +#include "elm_priv.h" +#include "elm_widget_nstate.h" +#include "elm_widget_button.h" + +#define MY_CLASS ELM_NSTATE_CLASS + +#define MY_CLASS_NAME "Elm_Nstate" +#define MY_CLASS_NAME_LEGACY "elm_nstate" + +static const Evas_Smart_Cb_Description _smart_callbacks[] = { + {NULL, NULL} +}; + +static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params); +static void _state_active(Evas_Object *obj, Elm_Nstate_Data *sd); + +static const Elm_Action key_actions[] = { + {"activate", _key_action_activate}, + {NULL, NULL} +}; + +EOLIAN static Eo_Base * +_elm_nstate_eo_base_constructor(Eo *obj, Elm_Nstate_Data *pd EINA_UNUSED) +{ + obj = eo_constructor(eo_super(obj, MY_CLASS)); + evas_obj_type_set(obj, MY_CLASS_NAME_LEGACY); + evas_obj_smart_callbacks_descriptions_set(obj, _smart_callbacks); + //TODO: Add ATSPI call here + + return obj; +} + +static void +_next_state_set(Elm_Nstate_Data *sd) +{ + ++sd->state; + if (sd->state == sd->nstate) sd->state = 0; +} + +static void +_state_active(Evas_Object *obj, Elm_Nstate_Data *sd) +{ + char buf[64]; + + sprintf(buf, "elm,state,changed,%d", sd->state); + elm_layout_signal_emit(obj, buf, "elm"); + edje_object_message_signal_process(elm_layout_edje_get(obj)); + elm_obj_layout_sizing_eval(obj); + eo_event_callback_call(obj, ELM_NSTATE_EVENT_STATE_CHANGED, NULL); +} + +static void +_on_state_changed(void *data, + Evas_Object *o EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + efl_ui_nstate_activate(data); +} + +EOLIAN static void +_elm_nstate_evas_object_smart_add(Eo *obj, Elm_Nstate_Data *pd) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + + evas_obj_smart_add(eo_super(obj, MY_CLASS)); + elm_widget_sub_object_parent_add(obj); + + pd->state = 0; + // Default: 2 states + pd->nstate = 2; + + if (!elm_layout_theme_set(obj, "nstate", "base", elm_widget_style_get(obj))) + CRI("Failed to set layout!"); + + edje_object_signal_callback_add(wd->resize_obj, "elm,action,state,changed", + "*", _on_state_changed, obj); +} + +EOLIAN static void +_elm_nstate_evas_object_smart_del(Eo *obj, Elm_Nstate_Data *pd EINA_UNUSED) +{ + evas_obj_smart_del(eo_super(obj, MY_CLASS)); +} + +EOLIAN static int +_elm_nstate_count_get(Eo *obj EINA_UNUSED, Elm_Nstate_Data *pd) +{ + return pd->nstate; +} + +EOLIAN static void +_elm_nstate_count_set(Eo *obj EINA_UNUSED, Elm_Nstate_Data *pd, int nstate) +{ + if (pd->nstate == nstate) return; + + pd->nstate = nstate; + pd->state = 0; +} + +EOLIAN static int +_elm_nstate_value_get(Eo *obj EINA_UNUSED, Elm_Nstate_Data *pd) +{ + return pd->state; +} + +static Eina_Bool +_is_valid_state(Elm_Nstate_Data *sd, int state) +{ + if (sd->state == state || (state < 0 || state >= sd->nstate)) + return EINA_FALSE; + + return EINA_TRUE; +} + +EOLIAN static void +_elm_nstate_value_set(Eo *obj, Elm_Nstate_Data *pd, int state) +{ + if (!_is_valid_state(pd, state)) return; + + pd->state = state; + _state_active(obj, pd); +} + +EOLIAN static Eina_Bool +_elm_nstate_elm_widget_theme_apply(Eo *obj, Elm_Nstate_Data *pd) +{ + Eina_Bool int_ret; + + int_ret = elm_obj_widget_theme_apply(eo_super(obj, MY_CLASS)); + if (!int_ret) return EINA_FALSE; + + _state_active(obj, pd); + + return EINA_TRUE; +} + +static Eina_Bool +_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED) +{ + efl_ui_nstate_activate(obj); + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_nstate_elm_widget_event(Eo *obj, Elm_Nstate_Data *_pd EINA_UNUSED, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + + if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + + if (!_elm_config_key_binding_call(obj, MY_CLASS_NAME, ev, key_actions)) + return EINA_FALSE; + + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + return EINA_TRUE; +} + +EOLIAN static void +_elm_nstate_activate(Eo *obj, Elm_Nstate_Data *_pd) +{ + _next_state_set(_pd); + _state_active(obj, _pd); +} + +EOLIAN static void +_elm_nstate_class_constructor(Eo_Class *klass) +{ + evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass); +} + +EAPI Evas_Object * +elm_nstate_add(Evas_Object *parent) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + Evas_Object *obj = eo_add(MY_CLASS, parent); + return obj; +} + +#include "elm_nstate.eo.c" diff --git a/src/lib/elm_nstate.eo b/src/lib/elm_nstate.eo new file mode 100644 index 000000000..6ff0f89a1 --- /dev/null +++ b/src/lib/elm_nstate.eo @@ -0,0 +1,47 @@ +class Elm.Nstate(Elm.Button) +{ + eo_prefix: efl_ui_nstate; + legacy_prefix: null; + data: Elm_Nstate_Data; + methods { + activate @protected { + } + @property count { + set { + [[Set the maximum number of states. + ]] + } + get { + [[Get the max number of states. + ]] + } + values { + nstate: int; [[The number of states.]] + } + } + @property value { + set { + [[Set the particular state given in (0...nstate}. + ]] + } + get { + [[Get the state value. + ]] + } + values { + state: int; [[The state.]] + } + } + } + implements { + class.constructor; + Eo.Base.constructor; + Evas.Object_Smart.add; + Evas.Object_Smart.del; + Elm.Widget.theme_apply; + Elm.Widget.event; + } + events { + state,changed; + } +} diff --git a/src/lib/elm_nstate.h b/src/lib/elm_nstate.h new file mode 100644 index 000000000..4e35212e3 --- /dev/null +++ b/src/lib/elm_nstate.h @@ -0,0 +1,7 @@ +#ifdef EFL_EO_API_SUPPORT +#include "elm_nstate_eo.h" +#endif +#ifndef EFL_NOLEGACY_API_SUPPORT +#include "elm_nstate_legacy.h" +#endif + diff --git a/src/lib/elm_nstate_eo.h b/src/lib/elm_nstate_eo.h new file mode 100644 index 000000000..a19bb6555 --- /dev/null +++ b/src/lib/elm_nstate_eo.h @@ -0,0 +1 @@ +#include "elm_nstate.eo.h" diff --git a/src/lib/elm_nstate_legacy.h b/src/lib/elm_nstate_legacy.h new file mode 100644 index 000000000..b0df38655 --- /dev/null +++ b/src/lib/elm_nstate_legacy.h @@ -0,0 +1,11 @@ +/** + * @brief Add a new nstate to the parent + * + * @param parent The parent object + * @return The new object or NULL if it cannot be created + * + * @ingroup Nstate + */ +EAPI Evas_Object *elm_nstate_add(Evas_Object *parent); + +#include "elm_nstate.eo.legacy.h" diff --git a/src/lib/elm_widget_check.h b/src/lib/elm_widget_check.h index bcf3eac1f..d5cf27e85 100644 --- a/src/lib/elm_widget_check.h +++ b/src/lib/elm_widget_check.h @@ -26,7 +26,6 @@ typedef struct _Elm_Check_Data Elm_Check_Data; struct _Elm_Check_Data { - Eina_Bool state; Eina_Bool *statep; }; diff --git a/src/lib/elm_widget_nstate.h b/src/lib/elm_widget_nstate.h new file mode 100644 index 000000000..eb9c8f4b8 --- /dev/null +++ b/src/lib/elm_widget_nstate.h @@ -0,0 +1,36 @@ +#include "elm_nstate_eo.h" + +typedef struct +{ + int nstate; + int state; +} Elm_Nstate_Data; + +EAPI void efl_ui_nstate_activate(Elm_Nstate *obj); + + +#define ELM_NSTATE_DATA_GET(o, sd) \ + Elm_Nstate_Data * sd = eo_data_scope_get(o, ELM_NSTATE_CLASS) + +#define ELM_NSTATE_DATA_GET_OR_RETURN(o, ptr) \ + ELM_NSTATE_DATA_GET(o, ptr); \ + if (EINA_UNLIKELY(!ptr)) \ + { \ + CRI("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return; \ + } + +#define ELM_NSTATE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ + ELM_NSTATE_DATA_GET(o, ptr); \ + if (EINA_UNLIKELY(!ptr)) \ + { \ + CRI("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return val; \ + } + +#define ELM_NSTATE_CHECK(obj) \ + if (EINA_UNLIKELY(!eo_isa((obj), ELM_NSTATE_CLASS))) \ + return + -- cgit v1.2.1