1. fix box as it didnt hide clipper when it gets empty

2. add bouncing at ends for scroller and config for it
3. fix quicklaunch to be cserver-freidnly thanks to its fork tricks
4. add signals to scroller when scrolling and hitting edges
5. pants.



SVN revision: 40549
This commit is contained in:
Carsten Haitzler 2009-05-08 11:27:32 +00:00
parent e74b5f1cb7
commit 5c7e2ec144
13 changed files with 566 additions and 65 deletions

View File

@ -1129,6 +1129,40 @@ my_anchorblock_anchor(void *data, Evas_Object *obj, void *event_info)
}
}
static void
my_anchorblock_edge_left(void *data, Evas_Object *obj, void *event_info)
{
printf("left\n");
}
static void
my_anchorblock_edge_right(void *data, Evas_Object *obj, void *event_info)
{
printf("right\n");
}
static void
my_anchorblock_edge_top(void *data, Evas_Object *obj, void *event_info)
{
printf("top\n");
}
static void
my_anchorblock_edge_bottom(void *data, Evas_Object *obj, void *event_info)
{
printf("bottom\n");
}
static void
my_anchorblock_scroll(void *data, Evas_Object *obj, void *event_info)
{
Evas_Coord x, y, w, h, vw, vh;
elm_scroller_region_get(obj, &x, &y, &w, &h);
elm_scroller_child_size_get(obj, &vw, &vh);
printf("scroll %ix%i +%i+%i in %ix%i\n", w, h, x, y, vw, vh);
}
static void
my_bt_17(void *data, Evas_Object *obj, void *event_info)
{
@ -1147,6 +1181,12 @@ my_bt_17(void *data, Evas_Object *obj, void *event_info)
sc = elm_scroller_add(win);
evas_object_size_hint_weight_set(sc, 1.0, 1.0);
elm_win_resize_object_add(win, sc);
evas_object_smart_callback_add(sc, "edge_left", my_anchorblock_edge_left, NULL);
evas_object_smart_callback_add(sc, "edge_right", my_anchorblock_edge_right, NULL);
evas_object_smart_callback_add(sc, "edge_top", my_anchorblock_edge_top, NULL);
evas_object_smart_callback_add(sc, "edge_bottom", my_anchorblock_edge_bottom, NULL);
evas_object_smart_callback_add(sc, "scroll", my_anchorblock_scroll, NULL);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, 1.0, 0.0);
@ -1575,10 +1615,16 @@ my_bt_20(void *data, Evas_Object *obj, void *event_info)
evas_object_show(win);
}
static void
my_li2_clear(void *data, Evas_Object *obj, void *event_info)
{
elm_list_clear(data);
}
static void
my_bt_21(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *li, *ic, *ic2, *bx;
Evas_Object *win, *bg, *li, *ic, *ic2, *bx, *bx2, *bt;
char buf[PATH_MAX];
win = elm_win_add(NULL, "list-2", ELM_WIN_BASIC);
@ -1586,12 +1632,19 @@ my_bt_21(void *data, Evas_Object *obj, void *event_info)
elm_win_autodel_set(win, 1);
bg = elm_bg_add(win);
snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
elm_bg_file_set(bg, buf, NULL);
elm_win_resize_object_add(win, bg);
evas_object_size_hint_weight_set(bg, 1.0, 1.0);
evas_object_show(bg);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, 1.0, 1.0);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
li = elm_list_add(win);
elm_win_resize_object_add(win, li);
evas_object_size_hint_align_set(li, -1.0, -1.0);
evas_object_size_hint_weight_set(li, 1.0, 1.0);
elm_list_horizontal_mode_set(li, ELM_LIST_LIMIT);
elm_list_multi_select_set(li, 1);
@ -1618,15 +1671,15 @@ my_bt_21(void *data, Evas_Object *obj, void *event_info)
elm_icon_scale_set(ic2, 0, 0);
elm_list_item_append(li, "How", ic, ic2, NULL, NULL);
bx = elm_box_add(win);
elm_box_horizontal_set(bx, 1);
bx2 = elm_box_add(win);
elm_box_horizontal_set(bx2, 1);
ic = elm_icon_add(win);
snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
elm_icon_file_set(ic, buf, NULL);
elm_icon_scale_set(ic, 0, 0);
evas_object_size_hint_align_set(ic, 0.5, 0.5);
elm_box_pack_end(bx, ic);
elm_box_pack_end(bx2, ic);
evas_object_show(ic);
ic = elm_icon_add(win);
@ -1634,9 +1687,9 @@ my_bt_21(void *data, Evas_Object *obj, void *event_info)
elm_icon_file_set(ic, buf, NULL);
elm_icon_scale_set(ic, 0, 0);
evas_object_size_hint_align_set(ic, 0.5, 0.0);
elm_box_pack_end(bx, ic);
elm_box_pack_end(bx2, ic);
evas_object_show(ic);
elm_list_item_append(li, "are", bx, NULL, NULL, NULL);
elm_list_item_append(li, "are", bx2, NULL, NULL, NULL);
elm_list_item_append(li, "you", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "doing", NULL, NULL, NULL, NULL);
@ -1653,8 +1706,26 @@ my_bt_21(void *data, Evas_Object *obj, void *event_info)
elm_list_go(li);
elm_box_pack_end(bx, li);
evas_object_show(li);
bx2 = elm_box_add(win);
elm_box_horizontal_set(bx2, 1);
elm_box_homogenous_set(bx2, 1);
evas_object_size_hint_weight_set(bx2, 1.0, 0.0);
evas_object_size_hint_align_set(bx2, -1.0, -1.0);
bt = elm_button_add(win);
elm_button_label_set(bt, "Clear");
evas_object_smart_callback_add(bt, "clicked", my_li2_clear, li);
evas_object_size_hint_align_set(bt, -1.0, -1.0);
evas_object_size_hint_weight_set(bt, 1.0, 0.0);
elm_box_pack_end(bx2, bt);
evas_object_show(bt);
elm_box_pack_end(bx, bx2);
evas_object_show(bx2);
evas_object_resize(win, 320, 300);
evas_object_show(win);
}
@ -2216,6 +2287,7 @@ my_bt_30(void *data, Evas_Object *obj, void *event_info)
{
Evas_Object *win, *bg, *gl, *bx, *bx2, *bt;
Elm_Genlist_Item *gli[10];
char buf[PATH_MAX];
int i;
win = elm_win_add(NULL, "genlist-2", ELM_WIN_BASIC);
@ -2223,6 +2295,8 @@ my_bt_30(void *data, Evas_Object *obj, void *event_info)
elm_win_autodel_set(win, 1);
bg = elm_bg_add(win);
snprintf(buf, sizeof(buf), "%s/images/plant_01.jpg", PACKAGE_DATA_DIR);
elm_bg_file_set(bg, buf, NULL);
elm_win_resize_object_add(win, bg);
evas_object_size_hint_weight_set(bg, 1.0, 1.0);
evas_object_show(bg);

View File

@ -337,7 +337,14 @@ extern "C" {
EAPI void elm_scroller_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
EAPI void elm_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v);
EAPI void elm_scroller_region_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
EAPI void elm_scroller_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
EAPI void elm_scroller_bounce_set(Evas_Object *obj, Evas_Bool h_bounce, Evas_Bool v_bounce);
/* smart callbacks called:
* "edge_left"
* "edge_right"
* "edge_top"
* "edge_bottom"
* "scroll"
*/
EAPI Evas_Object *elm_label_add(Evas_Object *parent);

View File

@ -623,10 +623,10 @@ _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
if (ow < 0) ow = 0;
oh = sd->wd->minh - oh;
if (oh < 0) oh = 0;
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x > ow) x = ow;
if (y > oh) y = oh;
// if (x < 0) x = 0;
// if (y < 0) y = 0;
// if (x > ow) x = ow;
// if (y > oh) y = oh;
if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
sd->wd->pan_x = x;
sd->wd->pan_y = y;
@ -751,6 +751,8 @@ elm_genlist_add(Evas_Object *parent)
wd->scr = elm_smart_scroller_add(e);
elm_widget_resize_object_set(obj, wd->scr);
elm_smart_scroller_bounce_allow_set(wd->scr, 0, 1);
wd->obj = obj;
wd->mode = ELM_LIST_SCROLL;

