From 0856f621caf920de54801688758503d52b328b56 Mon Sep 17 00:00:00 2001 From: raster Date: Thu, 23 Jun 2011 08:52:51 +0000 Subject: [PATCH] genscroller++. just stubs right now. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@60625 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- data/themes/default.edc | 1 + src/bin/Makefile.am | 3 +- src/bin/test.c | 2 + src/bin/test_genscroller.c | 36 ++++ src/lib/Elementary.h.in | 3 + src/lib/Makefile.am | 1 + src/lib/elm_genscroller.c | 523 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 src/bin/test_genscroller.c create mode 100644 src/lib/elm_genscroller.c diff --git a/data/themes/default.edc b/data/themes/default.edc index 7870254..e2f5471 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -319,6 +319,7 @@ collections { alias: "elm/carousel/base/default"; alias: "elm/gengrid/base/default"; alias: "elm/scroller/base/map_bubble"; + alias: "elm/genscroller/base/default"; data { item: "focus_highlight" "on"; diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 229592a..287e470 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -66,6 +66,7 @@ test_focus3.c \ test_focus.c \ test_gengrid.c \ test_genlist.c \ +test_genscroller.c \ test_glview_simple.c \ test_glview.c \ test_grid.c \ @@ -106,7 +107,7 @@ test_tooltip.c \ test_transit.c \ test_weather.c \ test_win_inline.c \ -test_win_state.c +test_win_state.c if HAVE_EIO elementary_test_SOURCES += test_eio.c diff --git a/src/bin/test.c b/src/bin/test.c index 34eaaa9..760c789 100644 --- a/src/bin/test.c +++ b/src/bin/test.c @@ -70,6 +70,7 @@ void test_genlist8(void *data, Evas_Object *obj, void *event_info); void test_genlist9(void *data, Evas_Object *obj, void *event_info); void test_genlist10(void *data, Evas_Object *obj, void *event_info); void test_genlist11(void *data, Evas_Object *obj, void *event_info); +void test_genscroller(void *data, Evas_Object *obj, void *event_info); void test_table(void *data, Evas_Object *obj, void *event_info); void test_table2(void *data, Evas_Object *obj, void *event_info); void test_table3(void *data, Evas_Object *obj, void *event_info); @@ -412,6 +413,7 @@ my_win_main(char *autorun) ADD_TEST("GLViewSimple", test_glview_simple); ADD_TEST("GLView", test_glview); ADD_TEST("3D", test_3d); + ADD_TEST("Genscroller", test_genscroller); #undef ADD_TEST if (autorun) diff --git a/src/bin/test_genscroller.c b/src/bin/test_genscroller.c new file mode 100644 index 0000000..e71bb0d --- /dev/null +++ b/src/bin/test_genscroller.c @@ -0,0 +1,36 @@ +#include +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#ifndef ELM_LIB_QUICKLAUNCH + +void +test_genscroller(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *win, *bg, *gl, *bx; + + win = elm_win_add(NULL, "genscroller", ELM_WIN_BASIC); + elm_win_title_set(win, "Genscroller"); + 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); + + gl = elm_genscroller_add(win); + elm_genscroller_world_size_set(gl, 2000, 2000); + evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(bx, gl); + evas_object_show(gl); + + evas_object_resize(win, 480, 800); + evas_object_show(win); +} +#endif diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index 1a32fa8..c734d33 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -5672,6 +5672,9 @@ EAPI Elm_Genlist_Item *elm_genlist_item_sorted_insert(Evas_Object *obj, const El EAPI void elm_grid_pack_set(Evas_Object *subobj, int x, int y, int w, int h); EAPI void elm_grid_pack_get(Evas_Object *subobj, int *x, int *y, int *w, int *h); + EAPI Evas_Object *elm_genscroller_add(Evas_Object *parent); + EAPI void elm_genscroller_world_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h); + #ifdef __cplusplus } #endif diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index e02f62b..dbfee07 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -67,6 +67,7 @@ elm_font.c \ elm_frame.c \ elm_gengrid.c \ elm_genlist.c \ +elm_genscroller.c \ elm_glview.c \ elm_grid.c \ elm_hover.c \ diff --git a/src/lib/elm_genscroller.c b/src/lib/elm_genscroller.c new file mode 100644 index 0000000..839e101 --- /dev/null +++ b/src/lib/elm_genscroller.c @@ -0,0 +1,523 @@ +#include +#include +#include "elm_priv.h" + +/** + * @defgroup Genscroller Genscroller + * + */ + +typedef struct _Widget_Data Widget_Data; +typedef struct _Pan Pan; + +struct _Widget_Data +{ + Evas_Object *obj, *scr, *pan_smart; + Pan *pan; + Evas_Coord pan_x, pan_y, minw, minh; +}; + +struct _Pan +{ + Evas_Object_Smart_Clipped_Data __clipped_data; + Widget_Data *wd; +}; + +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 _show_region_hook(void *data, + 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); +static void _signal_emit_hook(Evas_Object *obj, + const char *emission, + const char *source); +static void _pan_calculate(Evas_Object *obj); + +static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION; + +static const char SIG_SCROLL_EDGE_TOP[] = "scroll,edge,top"; +static const char SIG_SCROLL_EDGE_BOTTOM[] = "scroll,edge,bottom"; +static const char SIG_SCROLL_EDGE_LEFT[] = "scroll,edge,left"; +static const char SIG_SCROLL_EDGE_RIGHT[] = "scroll,edge,right"; + +static const Evas_Smart_Cb_Description _signals[] = { + {SIG_SCROLL_EDGE_TOP, ""}, + {SIG_SCROLL_EDGE_BOTTOM, ""}, + {SIG_SCROLL_EDGE_LEFT, ""}, + {SIG_SCROLL_EDGE_RIGHT, ""}, + {NULL, NULL} +}; + +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; + 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; + + Evas_Coord x = 0; + Evas_Coord y = 0; + Evas_Coord step_x = 0; + Evas_Coord step_y = 0; + Evas_Coord v_w = 0; + Evas_Coord v_h = 0; + Evas_Coord page_x = 0; + Evas_Coord page_y = 0; + + elm_smart_scroller_child_pos_get(wd->scr, &x, &y); + elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y); + elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y); + elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h); + + if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left"))) + { + x -= step_x; + } + else if ((!strcmp(ev->keyname, "Right")) || + (!strcmp(ev->keyname, "KP_Right"))) + { + x += step_x; + } + else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up"))) + { + y -= step_y; + } + else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down"))) + { + y += step_y; + } + else return EINA_FALSE; + + ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; + elm_smart_scroller_child_pos_set(wd->scr, x, y); + return EINA_TRUE; +} + +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_object_signal_emit(wd->obj, "elm,action,focus", "elm"); + evas_object_focus_set(wd->obj, EINA_TRUE); + } + else + { + elm_object_signal_emit(wd->obj, "elm,action,unfocus", "elm"); + evas_object_focus_set(wd->obj, EINA_FALSE); + } +} + +static void +_del_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + free(wd); +} + +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + evas_object_del(wd->pan_smart); + wd->pan_smart = NULL; +} + +static void +_mirrored_set(Evas_Object *obj, + Eina_Bool rtl) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_mirrored_set(wd->scr, 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(wd->obj)); + _elm_widget_mirrored_reload(obj); + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + elm_smart_scroller_object_theme_set(obj, wd->scr, "genscroller", "base", + elm_widget_style_get(obj)); + edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale); + _sizing_eval(obj); + evas_event_thaw(evas_object_evas_get(wd->obj)); + evas_event_thaw_eval(evas_object_evas_get(wd->obj)); +} + +static void +_show_region_hook(void *data, + Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(data); + Evas_Coord x, y, w, h; + if (!wd) return; + elm_widget_show_region_get(obj, &x, &y, &w, &h); + //x & y are screen coordinates, Add with pan coordinates + x += wd->pan_x; + y += wd->pan_y; + elm_smart_scroller_child_region_show(wd->scr, x, y, w, h); +} + +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 vmw, vmh; + if (!wd) return; + evas_object_size_hint_min_get(wd->scr, &minw, &minh); + evas_object_size_hint_max_get(wd->scr, &maxw, &maxh); + edje_object_size_min_calc + (elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh); + minw = vmw; + minh = vmh; + evas_object_size_hint_min_set(obj, minw, minh); + evas_object_size_hint_max_set(obj, maxw, maxh); +} + +static void +_signal_emit_hook(Evas_Object *obj, + const char *emission, + const char *source) +{ + Widget_Data *wd = elm_widget_data_get(obj); + edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), + emission, source); +} + +static void +_pan_set(Evas_Object *obj, + Evas_Coord x, + Evas_Coord y) +{ + Pan *sd = evas_object_smart_data_get(obj); + + if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return; + sd->wd->pan_x = x; + sd->wd->pan_y = y; + // FIXME: pan virtual scroll pos set + printf("PAN SET: %i %i\n", x, y); +} + +static void +_pan_get(Evas_Object *obj, + Evas_Coord *x, + Evas_Coord *y) +{ + Pan *sd = evas_object_smart_data_get(obj); + + if (x) *x = sd->wd->pan_x; + if (y) *y = sd->wd->pan_y; +} + +static void +_pan_max_get(Evas_Object *obj, + Evas_Coord *x, + Evas_Coord *y) +{ + Pan *sd = evas_object_smart_data_get(obj); + Evas_Coord ow, oh; + + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + ow = sd->wd->minw - ow; + if (ow < 0) ow = 0; + oh = sd->wd->minh - oh; + if (oh < 0) oh = 0; + if (x) *x = ow; + if (y) *y = oh; +} + +static void +_pan_min_get(Evas_Object *obj __UNUSED__, + Evas_Coord *x, + Evas_Coord *y) +{ + if (x) *x = 0; + if (y) *y = 0; +} + +static void +_pan_child_size_get(Evas_Object *obj, + Evas_Coord *w, + Evas_Coord *h) +{ + Pan *sd = evas_object_smart_data_get(obj); + + if (w) *w = sd->wd->minw; + if (h) *h = sd->wd->minh; +} + +static void +_pan_add(Evas_Object *obj) +{ + Pan *sd; + Evas_Object_Smart_Clipped_Data *cd; + + _pan_sc.add(obj); + cd = evas_object_smart_data_get(obj); + sd = ELM_NEW(Pan); + if (!sd) return; + sd->__clipped_data = *cd; + free(cd); + evas_object_smart_data_set(obj, sd); +} + +static void +_pan_del(Evas_Object *obj) +{ + Pan *sd = evas_object_smart_data_get(obj); + + if (!sd) return; + _pan_sc.del(obj); +} + +static void +_pan_resize(Evas_Object *obj, + Evas_Coord w, + Evas_Coord h) +{ +// Pan *sd = evas_object_smart_data_get(obj); + Evas_Coord ow, oh; + + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + if ((ow == w) && (oh == h)) return; + // FIXME: pan resized + printf("PAN SIZE: %i %i\n", w, h); +} + +static void +_pan_calculate(Evas_Object *obj) +{ +// Pan *sd = evas_object_smart_data_get(obj); + Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh; + + evas_event_freeze(evas_object_evas_get(obj)); + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh); + // FIXME: move/resize/show/realize/unrealize stuff + printf("PAN CALC\n"); + evas_event_thaw(evas_object_evas_get(obj)); + evas_event_thaw_eval(evas_object_evas_get(obj)); +} + +static void +_pan_move(Evas_Object *obj __UNUSED__, + Evas_Coord x, + Evas_Coord y) +{ +// Pan *sd = evas_object_smart_data_get(obj); + // FIXME: pan moved + printf("PAN MOVE: %i %i\n", x, y); +} + +static void +_hold_on(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_hold_set(wd->scr, 1); +} + +static void +_hold_off(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_hold_set(wd->scr, 0); +} + +static void +_freeze_on(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_freeze_set(wd->scr, 1); +} + +static void +_freeze_off(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_smart_scroller_freeze_set(wd->scr, 0); +} + +static void +_scroll_edge_left(void *data, + Evas_Object *scr __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *obj = data; + evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_LEFT, NULL); +} + +static void +_scroll_edge_right(void *data, + Evas_Object *scr __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *obj = data; + evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_RIGHT, NULL); +} + +static void +_scroll_edge_top(void *data, + Evas_Object *scr __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *obj = data; + evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_TOP, NULL); +} + +static void +_scroll_edge_bottom(void *data, + Evas_Object *scr __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *obj = data; + evas_object_smart_callback_call(obj, SIG_SCROLL_EDGE_BOTTOM, NULL); +} + +/** + * Add a new Genscroller object + * + * @param parent The parent object + * @return The new object or NULL if it cannot be created + * + * @ingroup Genscroller + */ +EAPI Evas_Object * +elm_genscroller_add(Evas_Object *parent) +{ + Evas_Object *obj; + Evas *e; + Widget_Data *wd; + Evas_Coord minw, minh; + static Evas_Smart *smart = NULL; + + if (!smart) + { + static Evas_Smart_Class sc; + + evas_object_smart_clipped_smart_set(&_pan_sc); + sc = _pan_sc; + sc.name = "elm_genscroller_pan"; + sc.version = EVAS_SMART_CLASS_VERSION; + sc.add = _pan_add; + sc.del = _pan_del; + sc.resize = _pan_resize; + sc.move = _pan_move; + sc.calculate = _pan_calculate; + if (!(smart = evas_smart_class_new(&sc))) return NULL; + } + + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); + + ELM_SET_WIDTYPE(widtype, "genscroller"); + elm_widget_type_set(obj, "genscroller"); + elm_widget_sub_object_add(parent, obj); + elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); + elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); + 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_can_focus_set(obj, EINA_TRUE); + elm_widget_event_hook_set(obj, _event_hook); + elm_widget_on_show_region_hook_set(obj, _show_region_hook, obj); + + wd->scr = elm_smart_scroller_add(e); + elm_smart_scroller_widget_set(wd->scr, obj); + elm_smart_scroller_object_theme_set(obj, wd->scr, "genscroller", "base", + elm_widget_style_get(obj)); + elm_smart_scroller_bounce_allow_set(wd->scr, + _elm_config->thumbscroll_bounce_enable, + _elm_config->thumbscroll_bounce_enable); + elm_widget_resize_object_set(obj, wd->scr); + + evas_object_smart_callback_add(wd->scr, "edge,left", _scroll_edge_left, obj); + evas_object_smart_callback_add(wd->scr, "edge,right", _scroll_edge_right, + obj); + evas_object_smart_callback_add(wd->scr, "edge,top", _scroll_edge_top, obj); + evas_object_smart_callback_add(wd->scr, "edge,bottom", _scroll_edge_bottom, + obj); + + wd->obj = obj; + + evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); + evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj); + evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj); + evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj); + + wd->pan_smart = evas_object_smart_add(e, smart); + wd->pan = evas_object_smart_data_get(wd->pan_smart); + wd->pan->wd = wd; + + elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart, + _pan_set, _pan_get, _pan_max_get, + _pan_min_get, _pan_child_size_get); + + edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), + &minw, &minh); + evas_object_size_hint_min_set(obj, minw, minh); + + evas_object_smart_callbacks_descriptions_set(obj, _signals); + + _mirrored_set(obj, elm_widget_mirrored_get(obj)); + _sizing_eval(obj); + return obj; +} + +/** + * XXX + * + * xxx + * + * @param obj The genlist object + * + * @ingroup Genscroller + */ +EAPI void +elm_genscroller_world_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->minw = w; + wd->minh = h; + evas_object_smart_callback_call(wd->pan_smart, "changed", NULL); + _sizing_eval(wd->obj); + evas_object_smart_changed(wd->pan_smart); +} -- 2.7.4