#include "elm_priv.h"
typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Entry_Context_Menu_Item Elm_Entry_Context_Menu_Item;
struct _Widget_Data
{
Evas_Coord lastw;
Evas_Coord downx, downy;
Evas_Coord cx, cy, cw, ch;
+ Eina_List *items;
Eina_Bool changed : 1;
Eina_Bool linewrap : 1;
Eina_Bool single_line : 1;
Eina_Bool disabled : 1;
};
+struct _Elm_Entry_Context_Menu_Item
+{
+ Evas_Object *obj;
+ const char *label;
+ const char *icon_file;
+ const char *icon_group;
+ Elm_Icon_Type icon_type;
+ void (*func) (void *data, Evas_Object *obj, void *event_info);
+ void *data;
+};
+
static void _del_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _disable_hook(Evas_Object *obj);
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Elm_Entry_Context_Menu_Item *it;
entries = eina_list_remove(entries, obj);
#ifdef HAVE_ELEMENTARY_X
ecore_event_handler_del(wd->sel_notify_handler);
if (wd->cut_sel) eina_stringshare_del(wd->cut_sel);
if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
if (wd->longpress_timer) ecore_timer_del(wd->longpress_timer);
+ EINA_LIST_FREE(wd->items, it)
+ {
+ eina_stringshare_del(it->label);
+ eina_stringshare_del(it->icon_file);
+ eina_stringshare_del(it->icon_group);
+ free(it);
+ }
free(wd);
}
edje_object_part_text_select_none(wd->ent, "elm.text");
}
+static void
+_item_clicked(void *data, Evas_Object *obj, void *event_info)
+{
+ Elm_Entry_Context_Menu_Item *it = data;
+ Evas_Object *obj2 = it->obj;
+ if (it->func) it->func(it->data, obj2, NULL);
+}
+
static int
_long_press(void *data)
{
Widget_Data *wd = elm_widget_data_get(data);
Evas_Object *top;
+ const Eina_List *l;
+ const Elm_Entry_Context_Menu_Item *it;
if (wd->hoversel) evas_object_del(wd->hoversel);
wd->hoversel = elm_hoversel_add(data);
+ elm_object_style_set(wd->hoversel, "entry");
elm_widget_sub_object_add(data, wd->hoversel);
elm_hoversel_label_set(wd->hoversel, "Text");
top = elm_widget_top_get(data);
elm_hoversel_item_add(wd->hoversel, "Cut", NULL, ELM_ICON_NONE, _cut, data);
elm_hoversel_item_add(wd->hoversel, "Cancel", NULL, ELM_ICON_NONE, _cancel, data);
}
+ EINA_LIST_FOREACH(wd->items, l, it)
+ {
+ elm_hoversel_item_add(wd->hoversel, it->label, it->icon_file, it->icon_type, _item_clicked, it);
+ }
if (wd->hoversel)
{
_hoversel_position(data);
edje_object_part_text_select_all(wd->ent, "elm.text");
}
+EAPI void
+elm_entry_context_menu_clear(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Eina_List *l;
+ Elm_Entry_Context_Menu_Item *it;
+ if (!wd) return;
+ EINA_LIST_FREE(wd->items, it)
+ {
+ eina_stringshare_del(it->label);
+ eina_stringshare_del(it->icon_file);
+ eina_stringshare_del(it->icon_group);
+ free(it);
+ }
+}
+
+EAPI void
+elm_entry_context_menu_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Entry_Context_Menu_Item *it;
+ if (!wd) return;
+ it = calloc(1, sizeof(Elm_Entry_Context_Menu_Item));
+ if (!it) return;
+ wd->items = eina_list_append(wd->items, it);
+ it->obj = obj;
+ it->label = eina_stringshare_add(label);
+ it->icon_file = eina_stringshare_add(icon_file);
+ it->icon_type = icon_type;
+ it->func = func;
+ it->data = (void *)data;
+}
+
EAPI char *
elm_entry_markup_to_utf8(const char *s)
{
#define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
typedef struct _Smart_Data Smart_Data;
+#define EVTIME 1
+//#define SCROLLDBG 1
+
struct _Smart_Data
{
Evas_Coord x, y, w, h;
edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
}
+static void
+_smart_anim_start(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "animate,start", NULL);
+}
+
+static void
+_smart_anim_stop(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "animate,stop", NULL);
+}
+
+static void
+_smart_drag_start(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "drag,start", NULL);
+}
+
+static void
+_smart_drag_stop(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "drag,stop", NULL);
+}
+
static int
_smart_scrollto_x_animator(void *data)
{
px = sd->scrollto.x.end;
sd->pan_func.set(sd->pan_obj, px, py);
sd->scrollto.x.animator = NULL;
+ if (!sd->scrollto.y.animator)
+ _smart_anim_stop(sd->smart_obj);
return 0;
}
return 1;
elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
if (!sd->scrollto.x.animator)
- sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd);
+ {
+ if (!sd->scrollto.y.animator)
+ _smart_anim_start(sd->smart_obj);
+ sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd);
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ }
+ sd->bouncemex = 0;
}
static int
py = sd->scrollto.y.end;
sd->pan_func.set(sd->pan_obj, px, py);
sd->scrollto.y.animator = NULL;
+ if (!sd->scrollto.x.animator)
+ _smart_anim_stop(sd->smart_obj);
return 0;
}
return 1;
elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
if (!sd->scrollto.y.animator)
- sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd);
+ {
+ if (!sd->scrollto.x.animator)
+ _smart_anim_start(sd->smart_obj);
+ sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd);
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ }
+ sd->bouncemey = 0;
}
static Eina_Bool
}
static Evas_Coord
-_smart_page_x_get(Smart_Data *sd)
+_smart_page_x_get(Smart_Data *sd, int offset)
{
- Evas_Coord x, y, w, h;
+ Evas_Coord x, y, w, h, cw, ch;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+ x += offset;
if (sd->pagerel_h > 0.0)
{
x = x / (sd->pagesize_h);
x = x * (sd->pagesize_h);
}
+ if (x < 0) x = 0;
+ else if ((x + w) > cw) x = cw - w;
return x;
}
static Evas_Coord
-_smart_page_y_get(Smart_Data *sd)
+_smart_page_y_get(Smart_Data *sd, int offset)
{
- Evas_Coord x, y, w, h;
+ Evas_Coord x, y, w, h, cw, ch;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+ y += offset;
if (sd->pagerel_v > 0.0)
{
y = y / (sd->pagesize_v);
y = y * (sd->pagesize_v);
}
+ if (y < 0) y = 0;
+ else if ((y + h) > ch) y = ch - h;
return y;
}
if (!_smart_do_page(sd)) return;
- elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
- if (sd->pagerel_h > 0.0)
- {
- x = x + (w * sd->pagerel_h * 0.5);
- x = x / (w * sd->pagerel_h);
- x = x * (w * sd->pagerel_h);
- }
- else if (sd->pagesize_h > 0)
- {
- x = x + (sd->pagesize_h * 0.5);
- x = x / (sd->pagesize_h);
- x = x * (sd->pagesize_h);
- }
- if (sd->pagerel_v > 0.0)
- {
- y = y + (w * sd->pagerel_v * 0.5);
- y = y / (w * sd->pagerel_v);
- y = y * (w * sd->pagerel_v);
- }
- else if (sd->pagesize_v > 0)
- {
- y = y + (sd->pagesize_v * 0.5);
- y = y / (sd->pagesize_v);
- y = y * (sd->pagesize_v);
- }
+ x = _smart_page_x_get(sd, 0);
+ y = _smart_page_y_get(sd, 0);
+
elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
}
-static void
-_smart_anim_start(Evas_Object *obj)
-{
- evas_object_smart_callback_call(obj, "animate,start", NULL);
-}
-
-static void
-_smart_anim_stop(Evas_Object *obj)
-{
- evas_object_smart_callback_call(obj, "animate,stop", NULL);
-}
-
-static void
-_smart_drag_start(Evas_Object *obj)
-{
- evas_object_smart_callback_call(obj, "drag,start", NULL);
-}
-
-static void
-_smart_drag_stop(Evas_Object *obj)
-{
- evas_object_smart_callback_call(obj, "drag,stop", NULL);
-}
-
static int
_smart_bounce_x_animator(void *data)
{
{
if (sd->bouncemex)
{
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
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;
{
if (sd->bouncemey)
{
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
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;
if (ny > y) ny = y;
}
if ((nx == px) && (ny == py)) return;
- if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator))
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
{
_smart_anim_stop(sd->smart_obj);
}
sd = data;
sd->pan_func.get(sd->pan_obj, &x, &y);
- if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator))
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
{
_smart_anim_stop(sd->smart_obj);
}
evas_key_modifier_is_set(ev->modifiers, "Super"))
return;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
- if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator))
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
{
_smart_anim_stop(sd->smart_obj);
}
if (_elm_config->thumbscroll_enable)
{
if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
- (sd->down.momentum_animator))
+ (sd->down.momentum_animator) || (sd->scrollto.x.animator) ||
+ (sd->scrollto.y.animator))
{
_smart_anim_stop(sd->smart_obj);
}
sd->down.sy = y;
sd->down.locked = 0;
memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20);
+#ifdef EVTIME
+ sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
sd->down.history[0].x = ev->canvas.x;
sd->down.history[0].y = ev->canvas.y;
}
{
Evas_Event_Mouse_Down *ev;
Smart_Data *sd;
- Evas_Coord x = 0, y = 0;
+ Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
sd = data;
ev = event_info;
int i;
Evas_Coord ax, ay, dx, dy, vel;
+#ifdef EVTIME
+ t = ev->timestamp / 1000.0;
+#else
t = ecore_loop_time_get();
+#endif
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
ax = ev->canvas.x;
ay = ev->canvas.y;
at = 0.0;
+#ifdef SCROLLDBG
+ printf("------\n");
+#endif
for (i = 0; i < 20; i++)
{
dt = t - sd->down.history[i].timestamp;
if (dt > 0.2) break;
+#ifdef SCROLLDBG
+ printf("H: %i %i @ %1.3f\n",
+ sd->down.history[i].x,
+ sd->down.history[i].y, dt);
+#endif
at += dt;
ax += sd->down.history[i].x;
ay += sd->down.history[i].y;
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);
- _smart_anim_start(sd->smart_obj);
- }
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.b0x = 0;
- sd->down.b0y = 0;
+ ox = -sd->down.dx;
+ oy = -sd->down.dy;
+ if (!_smart_do_page(sd))
+ {
+ if (!sd->down.momentum_animator)
+ {
+ sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd);
+ _smart_anim_start(sd->smart_obj);
+ }
+ sd->down.anim_start = ecore_loop_time_get();
+ 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;
+ }
}
}
if (sd->down.hold_animator)
Evas_Coord pgx, pgy;
elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
- pgx = _smart_page_x_get(sd);
- if (pgx != x) _smart_scrollto_x(sd, 0.5, pgx);
- pgy = _smart_page_y_get(sd);
- if (pgy != y) _smart_scrollto_y(sd, 0.5, pgy);
+ pgx = _smart_page_x_get(sd, ox);
+ if (pgx != x) _smart_scrollto_x(sd, 1.0, pgx);
+ pgy = _smart_page_y_get(sd, oy);
+ if (pgy != y) _smart_scrollto_y(sd, 1.0, pgy);
}
}
sd->down.dragged = 0;
memmove(&(sd->down.history[1]), &(sd->down.history[0]),
sizeof(sd->down.history[0]) * 19);
+#ifdef EVTIME
+ sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
sd->down.history[0].x = ev->cur.canvas.x;
sd->down.history[0].y = ev->cur.canvas.y;