and make entry work nicely by freezing/holding scrolling (hold == different

scroll mode).



SVN revision: 39601
This commit is contained in:
Carsten Haitzler 2009-03-20 15:08:33 +00:00
parent e5298074e7
commit 16a328cba1
8 changed files with 311 additions and 83 deletions

View File

@ -208,9 +208,12 @@ elm_hoversel_hover_end(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->hover) evas_object_del(wd->hover);
wd->hover = NULL;
evas_object_smart_callback_call(obj, "dismissed", NULL);
if (wd->hover)
{
evas_object_del(wd->hover);
wd->hover = NULL;
evas_object_smart_callback_call(obj, "dismissed", NULL);
}
}
EAPI Elm_Hoversel_Item *

View File

@ -179,6 +179,7 @@ _dismissed(void *data, Evas_Object *obj, void *event_info)
if (wd->hoversel) evas_object_hide(wd->hoversel);
if (wd->selmode)
edje_object_part_text_select_allow_set(wd->ent, "elm.text", 1);
elm_widget_scroll_freeze_pop(data);
}
static void
@ -273,6 +274,7 @@ _long_press(void *data)
}
wd->longpress_timer = NULL;
edje_object_part_text_select_allow_set(wd->ent, "elm.text", 0);
edje_object_part_text_select_abort(wd->ent, "elm.text");
return 0;
}
@ -285,6 +287,7 @@ _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
if (ev->button != 1) return;
// if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
elm_widget_scroll_freeze_push(data);
wd->longpress_timer = ecore_timer_add(1.0, _long_press, data);
wd->downx = ev->canvas.x;
wd->downy = ev->canvas.y;
@ -298,6 +301,7 @@ _mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info)
if (ev->button != 1) return;
if (wd->longpress_timer)
{
elm_widget_scroll_freeze_pop(data);
ecore_timer_del(wd->longpress_timer);
wd->longpress_timer = NULL;
}
@ -314,6 +318,7 @@ _mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
if (wd->longpress_timer)
{
elm_widget_scroll_freeze_pop(data);
ecore_timer_del(wd->longpress_timer);
wd->longpress_timer = NULL;
}
@ -330,6 +335,7 @@ _mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
((_elm_config->finger_size / 2) *
(_elm_config->finger_size / 2)))
{
elm_widget_scroll_freeze_pop(data);
ecore_timer_del(wd->longpress_timer);
wd->longpress_timer = NULL;
}
@ -347,6 +353,7 @@ _mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info)
((_elm_config->finger_size / 2) *
(_elm_config->finger_size / 2)))
{
elm_widget_scroll_freeze_pop(data);
ecore_timer_del(wd->longpress_timer);
wd->longpress_timer = NULL;
}
@ -412,7 +419,6 @@ _mkup_to_text(const char *mkup)
{
char *str = NULL;
int str_len = 0, str_alloc = 0;
// FIXME: markup -> text
char *s, *p;
char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
@ -637,9 +643,18 @@ _signal_selection_cleared(void *data, Evas_Object *obj, const char *emission, co
{
#ifdef HAVE_ELEMENTARY_X
if (elm_win_xwindow_get(elm_widget_top_get(data)))
ecore_x_selection_primary_set
(elm_win_xwindow_get(elm_widget_top_get(data)),
wd->cut_sel, strlen(wd->cut_sel));
{
char *t;
t = _mkup_to_text(wd->cut_sel);
if (t)
{
ecore_x_selection_primary_set
(elm_win_xwindow_get(elm_widget_top_get(data)),
t, strlen(t));
free(t);
}
}
#endif
eina_stringshare_del(wd->cut_sel);
wd->cut_sel = NULL;
@ -812,7 +827,6 @@ _event_selection_notify(void *data, int type, void *event)
char *txt = _text_to_mkup(text_data->text);
if (txt)
{
printf("inst: %s\n", txt);
elm_entry_entry_insert(data, txt);
free(txt);
}

View File

@ -98,6 +98,9 @@ EAPI void elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord
EAPI void elm_widget_scroll_hold_push(Evas_Object *obj);
EAPI void elm_widget_scroll_hold_pop(Evas_Object *obj);
EAPI int elm_widget_scroll_hold_get(const Evas_Object *obj);
EAPI void elm_widget_scroll_freeze_push(Evas_Object *obj);
EAPI void elm_widget_scroll_freeze_pop(Evas_Object *obj);
EAPI int elm_widget_scroll_freeze_get(const Evas_Object *obj);
EAPI void elm_widget_scale_set(Evas_Object *obj, double scale);
EAPI double elm_widget_scale_get(const Evas_Object *obj);

View File

@ -99,6 +99,38 @@ _sub_del(void *data, Evas_Object *obj, void *event_info)
}
}
static void
_hold_on(void *data, Evas_Object *obj, void *event_info)
{
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, Evas_Object *obj, void *event_info)
{
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, Evas_Object *obj, void *event_info)
{
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, Evas_Object *obj, void *event_info)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
elm_smart_scroller_freeze_set(wd->scr, 0);
}
static void
_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
@ -130,6 +162,10 @@ elm_scroller_add(Evas_Object *parent)
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, 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);
_sizing_eval(obj);
return obj;

