From 4c76631b4b9ea891d5e39da9270eb4ea207e3f5e Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Sun, 17 Oct 2010 01:44:57 +0000 Subject: [PATCH] Elementary Magnetslider, a new switcher with "magnet" property This is one more widget whose idea come from Samsung set of contributions to Elementary. SVN revision: 53503 --- legacy/elementary/data/themes/default.edc | 301 +++++++++++ legacy/elementary/src/bin/Makefile.am | 1 + legacy/elementary/src/bin/test.c | 2 + legacy/elementary/src/bin/test_magnetslider.c | 105 ++++ legacy/elementary/src/lib/Elementary.h.in | 27 + legacy/elementary/src/lib/Makefile.am | 1 + legacy/elementary/src/lib/elm_magnetslider.c | 505 ++++++++++++++++++ 7 files changed, 942 insertions(+) create mode 100644 legacy/elementary/src/bin/test_magnetslider.c create mode 100644 legacy/elementary/src/lib/elm_magnetslider.c diff --git a/legacy/elementary/data/themes/default.edc b/legacy/elementary/data/themes/default.edc index 39c94500ed..758ca6e941 100644 --- a/legacy/elementary/data/themes/default.edc +++ b/legacy/elementary/data/themes/default.edc @@ -12753,6 +12753,307 @@ collections { } } +//////////////////////////////////////////////////////////////////////////////// +// magnetslider +//////////////////////////////////////////////////////////////////////////////// + group { name: "elm/magnetslider/base/default"; + + images { + image: "shelf_inset.png" COMP; + image: "ilist_1.png" COMP; + } + + parts { + part { + name: "base"; + mouse_events: 0; + description { + state: "default" 0.0; + max: 99999 30; + min: 150 30; + rel1.offset: 1 1; + rel2.offset: -2 -2; + image { + normal: "ilist_1.png"; + border: 2 2 2 2; + } + fill.smooth: 0; + } + } + part { name: "conf_over"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + image { + normal: "shelf_inset.png"; + border: 7 7 7 7; + middle: 0; + } + fill.smooth : 0; + } + } + part { name: "icon.dragable.area"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + rel1.to: "base"; + rel2.to: "base"; + } + } + part { name: "elm.text.left"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.05 0.5; + min: 1 1; + } + } + } + part { name: "elm.text.center"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.5 0.5; + min: 1 1; + } + } + } + part { name: "elm.text.right"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.95 0.5; + min: 1 1; + } + } + } + part { name: "elm.swallow.icon"; + type: SWALLOW; + mouse_events: 1; + scale: 1; + description { state: "default" 0.0; + min: 64 30; + fixed: 1 1; + align: 0.5 0.5; + rel1.to: "icon.dragable.area"; + rel2 { + relative: 0.0 1.0; + to: "icon.dragable.area"; + } + } + dragable { + confine: "icon.dragable.area"; + x: 1 1 1530; + y: 0 0 0; + } + } + } + } + + group { name: "elm/magnetslider/icon/default"; + alias: "elm/magnetslider/icon/bar"; + + images { + image: "bt_bases.png" COMP; + image: "bt_basew.png" COMP; + image: "bt_hilightw.png" COMP; + } + + parts { + part { name: "button"; + type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + color: 255 255 255 0; + } + } + part { name: "button0"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "button2"; + rel1.offset: -4 -4; + rel2.to: "button2"; + rel2.offset: 3 3; + image { + normal: "bt_bases.png"; + border: 11 11 11 11; + middle: SOLID; + } + color: 255 255 255 128; + } + } + part { name: "button2"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "button"; + rel2.to: "button"; + image { + normal: "bt_basew.png"; + border: 7 7 7 7; + middle: SOLID; + } + color: 255 255 255 210; + } + } + part { name: "button3"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "button2"; + rel2.to: "button2"; + rel2.relative: 1.0 0.5; + image { + normal: "bt_hilightw.png"; + border: 4 4 4 0; + } + color: 255 255 255 190; + } + } + } + } + + group { name: "elm/magnetslider/base/bar"; + + images { + image: "shelf_inset.png" COMP; + image: "ilist_1.png" COMP; + } + + parts { + part { + name: "base"; + mouse_events: 0; + description { + state: "default" 0.0; + max: 99999 30; + min: 150 30; + rel1.offset: 1 1; + rel2.offset: -2 -2; + image { + normal: "ilist_1.png"; + border: 2 2 2 2; + } + fill.smooth: 0; + } + } + part { name: "conf_over"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + image { + normal: "shelf_inset.png"; + border: 7 7 7 7; + middle: 0; + } + fill.smooth : 0; + } + } + part { name: "icon.dragable.area"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + rel1.to: "base"; + rel2.to: "base"; + } + } + part { name: "elm.text.left"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.05 0.5; + min: 1 1; + } + } + } + part { name: "elm.text.center"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.5 0.5; + min: 1 1; + } + } + } + part { name: "elm.text.right"; + type: TEXT; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + text { + font: "Sans,Edje-Vera"; + size: 10; + align: 0.95 0.5; + min: 1 1; + } + } + } + part { name: "bar"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "base"; + rel1.offset: 0 2; + rel2 { + relative: 0 1; + offset: 3 -3; + to_x: "elm.swallow.icon"; + to_y: "base"; + } + color: 0 0 0 180; + } + } + part { name: "elm.swallow.icon"; + type: SWALLOW; + mouse_events: 1; + scale: 1; + description { state: "default" 0.0; + min: 64 30; + fixed: 1 1; + align: 0.5 0.5; + rel1.to: "icon.dragable.area"; + rel2 { + relative: 0.0 1.0; + to: "icon.dragable.area"; + } + } + dragable { + confine: "icon.dragable.area"; + x: 1 1 1530; + y: 0 0 0; + } + } + } + } + /////////////////////////////////////////////////////////////////////////////// group { name: "elm/genlist/item/default/default"; data.item: "stacking" "above"; diff --git a/legacy/elementary/src/bin/Makefile.am b/legacy/elementary/src/bin/Makefile.am index 74ffd45e9e..df6f133db5 100644 --- a/legacy/elementary/src/bin/Makefile.am +++ b/legacy/elementary/src/bin/Makefile.am @@ -54,6 +54,7 @@ test_carousel.c \ test_inwin.c \ test_scaling.c \ test_slider.c \ +test_magnetslider.c \ test_genlist.c \ test_check.c \ test_pager.c \ diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index 14994ea293..551347bd42 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -41,6 +41,7 @@ void test_inwin2(void *data, Evas_Object *obj, void *event_info); void test_scaling(void *data, Evas_Object *obj, void *event_info); void test_scaling2(void *data, Evas_Object *obj, void *event_info); void test_slider(void *data, Evas_Object *obj, void *event_info); +void test_magnetslider(void *data, Evas_Object *obj, void *event_info); void test_genlist(void *data, Evas_Object *obj, void *event_info); void test_genlist2(void *data, Evas_Object *obj, void *event_info); void test_genlist3(void *data, Evas_Object *obj, void *event_info); @@ -256,6 +257,7 @@ my_win_main(char *autorun) ADD_TEST("Scaling", test_scaling); ADD_TEST("Scaling 2", test_scaling2); ADD_TEST("Slider", test_slider); + ADD_TEST("Magnetslider", test_magnetslider); ADD_TEST("Genlist", test_genlist); ADD_TEST("Genlist 2", test_genlist2); ADD_TEST("Genlist 3", test_genlist3); diff --git a/legacy/elementary/src/bin/test_magnetslider.c b/legacy/elementary/src/bin/test_magnetslider.c new file mode 100644 index 0000000000..c106bf26be --- /dev/null +++ b/legacy/elementary/src/bin/test_magnetslider.c @@ -0,0 +1,105 @@ +#include +#ifndef ELM_LIB_QUICKLAUNCH + +static void _pos_selected_cb(void *data, Evas_Object *obj, void *event_info) +{ + printf("Selection: %s\n", (char *)event_info); + printf("Label selected: %s\n", elm_magnetslider_selected_label_get(obj)); +} + +static void +_position_change_magnetic_cb(void *data, Evas_Object * obj, void *event_info) +{ + if (!strcmp((char *)event_info, "left")) + elm_magnetslider_magnet_pos_set(obj, ELM_MAGNETSLIDER_LEFT); + else if (!strcmp((char *)event_info, "right")) + elm_magnetslider_magnet_pos_set(obj, ELM_MAGNETSLIDER_RIGHT); +} + +void +test_magnetslider(void *data, Evas_Object * obj, void *event_info) +{ + Evas_Object *win, *bg, *bx, *ms; + + win = elm_win_add(NULL, "magnetslider", ELM_WIN_BASIC); + elm_win_title_set(win, "Magnetslider"); + elm_win_autodel_set(win, 1); + + 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); + + 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); + + ms = elm_magnetslider_add(win); + evas_object_size_hint_weight_set(ms, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ms, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_magnetslider_indicator_pos_set(ms, ELM_MAGNETSLIDER_RIGHT); + elm_magnetslider_magnet_pos_set(ms, ELM_MAGNETSLIDER_RIGHT); + elm_magnetslider_labels_set(ms, "Snooze", NULL, "Stop"); + elm_magnetslider_enabled_pos_set(ms, ELM_MAGNETSLIDER_LEFT | + ELM_MAGNETSLIDER_RIGHT); + evas_object_smart_callback_add(ms, "pos_changed", + _position_change_magnetic_cb, NULL); + evas_object_smart_callback_add(ms, "selected", _pos_selected_cb, NULL); + evas_object_show(ms); + elm_box_pack_end(bx, ms); + + ms = elm_magnetslider_add(win); + evas_object_size_hint_weight_set(ms, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ms, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_magnetslider_indicator_pos_set(ms, ELM_MAGNETSLIDER_CENTER); + elm_magnetslider_magnet_pos_set(ms, ELM_MAGNETSLIDER_CENTER); + elm_magnetslider_labels_set(ms, "Snooze", NULL, "Stop"); + elm_magnetslider_enabled_pos_set(ms, ELM_MAGNETSLIDER_LEFT | + ELM_MAGNETSLIDER_RIGHT); + evas_object_smart_callback_add(ms, "selected", _pos_selected_cb, NULL); + evas_object_show(ms); + elm_box_pack_end(bx, ms); + + ms = elm_magnetslider_add(win); + elm_object_style_set(ms, "bar"); + evas_object_size_hint_weight_set(ms, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ms, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_magnetslider_indicator_pos_set(ms, ELM_MAGNETSLIDER_LEFT); + elm_magnetslider_magnet_pos_set(ms, ELM_MAGNETSLIDER_CENTER| + ELM_MAGNETSLIDER_RIGHT); + elm_magnetslider_enabled_pos_set(ms, ELM_MAGNETSLIDER_CENTER | + ELM_MAGNETSLIDER_RIGHT); + elm_magnetslider_labels_set(ms, NULL, "Accept", "Reject"); + evas_object_smart_callback_add(ms, "selected", _pos_selected_cb, NULL); + evas_object_show(ms); + elm_box_pack_end(bx, ms); + + ms = elm_magnetslider_add(win); + elm_object_style_set(ms, "bar"); + evas_object_size_hint_weight_set(ms, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ms, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_magnetslider_indicator_pos_set(ms, ELM_MAGNETSLIDER_LEFT); + elm_magnetslider_magnet_pos_set(ms, ELM_MAGNETSLIDER_LEFT); + elm_magnetslider_labels_set(ms, NULL, "Accept", "Reject"); + evas_object_smart_callback_add(ms, "pos_changed", + _position_change_magnetic_cb, NULL); + evas_object_smart_callback_add(ms, "selected", _pos_selected_cb, NULL); + evas_object_show(ms); + elm_box_pack_end(bx, ms); + + + ms = elm_magnetslider_add(win); + evas_object_size_hint_weight_set(ms, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ms, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_magnetslider_indicator_pos_set(ms, ELM_MAGNETSLIDER_LEFT); + elm_magnetslider_magnet_pos_set(ms, ELM_MAGNETSLIDER_ALL); + elm_magnetslider_labels_set(ms, "Left", "Center", "Right"); + evas_object_smart_callback_add(ms, "selected", _pos_selected_cb, NULL); + evas_object_show(ms); + elm_box_pack_end(bx, ms); + + evas_object_resize(win, 320, 400); + evas_object_show(win); +} +#endif diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index d1e22a5870..b175587072 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -1357,6 +1357,33 @@ extern "C" { EAPI void elm_slider_indicator_show_set(Evas_Object *obj, Eina_Bool show); EAPI Eina_Bool elm_slider_indicator_show_get(const Evas_Object *obj); + /* magnetslider */ + typedef enum _Elm_Magnetslider_Pos + { + ELM_MAGNETSLIDER_NONE = 0, + ELM_MAGNETSLIDER_LEFT = 1 << 0, + ELM_MAGNETSLIDER_CENTER = 1 << 1, + ELM_MAGNETSLIDER_RIGHT = 1 << 2, + ELM_MAGNETSLIDER_ALL = (1 << 3) -1 + } Elm_Magnetslider_Pos; + + EAPI Evas_Object *elm_magnetslider_add(Evas_Object *parent); + EAPI void elm_magnetslider_labels_set(Evas_Object *obj, const char *left_label, const char *center_label, const char *right_label); + EAPI void elm_magnetslider_labels_get(const Evas_Object *obj, const char **left_label, const char **center_label, const char **right_label); + EAPI const char *elm_magnetslider_selected_label_get(const Evas_Object *obj); + EAPI void elm_magnetslider_indicator_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos); + EAPI Elm_Magnetslider_Pos elm_magnetslider_indicator_pos_get(const Evas_Object *obj); + EAPI void elm_magnetslider_magnet_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos); + EAPI Elm_Magnetslider_Pos elm_magnetslider_magnet_pos_get(const Evas_Object *obj); + EAPI void elm_magnetslider_enabled_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos); + EAPI Elm_Magnetslider_Pos elm_magnetslider_enabled_pos_get(const Evas_Object *obj); + /* smart callbacks called: + * "selected" - when user selects a position (the label is passed as + * event info)". + * "pos_changed" - when a button reaches to the special position like + * "left", "right" and "center". + */ + typedef enum _Elm_Genlist_Item_Flags { ELM_GENLIST_ITEM_NONE = 0, diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index 8f9acb4639..3b58af55b1 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -60,6 +60,7 @@ elm_toolbar.c \ elm_list.c \ elm_carousel.c \ elm_slider.c \ +elm_magnetslider.c \ elm_genlist.c \ elm_check.c \ elm_radio.c \ diff --git a/legacy/elementary/src/lib/elm_magnetslider.c b/legacy/elementary/src/lib/elm_magnetslider.c new file mode 100644 index 0000000000..2e086c3b3c --- /dev/null +++ b/legacy/elementary/src/lib/elm_magnetslider.c @@ -0,0 +1,505 @@ +/** + * @addtogroup Magnetslider Magnetslider + * + * A magnet slider is a switcher for 3 labels with customizable + * magnet properties. When the position is set with magnet, the knob + * will be moved to it if it's nearest the magnetized position. + * + * Signals emmitted: + * "selected" - when user selects a position (the label is passed as + * event info)". + * "pos_changed" - when a button reaches to the special position like + * "left", "right" and "center". + */ + +#include +#include +#include "elm_priv.h" + +typedef struct _Widget_Data Widget_Data; + +struct _Widget_Data +{ + Evas_Object *ms; // magnetslider + Evas_Object *icon; // an icon for a button or a bar + Elm_Magnetslider_Pos magnet_position, enabled_position; + const char *text_left, *text_right, *text_center; + Ecore_Animator *icon_animator; + double final_position; + Eina_Bool mouse_down : 1; +}; + +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 _icon_down_cb(void *data, Evas *e, + Evas_Object *obj, void *event_info); +static void _icon_move_cb(void *data, Evas *e, + Evas_Object *obj, void *event_info); +static void _icon_up_cb(void *data, Evas *e, + Evas_Object *obj, void *event_info); +static Eina_Bool _icon_animation(void *data); + +#define SIG_CHANGED "pos_changed" +#define SIG_SELECTED "selected" + +static const Evas_Smart_Cb_Description _signals[] = +{ + {SIG_CHANGED, ""}, + {SIG_SELECTED, ""}, + {NULL, NULL} +}; + + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + 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); + free(wd); +} + +static void +_theme_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (!edje_object_part_swallow_get(wd->ms, "elm.swallow.icon")) + edje_object_part_unswallow(wd->ms, wd->icon); + + _elm_theme_object_set(obj, wd->ms, "magnetslider", + "base", elm_widget_style_get(obj)); + _elm_theme_object_set(obj, wd->icon, "magnetslider", + "icon", elm_widget_style_get(obj)); + edje_object_part_swallow(wd->ms, "elm.swallow.icon", wd->icon); + edje_object_part_text_set(wd->ms, "elm.text.left", wd->text_left); + edje_object_part_text_set(wd->ms, "elm.text.right", wd->text_right); + edje_object_part_text_set(wd->ms, "elm.text.center", wd->text_center); + edje_object_message_signal_process(wd->ms); + _sizing_eval(obj); +} + +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(4, &minw, 1, &minh); + edje_object_size_min_restricted_calc(wd->ms, &minw, &minh, minw, minh); + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, -1, -1); +} + +static void +_icon_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get((Evas_Object *) data); + if (!wd) return; + wd->mouse_down = EINA_TRUE; +} + +static void +_icon_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *as = (Evas_Object *) data; + Widget_Data *wd = elm_widget_data_get(as); + double pos = 0.0; + if (!wd) return; + + if (!wd->mouse_down) return; + edje_object_part_drag_value_get(wd->ms, "elm.swallow.icon", &pos, NULL); + if (pos == 0.0) + evas_object_smart_callback_call(as, SIG_CHANGED, "left"); + else if (pos == 1.0) + evas_object_smart_callback_call(as, SIG_CHANGED, "right"); + else if (pos >= 0.45 && pos <= 0.55) + evas_object_smart_callback_call(as, SIG_CHANGED, "center"); +} + +static void +_icon_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(data); + double position = 0.0; + if (!wd) return; + + wd->mouse_down = EINA_FALSE; + + edje_object_part_drag_value_get(wd->ms, "elm.swallow.icon", + &position, NULL); + + if (position == 0.0 && (wd->enabled_position & ELM_MAGNETSLIDER_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 && + (wd->enabled_position & ELM_MAGNETSLIDER_CENTER)) + { + wd->final_position = 0.5; + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_center); + return; + } + if (position == 1.0 && (wd->enabled_position & ELM_MAGNETSLIDER_RIGHT)) + { + wd->final_position = 1; + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_right); + return; + } + + if (!wd->magnet_position) + { + wd->final_position = 0; + goto as_anim; + } + + if (position < 0.3) + { + if (wd->magnet_position & ELM_MAGNETSLIDER_LEFT) + wd->final_position = 0; + else if (wd->magnet_position & ELM_MAGNETSLIDER_CENTER) + wd->final_position = 0.5; + else if (wd->magnet_position & ELM_MAGNETSLIDER_RIGHT) + wd->final_position = 1; + } + else if ((position >= 0.3) && (position <= 0.7)) + { + if (wd->magnet_position & ELM_MAGNETSLIDER_CENTER) + wd->final_position = 0.5; + else if (position < 0.5) + { + if (wd->magnet_position & ELM_MAGNETSLIDER_LEFT) + wd->final_position = 0; + else + wd->final_position = 1; + } + else + { + if (wd->magnet_position & ELM_MAGNETSLIDER_RIGHT) + wd->final_position = 1; + else + wd->final_position = 0; + } + } + else + { + if (wd->magnet_position & ELM_MAGNETSLIDER_RIGHT) + wd->final_position = 1; + else if (wd->magnet_position & ELM_MAGNETSLIDER_CENTER) + wd->final_position = 0.5; + else + wd->final_position = 0; + } +as_anim: + wd->icon_animator = ecore_animator_add(_icon_animation, data); +} + +static Eina_Bool +_icon_animation(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + double cur_position = 0.0, new_position = 0.0; + double move_amount = 0.05; + Eina_Bool flag_finish_animation = EINA_FALSE; + if (!wd) return EINA_FALSE; + + edje_object_part_drag_value_get(wd->ms, + "elm.swallow.icon", &cur_position, NULL); + if ((wd->final_position == 0.0) || + (wd->final_position == 0.5 && cur_position >= wd->final_position)) + { + new_position = cur_position - move_amount; + if (new_position <= wd->final_position) + { + new_position = wd->final_position; + flag_finish_animation = EINA_TRUE; + } + } + else if ((wd->final_position == 1.0) || + (wd->final_position == 0.5 && cur_position < wd->final_position)) + { + new_position = cur_position + move_amount; + if (new_position >= wd->final_position) + { + new_position = wd->final_position; + flag_finish_animation = EINA_TRUE; + } + } + edje_object_part_drag_value_set(wd->ms, + "elm.swallow.icon", new_position, 0.5); + if (flag_finish_animation) + { + if ((wd->final_position == 0) && + (wd->enabled_position & ELM_MAGNETSLIDER_LEFT)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_left); + else if ((wd->final_position == 0.5) && + (wd->enabled_position & ELM_MAGNETSLIDER_CENTER)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_center); + else if ((wd->final_position == 1) && + (wd->enabled_position & ELM_MAGNETSLIDER_RIGHT)) + evas_object_smart_callback_call(data, SIG_SELECTED, + (void *)wd->text_right); + return EINA_FALSE; + } + return EINA_TRUE; +} + +/** + * Add a new magnetslider to the parent. + * + * @param parent The parent object + * @return The new magnetslider object or NULL if it cannot be created + * + * @ingroup Magnetslider + */ +EAPI Evas_Object * +elm_magnetslider_add(Evas_Object *parent) +{ + Evas_Object *obj; + Widget_Data *wd; + Evas *e; + + wd = ELM_NEW(Widget_Data); + e = evas_object_evas_get(parent); + obj = elm_widget_add(e); + ELM_SET_WIDTYPE(widtype, "magnetslider"); + elm_widget_type_set(obj, "magnetslider"); + 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); + + wd->mouse_down = EINA_FALSE; + wd->enabled_position = ELM_MAGNETSLIDER_ALL; + + wd->ms = edje_object_add(e); + _elm_theme_object_set(obj, wd->ms, "magnetslider", "base", "default"); + elm_widget_resize_object_set(obj, wd->ms); + + wd->icon = edje_object_add(e); + elm_widget_sub_object_add(obj, wd->icon); + _elm_theme_object_set(obj, wd->icon, "magnetslider", "icon", "default"); + edje_object_part_swallow(wd->ms, "elm.swallow.icon", wd->icon); + + evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_DOWN, + _icon_down_cb, obj); + evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_MOVE, + _icon_move_cb, obj); + evas_object_event_callback_add(wd->icon, EVAS_CALLBACK_MOUSE_UP, + _icon_up_cb, obj); + + evas_object_smart_callbacks_descriptions_set(obj, _signals); + _sizing_eval(obj); + return obj; +} + +/** + * Set magnetslider indicator position. + * + * @param obj The magnetslider object. + * @param pos The position of the indicator. + * + * @ingroup Magnetslider + */ +EAPI void +elm_magnetslider_indicator_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + double position = 0.0; + if (!wd) return; + if (pos == ELM_MAGNETSLIDER_CENTER) position = 0.5; + else if (pos == ELM_MAGNETSLIDER_RIGHT) position = 1.0; + edje_object_part_drag_value_set(wd->ms, "elm.swallow.icon", position, 0.5); +} + +/** + * Get magnetslider indicator position. + * + * @param obj The magnetslider object. + * @return The position of the indicator. + * + * @ingroup Magnetslider + */ +EAPI Elm_Magnetslider_Pos +elm_magnetslider_indicator_pos_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAGNETSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + double position; + if (!wd) return ELM_MAGNETSLIDER_NONE; + + edje_object_part_drag_value_get(wd->ms, "elm.swallow.icon", &position, NULL); + if (position < 0.3) + return ELM_MAGNETSLIDER_LEFT; + else if (position < 0.7) + return ELM_MAGNETSLIDER_CENTER; + else + return ELM_MAGNETSLIDER_RIGHT; +} + +/** + * Set magnetslider magnet position. + * + * @param obj The magnetslider object. + * @param pos Bit mask indicating the magnet positions. + * Example: use (ELM_MAGNETSLIDER_LEFT | ELM_MAGNETSLIDER_RIGHT) + * to put magnet property on both positions + * + * @ingroup Magnetslider + */ +EAPI void +elm_magnetslider_magnet_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->magnet_position = pos; +} + +/** + * Get magnetslider magnet position. + * + * @param obj The magnetslider object. + * @return The positions with magnet property. + * + * @ingroup Magnetslider + */ +EAPI Elm_Magnetslider_Pos +elm_magnetslider_magnet_pos_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAGNETSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_MAGNETSLIDER_NONE; + return wd->magnet_position; +} + +/** + * Set magnetslider enabled position. + * + * All the positions are enabled by default. + * + * @param obj The magnetslider object. + * @param pos Bit mask indicating the enabled positions. + * Example: use (ELM_MAGNETSLIDER_LEFT | ELM_MAGNETSLIDER_RIGHT) + * to enable both positions, so the user can select it. + * + * @ingroup Magnetslider + */ +EAPI void +elm_magnetslider_enabled_pos_set(Evas_Object *obj, Elm_Magnetslider_Pos pos) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->enabled_position = pos; +} + +/** + * Get magnetslider enabled position. + * + * All the positions are enabled by default. + * + * @param obj The magnetslider object. + * @return The enabled positions. + * + * @ingroup Magnetslider + */ +EAPI Elm_Magnetslider_Pos +elm_magnetslider_enabled_pos_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAGNETSLIDER_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_MAGNETSLIDER_NONE; + return wd->enabled_position; +} + +/** + * Set magnetslider labels. + * + * @param obj The magnetslider object + * @param left_label The label which is going to be set. + * @param center_label The label which is going to be set. + * @param right_label The label which is going to be set. + * + * @ingroup Magnetslider + */ +EAPI void +elm_magnetslider_labels_set(Evas_Object *obj, const char *left_label, const char *center_label, const char *right_label) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + eina_stringshare_replace(&wd->text_left, left_label); + edje_object_part_text_set(wd->ms, "elm.text.left", left_label); + eina_stringshare_replace(&wd->text_center, center_label); + edje_object_part_text_set(wd->ms, "elm.text.center", center_label); + eina_stringshare_replace(&wd->text_right, right_label); + edje_object_part_text_set(wd->ms, "elm.text.right", right_label); +} + +/** + * Get magnetslider labels. + * + * @param obj The magnetslider object + * @param left_label A char** to place the left_label of @p obj into + * @param center_label A char** to place the center_label of @p obj into + * @param right_label A char** to place the right_label of @p obj into + * + * @ingroup Magnetslider + */ +EAPI void +elm_magnetslider_labels_get(const Evas_Object *obj, const char **left_label, const char **center_label, const char **right_label) +{ + if (left_label) *left_label= NULL; + if (center_label) *center_label= NULL; + if (right_label) *right_label= NULL; + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (left_label) *left_label = wd->text_left; + if (center_label) *center_label = wd->text_center; + if (right_label) *right_label = wd->text_right; +} + +/** + * Get magnetslider selected label. + * + * @param obj The magnetslider object + * @return The selected label + * + * @ingroup Magnetslider + */ +EAPI const char * +elm_magnetslider_selected_label_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return NULL; + + if ((wd->final_position == 0.0) && + (wd->enabled_position & ELM_MAGNETSLIDER_LEFT)) + return wd->text_left; + + if ((wd->final_position == 0.5) && + (wd->enabled_position & ELM_MAGNETSLIDER_CENTER)) + return wd->text_center; + + if ((wd->final_position == 1.0) && + (wd->enabled_position & ELM_MAGNETSLIDER_RIGHT)) + return wd->text_right; + + return NULL; +}