View File

@ -370,6 +370,8 @@ elm_list_add(Evas_Object *parent)
wd->scroller = elm_scroller_add(parent);
elm_widget_resize_object_set(obj, wd->scroller);
elm_scroller_bounce_set(wd->scroller, 0, 1);
wd->box = elm_box_add(parent);
elm_box_homogenous_set(wd->box, 1);
evas_object_size_hint_weight_set(wd->box, 1.0, 0.0);

View File

@ -91,6 +91,8 @@ elm_shutdown(void)
static const char *elm_engine, *elm_scale, *elm_theme, *elm_prefix, *elm_data_dir;
static const char *elm_font_hinting, *elm_font_path, *elm_image_cache;
static const char *elm_font_cache, *elm_finger_size, *elm_fps;
static const char *elm_thumbscroll_enabled, *elm_thumbscroll_threshhold;
static const char *elm_thumbscroll_momentum_threshhold, *elm_thumbscroll_friction;
EAPI void
elm_quicklaunch_init(int argc, char **argv)
@ -121,6 +123,10 @@ elm_quicklaunch_init(int argc, char **argv)
elm_font_cache = getenv("ELM_FONT_CACHE");
elm_finger_size = getenv("ELM_FINGER_SIZE");
elm_fps = getenv("ELM_FPS");
elm_thumbscroll_enabled = getenv("ELM_THUMBSCROLL_ENABLE");
elm_thumbscroll_threshhold = getenv("ELM_THUMBSCROLL_THRESHOLD");
elm_thumbscroll_momentum_threshhold = getenv("ELM_THUMBSCROLL_MOMENTUM_THRESHOLD");
elm_thumbscroll_friction = getenv("ELM_THUMBSCROLL_FRICTION");
if (!_elm_data_dir)
{
@ -174,7 +180,9 @@ elm_quicklaunch_init(int argc, char **argv)
_elm_config->thumbscroll_enable = 1;
_elm_config->thumbscroll_threshhold = 24;
_elm_config->thumbscroll_momentum_threshhold = 100.0;
_elm_config->thumbscroll_friction = 20.0;
_elm_config->thumbscroll_friction = 1.0;
_elm_config->thumbscroll_bounce_friction = 0.5;
_elm_config->thumbscroll_bounce_enable = 1;
_elm_config->scale = 1.0;
_elm_config->font_hinting = 2;
_elm_config->font_dirs = NULL;
@ -221,6 +229,16 @@ elm_quicklaunch_init(int argc, char **argv)
_elm_config->engine = ELM_SOFTWARE_16_WINCE;
}
if (elm_thumbscroll_enabled)
_elm_config->thumbscroll_enable = atoi(elm_thumbscroll_enabled);
if (elm_thumbscroll_threshhold)
_elm_config->thumbscroll_threshhold = atoi(elm_thumbscroll_threshhold);
// FIXME: floatformat locale issues here 1.0 vs 1,0 - should just be 1.0
if (elm_thumbscroll_momentum_threshhold)
_elm_config->thumbscroll_momentum_threshhold = atof(elm_thumbscroll_momentum_threshhold);
if (elm_thumbscroll_friction)
_elm_config->thumbscroll_friction = atof(elm_thumbscroll_friction);
if (elm_theme)
_elm_theme_parse(elm_theme);
else
@ -349,7 +367,8 @@ elm_quicklaunch_sub_shutdown(void)
ecore_event_handler_del(_elm_event_property_change);
_elm_event_property_change = NULL;
ecore_x_disconnect();
#endif
#endif
evas_cserve_disconnect();
}
}