View File

@ -234,7 +234,8 @@ elm_slider_add(Evas_Object *parent)
edje_object_signal_callback_add(wd->slider, "drag,start", "*", _drag_start, obj);
edje_object_signal_callback_add(wd->slider, "drag,stop", "*", _drag_stop, obj);
edje_object_signal_callback_add(wd->slider, "drag,step", "*", _drag_stop, obj);
edje_object_signal_callback_add(wd->slider, "drag,set", "*", _drag_stop, obj);
edje_object_signal_callback_add(wd->slider, "drag,page", "*", _drag_stop, obj);
// edje_object_signal_callback_add(wd->slider, "drag,set", "*", _drag_stop, obj);
edje_object_part_drag_value_set(wd->slider, "elm.dragable.slider", 0.0, 0.0);
wd->spacer = evas_object_rectangle_add(e);

View File

@ -36,6 +36,7 @@ struct _Smart_Data
void *data;
Evas_Coord rx, ry, rw, rh;
int scroll_hold;
int scroll_freeze;
double scale;
unsigned char can_focus : 1;
unsigned char child_can_focus : 1;
@ -695,6 +696,8 @@ elm_widget_scroll_hold_push(Evas_Object *obj)
{
API_ENTRY return;
sd->scroll_hold++;
if (sd->scroll_hold == 1)
evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
}
@ -703,6 +706,9 @@ elm_widget_scroll_hold_pop(Evas_Object *obj)
{
API_ENTRY return;
sd->scroll_hold--;
if (sd->scroll_hold < 0) sd->scroll_hold = 0;
if (sd->scroll_hold == 0)
evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
}
@ -713,6 +719,34 @@ elm_widget_scroll_hold_get(const Evas_Object *obj)
return sd->scroll_hold;
}
EAPI void
elm_widget_scroll_freeze_push(Evas_Object *obj)
{
API_ENTRY return;
sd->scroll_freeze++;
if (sd->scroll_freeze == 1)
evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
}
EAPI void
elm_widget_scroll_freeze_pop(Evas_Object *obj)
{
API_ENTRY return;
sd->scroll_freeze--;
if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
if (sd->scroll_freeze == 0)
evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
}
EAPI int
elm_widget_scroll_freeze_get(const Evas_Object *obj)
{
API_ENTRY return 0;
return sd->scroll_freeze;
}
EAPI void
elm_widget_scale_set(Evas_Object *obj, double scale)
{

View File

@ -27,9 +27,11 @@ struct _Smart_Data
double timestamp;
} history[20];
double anim_start;
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;
Evas_Coord locked_x, locked_y;
unsigned char now : 1;
unsigned char dragged : 1;
@ -57,6 +59,8 @@ struct _Smart_Data
unsigned char vbar_visible : 1;
unsigned char extern_pan : 1;
unsigned char one_dir_at_a_time : 1;
unsigned char hold : 1;
unsigned char freeze : 1;
};
/* local subsystem functions */
@ -68,6 +72,7 @@ static void _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void
static int _smart_hold_animator(void *data);
static int _smart_momentum_animator(void *data);
static void _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
static int _smart_onhold_animator(void *data);
static void _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source);
@ -353,6 +358,28 @@ elm_smart_scroller_theme_set(Evas_Object *obj, const char *clas, const char *gro
_smart_scrollbar_bar_visibility_adjust(sd);
}
void
elm_smart_scroller_hold_set(Evas_Object *obj, Evas_Bool hold)
{
API_ENTRY return;
sd->hold = hold;
}
void
elm_smart_scroller_freeze_set(Evas_Object *obj, Evas_Bool freeze)
{
API_ENTRY return;
sd->freeze = freeze;
if (sd->freeze)
{
if (sd->down.onhold_animator)
{
ecore_animator_del(sd->down.onhold_animator);
sd->down.onhold_animator = NULL;
}
}
}
/* local subsystem functions */
static void
_smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source)
@ -520,55 +547,63 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
if (ev->button == 1)
{
if (sd->down.onhold_animator)
{
ecore_animator_del(sd->down.onhold_animator);
sd->down.onhold_animator = NULL;
}
x = ev->canvas.x - sd->down.x;
y = ev->canvas.y - sd->down.y;
if (sd->down.dragged)
{
double t, at, dt;
int i;
Evas_Coord ax, ay, dx, dy, vel;
t = ecore_time_get();
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
ax = ev->canvas.x;
ay = ev->canvas.y;
at = 0.0;
for (i = 0; i < 20; i++)
{
dt = t - sd->down.history[i].timestamp;
if (dt > 0.2) break;
at += dt;
ax += sd->down.history[i].x;
ay += sd->down.history[i].y;
}
ax /= (i + 1);
ay /= (i + 1);
at /= (i + 1);
at *= 4.0;
dx = ev->canvas.x - ax;
dy = ev->canvas.y - ay;
if (at > 0)
{
vel = sqrt((dx * dx) + (dy * dy)) / at;
if ((_elm_config->thumbscroll_friction > 0.0) &&
(vel > _elm_config->thumbscroll_momentum_threshhold))
{
if (!sd->down.momentum_animator)
sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd);
if (sd->down.hold_animator)
if (sd->down.dragged)
{
if ((!sd->hold) && (!sd->freeze))
{
double t, at, dt;
int i;
Evas_Coord ax, ay, dx, dy, vel;
t = ecore_time_get();
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
ax = ev->canvas.x;
ay = ev->canvas.y;
at = 0.0;
for (i = 0; i < 20; i++)
{
dt = t - sd->down.history[i].timestamp;
if (dt > 0.2) break;
at += dt;
ax += sd->down.history[i].x;
ay += sd->down.history[i].y;
}
ax /= (i + 1);
ay /= (i + 1);
at /= (i + 1);
at *= 4.0;
dx = ev->canvas.x - ax;
dy = ev->canvas.y - ay;
if (at > 0)
{
vel = sqrt((dx * dx) + (dy * dy)) / at;
if ((_elm_config->thumbscroll_friction > 0.0) &&
(vel > _elm_config->thumbscroll_momentum_threshhold))
{
ecore_animator_del(sd->down.hold_animator);
sd->down.hold_animator = NULL;
if (!sd->down.momentum_animator)
sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd);
if (sd->down.hold_animator)
{
ecore_animator_del(sd->down.hold_animator);
sd->down.hold_animator = NULL;
}
sd->down.dx = ((double)dx / at);
sd->down.dy = ((double)dy / at);
sd->down.anim_start = t;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
sd->down.sx = x;
sd->down.sy = y;
}
sd->down.dx = ((double)dx / at);
sd->down.dy = ((double)dy / at);
sd->down.anim_start = t;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
sd->down.sx = x;
sd->down.sy = y;
}
}
evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
}
}
evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
}
sd->down.dragged = 0;
sd->down.now = 0;
@ -576,6 +611,34 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
}
}
static int
_smart_onhold_animator(void *data)
{
Smart_Data *sd;
double t, td;
double vx, vy;
Evas_Coord x, y, ox, oy, dx, dy;
sd = data;
t = ecore_loop_time_get();
if (sd->down.onhold_tlast > 0.0)
{
td = t - sd->down.onhold_tlast;
vx = sd->down.onhold_vx * td * _elm_config->thumbscroll_threshhold * 2.0;
vy = sd->down.onhold_vy * td * _elm_config->thumbscroll_threshhold * 2.0;
elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
sd->down.onhold_vxe += vx;
sd->down.onhold_vye += vy;
x = ox + (int)sd->down.onhold_vxe;
y = oy + (int)sd->down.onhold_vye;
sd->down.onhold_vxe -= (int)sd->down.onhold_vxe;
sd->down.onhold_vye -= (int)sd->down.onhold_vye;
elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
sd->down.onhold_tlast = t;
return 1;
}
static void
_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
@ -620,34 +683,98 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
}
}
}
if ((sd->down.dragged) ||
(((x * x) + (y * y)) >
(_elm_config->thumbscroll_threshhold *
_elm_config->thumbscroll_threshhold)))
{
if (!sd->down.dragged)
evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
sd->down.dragged = 1;
x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
if ((sd->down.dir_x) || (sd->down.dir_y))
{
if (!sd->down.locked)
{
sd->down.locked_x = x;
sd->down.locked_y = y;
sd->down.locked = 1;
}
if (sd->down.dir_x) y = sd->down.locked_y;
else x = sd->down.locked_x;
}
sd->down.hold_x = x;
sd->down.hold_y = y;
if (!sd->down.hold_animator)
sd->down.hold_animator = ecore_animator_add(_smart_hold_animator, sd);
// elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
if (!sd->hold)
{
if ((sd->down.dragged) ||
(((x * x) + (y * y)) >
(_elm_config->thumbscroll_threshhold *
_elm_config->thumbscroll_threshhold)))
{
if (!sd->down.dragged)
evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
sd->down.dragged = 1;
x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
if ((sd->down.dir_x) || (sd->down.dir_y))
{
if (!sd->down.locked)
{
sd->down.locked_x = x;
sd->down.locked_y = y;
sd->down.locked = 1;
}
if (sd->down.dir_x) y = sd->down.locked_y;
else x = sd->down.locked_x;
}
sd->down.hold_x = x;
sd->down.hold_y = y;
if (!sd->down.hold_animator)
sd->down.hold_animator = ecore_animator_add(_smart_hold_animator, sd);
// elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
}
}
else if (!sd->freeze)
{
Evas_Coord ex, ey, ew, eh;
double vx = 0.0, vy = 0.0;
evas_object_geometry_get(sd->event_obj, &ex, &ey, &ew, &eh);
x = ev->cur.canvas.y - ex;
y = ev->cur.canvas.y - ey;
if (x < _elm_config->thumbscroll_threshhold)
{
if (_elm_config->thumbscroll_threshhold > 0.0)
vx = -(double)(_elm_config->thumbscroll_threshhold - x) /
_elm_config->thumbscroll_threshhold;
else
vx = -1.0;
}
else if (x > (ew - _elm_config->thumbscroll_threshhold))
{
if (_elm_config->thumbscroll_threshhold > 0.0)
vx = (double)(_elm_config->thumbscroll_threshhold - (ew - x)) /
_elm_config->thumbscroll_threshhold;
else
vx = 1.0;
}
if (y < _elm_config->thumbscroll_threshhold)
{
if (_elm_config->thumbscroll_threshhold > 0.0)
vy = -(double)(_elm_config->thumbscroll_threshhold - y) /
_elm_config->thumbscroll_threshhold;
else
vy = -1.0;
}
else if (y > (eh - _elm_config->thumbscroll_threshhold))
{
if (_elm_config->thumbscroll_threshhold > 0.0)
vy = (double)(_elm_config->thumbscroll_threshhold - (eh - y)) /
_elm_config->thumbscroll_threshhold;
else
vy = 1.0;
}
if ((vx != 0.0) || (vy != 0.0))
{
sd->down.onhold_vx = vx;
sd->down.onhold_vy = vy;
if (!sd->down.onhold_animator)
{
sd->down.onhold_vxe = 0.0;
sd->down.onhold_vye = 0.0;
sd->down.onhold_tlast = 0.0;
sd->down.onhold_animator = ecore_animator_add(_smart_onhold_animator, sd);
}
}
else
{
if (sd->down.onhold_animator)
{
ecore_animator_del(sd->down.onhold_animator);
sd->down.onhold_animator = NULL;
}
}
}
}
}
}
@ -979,8 +1106,16 @@ _smart_add(Evas_Object *obj)
o = edje_object_add(evas_object_evas_get(obj));
sd->edje_obj = o;
_elm_theme_set(o, "scroller", "base", "default");
edje_object_signal_callback_add(o, "drag*", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag*", "elm.dragable.hbar", _smart_edje_drag_h, sd);
edje_object_signal_callback_add(o, "drag", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag,start", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag,step", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag,page", "elm.dragable.vbar", _smart_edje_drag_v, sd);
edje_object_signal_callback_add(o, "drag", "elm.dragable.hbar", _smart_edje_drag_h, sd);
edje_object_signal_callback_add(o, "drag,start", "elm.dragable.hbar", _smart_edje_drag_h, sd);
edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.hbar", _smart_edje_drag_h, sd);
edje_object_signal_callback_add(o, "drag,step", "elm.dragable.hbar", _smart_edje_drag_h, sd);
edje_object_signal_callback_add(o, "drag,page", "elm.dragable.hbar", _smart_edje_drag_h, sd);
evas_object_smart_member_add(o, obj);
o = evas_object_rectangle_add(evas_object_evas_get(obj));

View File

@ -24,3 +24,5 @@ Evas_Object *elm_smart_scroller_edje_object_get (Evas_Object *obj);
void elm_smart_scroller_single_dir_set (Evas_Object *obj, Evas_Bool single_dir);
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);