View File

@ -41,6 +41,8 @@ struct _Elm_Config
int thumbscroll_threshhold;
double thumbscroll_momentum_threshhold;
double thumbscroll_friction;
double thumbscroll_bounce_friction;
int thumbscroll_bounce_enable;
double scale;
int bgpixmap;
int compositing;

View File

@ -137,6 +137,36 @@ _resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
_sizing_eval(data);
}
static void
_edge_left(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
evas_object_smart_callback_call(data, "edge_left", NULL);
}
static void
_edge_right(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
evas_object_smart_callback_call(data, "edge_right", NULL);
}
static void
_edge_top(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
evas_object_smart_callback_call(data, "edge_top", NULL);
}
static void
_edge_bottom(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
evas_object_smart_callback_call(data, "edge_bottom", NULL);
}
static void
_scroll(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
evas_object_smart_callback_call(data, "scroll", NULL);
}
EAPI Evas_Object *
elm_scroller_add(Evas_Object *parent)
{
@ -167,6 +197,12 @@ elm_scroller_add(Evas_Object *parent)
evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
evas_object_smart_callback_add(wd->scr, "scroll", _scroll, obj);
_sizing_eval(obj);
return obj;
}
@ -232,3 +268,19 @@ elm_scroller_region_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coo
if ((x) && (y)) elm_smart_scroller_child_pos_get(wd->scr, x, y);
if ((w) && (h)) elm_smart_scroller_child_viewport_size_get(wd->scr, w, h);
}
EAPI void
elm_scroller_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_geometry_get(wd->content, NULL, NULL, w, h);
}
EAPI void
elm_scroller_bounce_set(Evas_Object *obj, Evas_Bool h_bounce, Evas_Bool v_bounce)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
}

View File

@ -185,6 +185,7 @@ elm_toolbar_add(Evas_Object *parent)
elm_widget_can_focus_set(obj, 0);
wd->scr = elm_smart_scroller_add(e);
elm_scroller_bounce_set(wd->scr, 1, 0);
elm_smart_scroller_theme_set(wd->scr, "toolbar", "base", "default");
elm_widget_resize_object_set(obj, wd->scr);
elm_smart_scroller_policy_set(wd->scr,

View File

@ -162,7 +162,12 @@ _els_smart_box_unpack(Evas_Object *obj)
if (!sd) return;
sd->items = eina_list_remove(sd->items, obj);
_smart_disown(obj);
if (!sd->deleting) _smart_reconfigure(sd);
if (!sd->deleting)
{
if (!evas_object_clipees_get(sd->clip))
evas_object_hide(sd->clip);
_smart_reconfigure(sd);
}
}
/* local subsystem functions */

View File

@ -356,6 +356,7 @@ _smart_add(Evas_Object *obj)
sd = calloc(1, sizeof(Smart_Data));
if (!sd) return;
sd->obj = evas_object_image_add(evas_object_evas_get(obj));
evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
sd->x = 0;
sd->y = 0;
sd->w = 0;

View File

@ -87,10 +87,10 @@ void
_elm_smart_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
API_ENTRY return;
if (x > (sd->child_w - sd->w)) x = sd->child_w - sd->w;
if (y > (sd->child_h - sd->h)) y = sd->child_h - sd->h;
if (x < 0) x = 0;
if (y < 0) y = 0;
// if (x > (sd->child_w - sd->w)) x = sd->child_w - sd->w;
// if (y > (sd->child_h - sd->h)) y = sd->child_h - sd->h;
// if (x < 0) x = 0;
// if (y < 0) y = 0;
if ((x == sd->px) && (y == sd->py)) return;
sd->px = x;
sd->py = y;

View File

@ -22,22 +22,34 @@ struct _Smart_Data
Evas_Coord x, y;
Evas_Coord sx, sy;
Evas_Coord dx, dy;
Evas_Coord bx, by;
Evas_Coord ax, ay;
Evas_Coord bx0, by0;
Evas_Coord b0x, b0y;
Evas_Coord b2x, b2y;
struct {
Evas_Coord x, y;
double timestamp;
} history[20];
double anim_start;
double anim_start2;
double anim_start3;
double onhold_vx, onhold_vy, onhold_tlast, onhold_vxe, onhold_vye;
Evas_Coord hold_x, hold_y;
Ecore_Animator *hold_animator;
Ecore_Animator *momentum_animator;
Ecore_Animator *onhold_animator;
Ecore_Animator *momentum_animator;
Ecore_Animator *bounce_x_animator;
Ecore_Animator *bounce_y_animator;
Evas_Coord locked_x, locked_y;
unsigned char now : 1;
unsigned char dragged : 1;
unsigned char dir_x : 1;
unsigned char dir_y : 1;
unsigned char dir_none : 1;
unsigned char locked : 1;
unsigned char bounce_x_hold : 1;
unsigned char bounce_y_hold : 1;
} down;
struct {
@ -61,6 +73,10 @@ struct _Smart_Data
unsigned char one_dir_at_a_time : 1;
unsigned char hold : 1;
unsigned char freeze : 1;
unsigned char bouncemex : 1;
unsigned char bouncemey : 1;
unsigned char bounce_horiz : 1;
unsigned char bounce_vert : 1;
};
/* local subsystem functions */
@ -215,6 +231,173 @@ elm_smart_scroller_custom_edje_file_set(Evas_Object *obj, char *file, char *grou
edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
}
static int
_smart_bounce_x_animator(void *data)
{
Smart_Data *sd;
Evas_Coord x, y, dx, dy/*, ox, oy*/;
double t, p, dt;
sd = data;
t = ecore_loop_time_get();
dt = t - sd->down.anim_start2;
if (dt >= 0.0)
{
dt = dt / _elm_config->thumbscroll_bounce_friction;
if (dt > 1.0) dt = 1.0;
p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt));
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
dx = sd->down.b2x - sd->down.bx;
dx = (dx * p);
x = sd->down.bx + dx;
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
if (dt >= 1.0)
{
if (sd->down.momentum_animator)
sd->down.bounce_x_hold = 1;
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
return 0;
}
}
return 1;
}
static int
_smart_bounce_y_animator(void *data)
{
Smart_Data *sd;
Evas_Coord x, y, dx, dy;
double t, p, dt;
sd = data;
t = ecore_loop_time_get();
dt = t - sd->down.anim_start3;
if (dt >= 0.0)
{
dt = dt / _elm_config->thumbscroll_bounce_friction;
if (dt > 1.0) dt = 1.0;
p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt));
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
dy = sd->down.b2y - sd->down.by;
dy = (dy * p);
y = sd->down.by + dy;
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
if (dt >= 1.0)
{
if (sd->down.momentum_animator)
sd->down.bounce_y_hold = 1;
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
return 0;
}
}
return 1;
}
static int
_smart_momentum_animator(void *data)
{
Smart_Data *sd;
double t, dt, p;
Evas_Coord x, y, dx, dy, px, py;
sd = data;
t = ecore_loop_time_get();
dt = t - sd->down.anim_start;
if (dt >= 0.0)
{
dt = dt / _elm_config->thumbscroll_friction;
if (dt > 1.0) dt = 1.0;
p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt));
dx = (sd->down.dx * _elm_config->thumbscroll_friction * p);
dy = (sd->down.dy * _elm_config->thumbscroll_friction * p);
sd->down.ax = dx;
sd->down.ay = dy;
x = sd->down.sx - dx;
y = sd->down.sy - dy;
elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py);
if ((sd->down.bounce_x_animator) ||
(sd->down.bounce_x_hold))
{
sd->down.bx = sd->down.bx0 - dx + sd->down.b0x;
x = px;
}
if ((sd->down.bounce_y_animator) ||
(sd->down.bounce_y_hold))
{
sd->down.by = sd->down.by0 - dy + sd->down.b0y;
y = py;
}
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
if (dt >= 1.0)
{
sd->down.momentum_animator = NULL;
sd->down.bounce_x_hold = 0;
sd->down.bounce_y_hold = 0;
sd->down.ax = 0;
sd->down.ay = 0;
return 0;
}
}
return 1;
}
static void
bounce_eval(Smart_Data *sd)
{
Evas_Coord mx, my, px, py, bx, by, b2x, b2y;
if ((!sd->bouncemex) && (!sd->bouncemey)) return;
if (sd->down.now) return; // down bounce while still held down
if (sd->down.onhold_animator)
{
ecore_animator_del(sd->down.onhold_animator);
sd->down.onhold_animator = NULL;
}
if (sd->down.hold_animator)
{
ecore_animator_del(sd->down.hold_animator);
sd->down.hold_animator = NULL;
}
sd->pan_func.max_get(sd->pan_obj, &mx, &my);
sd->pan_func.get(sd->pan_obj, &px, &py);
bx = px;
by = py;
if (px < 0) px = 0;
if (px > mx) px = mx;
if (py < 0) py = 0;
if (py > my) py = my;
b2x = px;
b2y = py;
if (!sd->down.bounce_x_animator)
{
if (sd->bouncemex)
{
sd->down.bounce_x_animator = ecore_animator_add(_smart_bounce_x_animator, sd);
sd->down.anim_start2 = ecore_loop_time_get();
sd->down.bx = bx;
sd->down.bx0 = bx;
sd->down.b2x = b2x;
if (sd->down.momentum_animator) sd->down.b0x = sd->down.ax;
else sd->down.b0x = 0;
}
}
if (!sd->down.bounce_y_animator)
{
if (sd->bouncemey)
{
sd->down.bounce_y_animator = ecore_animator_add(_smart_bounce_y_animator, sd);
sd->down.anim_start3 = ecore_loop_time_get();
sd->down.by = by;
sd->down.by0 = by;
sd->down.b2y = b2y;
if (sd->down.momentum_animator) sd->down.b0y = sd->down.ay;
else sd->down.b0y = 0;
}
}
}
void
elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
@ -235,9 +418,62 @@ elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, vy);
edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", vx, 0.0);
sd->pan_func.get(sd->pan_obj, &px, &py);
if (!_elm_config->thumbscroll_bounce_enable)
{
if (x < 0) x = 0;
if (x > mx) x = mx;
if (y < 0) y = 0;
if (y > my) y = my;
}
if (!sd->bounce_horiz)
{
if (x < 0) x = 0;
if (x > mx) x = mx;
}
if (!sd->bounce_vert)
{
if (y < 0) y = 0;
if (y > my) y = my;
}
sd->pan_func.set(sd->pan_obj, x, y);
if ((px != x) || (py != y))
edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
if (!sd->down.bounce_x_animator)
{
if ((x < 0) || (x > mx))
{
sd->bouncemex = 1;
bounce_eval(sd);
}
}
if (!sd->down.bounce_y_animator)
{
if ((y < 0) || (y > my))
{
sd->bouncemey = 1;
bounce_eval(sd);
}
}
if ((x != px) || (y != py))
{
evas_object_smart_callback_call(obj, "scroll", NULL);
}
if ((x != px)/* && (!sd->bouncemex)*/)
{
if (x == 0)
evas_object_smart_callback_call(obj, "edge,left", NULL);
if (x == mx)
evas_object_smart_callback_call(obj, "edge,right", NULL);
}
if ((y != py)/* && (!sd->bouncemey)*/)
{
if (y == 0)
evas_object_smart_callback_call(obj, "edge,top", NULL);
if (y == my)
evas_object_smart_callback_call(obj, "edge,bottom", NULL);
}
}
void
@ -272,6 +508,18 @@ elm_smart_scroller_child_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord
if (ny > y) ny = y;
}
if ((nx == px) && (ny == py)) return;
if (sd->down.bounce_x_animator)
{
ecore_animator_del(sd->down.bounce_x_animator);
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
}
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
elm_smart_scroller_child_pos_set(obj, nx, ny);
}
@ -404,6 +652,14 @@ elm_smart_scroller_freeze_set(Evas_Object *obj, Evas_Bool freeze)
}
}
void
elm_smart_scroller_bounce_allow_set(Evas_Object *obj, Evas_Bool horiz, Evas_Bool vert)
{
API_ENTRY return;
sd->bounce_horiz = horiz;
sd->bounce_vert = vert;
}
/* local subsystem functions */
static void
_smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source)
@ -437,10 +693,24 @@ _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info)
static void
_smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info)
{
Evas_Coord x, y;
Evas_Coord w, h;
Smart_Data *sd;
sd = data;
if (sd->down.bounce_x_animator)
{
ecore_animator_del(sd->down.bounce_x_animator);
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
}
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
sd->pan_func.get(sd->pan_obj, &x, &y);
sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
if ((w != sd->child.w) || (h != sd->child.h))
{
@ -448,6 +718,7 @@ _smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info)
sd->child.h = h;
_smart_scrollbar_size_adjust(sd);
evas_object_size_hint_min_set(sd->smart_obj, sd->child.w, sd->child.h);
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
}
@ -459,6 +730,18 @@ _smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info)
sd = data;
sd->pan_func.get(sd->pan_obj, &x, &y);
if (sd->down.bounce_x_animator)
{
ecore_animator_del(sd->down.bounce_x_animator);
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
}
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
@ -473,6 +756,12 @@ _smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info)
ev = event_info;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
y += ev->z * sd->step.y;
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
@ -487,6 +776,18 @@ _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
ev = event_info;
if (_elm_config->thumbscroll_enable)
{
if (sd->down.bounce_x_animator)
{
ecore_animator_del(sd->down.bounce_x_animator);
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
}
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
if (sd->down.hold_animator)
{
ecore_animator_del(sd->down.hold_animator);
@ -496,6 +797,10 @@ _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
ecore_animator_del(sd->down.momentum_animator);
sd->down.momentum_animator = NULL;
sd->down.bounce_x_hold = 0;
sd->down.bounce_y_hold = 0;
sd->down.ax = 0;
sd->down.ay = 0;
}
if (ev->button == 1)
{
@ -503,6 +808,7 @@ _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
sd->down.dragged = 0;
sd->down.dir_x = 0;
sd->down.dir_y = 0;
sd->down.dir_none = 0;
sd->down.x = ev->canvas.x;
sd->down.y = ev->canvas.y;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
@ -510,7 +816,7 @@ _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
sd->down.sy = y;
sd->down.locked = 0;
memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20);
sd->down.history[0].timestamp = ecore_time_get();
sd->down.history[0].timestamp = ecore_loop_time_get();
sd->down.history[0].x = ev->canvas.x;
sd->down.history[0].y = ev->canvas.y;
}
@ -528,35 +834,6 @@ _smart_hold_animator(void *data)
return 0;
}
static int
_smart_momentum_animator(void *data)
{
Smart_Data *sd;
double t, dt, p;
Evas_Coord x, y, dx, dy;
sd = data;
t = ecore_time_get();
dt = t - sd->down.anim_start;
if (dt >= 0.0)
{
dt = dt / _elm_config->thumbscroll_friction;
if (dt > 1.0) dt = 1.0;
p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt));
dx = (sd->down.dx * _elm_config->thumbscroll_friction * p);
dy = (sd->down.dy * _elm_config->thumbscroll_friction * p);
x = sd->down.sx - dx;
y = sd->down.sy - dy;
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
if (dt >= 1.0)
{
sd->down.momentum_animator = NULL;
return 0;
}
}
return 1;
}
static void
_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
@ -586,7 +863,7 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
int i;
Evas_Coord ax, ay, dx, dy, vel;
t = ecore_time_get();
t = ecore_loop_time_get();
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
ax = ev->canvas.x;
ay = ev->canvas.y;
@ -624,6 +901,8 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
sd->down.sx = x;
sd->down.sy = y;
sd->down.b0x = 0;
sd->down.b0y = 0;
}
}
}
@ -631,6 +910,9 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
}
sd->down.dragged = 0;
sd->down.now = 0;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
bounce_eval(sd);
}
}
}
@ -677,9 +959,11 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
if (sd->down.now)
{
int faildir = 0;
memmove(&(sd->down.history[1]), &(sd->down.history[0]),
sizeof(sd->down.history[0]) * 19);
sd->down.history[0].timestamp = ecore_time_get();
sd->down.history[0].timestamp = ecore_loop_time_get();
sd->down.history[0].x = ev->cur.canvas.x;
sd->down.history[0].y = ev->cur.canvas.y;
@ -688,24 +972,27 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
y = ev->cur.canvas.y - sd->down.y;
if (y < 0) y = -y;
if ((sd->one_dir_at_a_time) &&
(!sd->down.dir_x) && (!sd->down.dir_y))
(!sd->down.dir_x) && (!sd->down.dir_y) && (!sd->down.dir_none))
{
if (x > y)
{
if (x > _elm_config->thumbscroll_threshhold)
{
if (x > _elm_config->thumbscroll_threshhold)
{
if (x > (y * 2))
{
sd->down.dir_x = 1;
sd->down.dir_y = 0;
}
else faildir++;
}
else
if (y > _elm_config->thumbscroll_threshhold)
{
if (y > _elm_config->thumbscroll_threshhold)
if (y > (x * 2))
{
sd->down.dir_x = 0;
sd->down.dir_y = 1;
}
}
else faildir++;
}
if (faildir) sd->down.dir_none = 1;
}
if (!sd->hold)
{
@ -809,6 +1096,7 @@ _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
Evas_Event_Key_Down *ev;
Smart_Data *sd;
Evas_Coord x = 0, y = 0, vw = 0, vh = 0, mx = 0, my = 0;
int xch = 0, ych = 0;
sd = data;
ev = event_info;
@ -817,23 +1105,42 @@ _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
sd->pan_func.max_get(sd->pan_obj, &mx, &my);
evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
if (!strcmp(ev->keyname, "Left"))
x -= sd->step.x;
{
x -= sd->step.x;
xch = 1;
}
else if (!strcmp(ev->keyname, "Right"))
x += sd->step.x;
{
x += sd->step.x;
xch = 1;
}
else if (!strcmp(ev->keyname, "Up"))
y -= sd->step.y;
{
y -= sd->step.y;
ych = 1;
}
else if (!strcmp(ev->keyname, "Home"))
y = 0;
{
y = 0;
ych = 1;
}
else if (!strcmp(ev->keyname, "End"))
y = my;
{
y = my;
ych = 1;
}
else if (!strcmp(ev->keyname, "Down"))
y += sd->step.y;
{
y += sd->step.y;
ych = 1;
}
else if (!strcmp(ev->keyname, "Prior"))
{
if (sd->page.y < 0)
y -= -(sd->page.y * vh) / 100;
else
y -= sd->page.y;
ych = 1;
}
else if (!strcmp(ev->keyname, "Next"))
{
@ -841,7 +1148,27 @@ _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
y += -(sd->page.y * vh) / 100;
else
y += sd->page.y;
ych = 1;
}
if (xch)
{
if (sd->down.bounce_x_animator)
{
ecore_animator_del(sd->down.bounce_x_animator);
sd->down.bounce_x_animator = NULL;
sd->bouncemex = 0;
}
}
if (ych)
{
if (sd->down.bounce_y_animator)
{
ecore_animator_del(sd->down.bounce_y_animator);
sd->down.bounce_y_animator = NULL;
sd->bouncemey = 0;
}
}
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
@ -1135,6 +1462,11 @@ _smart_add(Evas_Object *obj)
sd->hbar_visible = 1;
sd->vbar_visible = 1;
sd->bounce_horiz = 1;
sd->bounce_vert = 1;
sd->one_dir_at_a_time = 1;
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _smart_event_key_down, sd);
evas_object_propagate_events_set(obj, 0);
@ -1180,7 +1512,10 @@ _smart_del(Evas_Object *obj)
evas_object_del(sd->edje_obj);
evas_object_del(sd->event_obj);
if (sd->down.hold_animator) ecore_animator_del(sd->down.hold_animator);
if (sd->down.onhold_animator) ecore_animator_del(sd->down.onhold_animator);
if (sd->down.momentum_animator) ecore_animator_del(sd->down.momentum_animator);
if (sd->down.bounce_x_animator) ecore_animator_del(sd->down.bounce_x_animator);
if (sd->down.bounce_y_animator) ecore_animator_del(sd->down.bounce_y_animator);
free(sd);
evas_object_smart_data_set(obj, NULL);
}

View File

@ -26,3 +26,4 @@ Evas_Bool elm_smart_scroller_single_dir_get (Evas_Object *obj);
void elm_smart_scroller_theme_set (Evas_Object *obj, const char *clas, const char *group, const char *style);
void elm_smart_scroller_hold_set (Evas_Object *obj, Evas_Bool hold);
void elm_smart_scroller_freeze_set (Evas_Object *obj, Evas_Bool freeze);
void elm_smart_scroller_bounce_allow_set (Evas_Object *obj, Evas_Bool horiz, Evas_Bool vert);