add support for highlighting urls on mouse over.
add support for launching urls. Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
parent
af8eae9b68
commit
e64e058934
885
src/bin/grid.c
885
src/bin/grid.c
|
@ -4,6 +4,7 @@
|
|||
#include "colors.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "theme.h"
|
||||
|
||||
/* local function prototypes */
|
||||
static void _smart_size(Evas_Object *obj, int w, int h, Eina_Bool force);
|
||||
|
@ -15,6 +16,741 @@ static Evas_Smart *_smart = NULL;
|
|||
static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
|
||||
|
||||
/* local functions */
|
||||
static void
|
||||
_coord_to_cursor(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *cx, int *cy)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Coord ox = 0, oy = 0;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||
|
||||
evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
|
||||
|
||||
*cx = (x - ox) / sd->font.chw;
|
||||
*cy = (y - oy) / sd->font.chh;
|
||||
|
||||
if (*cx < 0)
|
||||
*cx = 0;
|
||||
else if (*cx >= sd->grid.w)
|
||||
*cx = (sd->grid.w - 1);
|
||||
if (*cy < 0)
|
||||
*cy = 0;
|
||||
else if (*cy >= sd->grid.h)
|
||||
*cy = (sd->grid.h - 1);
|
||||
}
|
||||
|
||||
static char *
|
||||
_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y, size_t *len)
|
||||
{
|
||||
Grid *sd;
|
||||
Eina_Strbuf *sb;
|
||||
char *s;
|
||||
int x = 0, y = 0;
|
||||
size_t len_backup;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return NULL;
|
||||
|
||||
sb = eina_strbuf_new();
|
||||
_grid_save_freeze();
|
||||
for (y = c1y; y <= c2y; y++)
|
||||
{
|
||||
Grid_Cell *cells;
|
||||
int w, last0, v, start_x, end_x;
|
||||
|
||||
w = 0;
|
||||
last0 = -1;
|
||||
if (!(cells = _cellrow_get(sd, y, &w))) continue;
|
||||
if (w > sd->grid.w) w = sd->grid.w;
|
||||
if (y == c1y && c1x >= w)
|
||||
{
|
||||
eina_strbuf_append_char(sb, '\n');
|
||||
continue;
|
||||
}
|
||||
start_x = c1x;
|
||||
end_x = (c2x >= w) ? w - 1 : c2x;
|
||||
if (c1y != c2y)
|
||||
{
|
||||
if (y == c1y) end_x = w - 1;
|
||||
else if (y == c2y) start_x = 0;
|
||||
else
|
||||
{
|
||||
start_x = 0;
|
||||
end_x = w - 1;
|
||||
}
|
||||
}
|
||||
for (x = start_x; x <= end_x; x++)
|
||||
{
|
||||
#if defined(SUPPORT_DBLWIDTH)
|
||||
if ((cells[x].codepoint == 0) && (cells[x].att.dblwidth))
|
||||
{
|
||||
if (x < end_x) x++;
|
||||
else break;
|
||||
}
|
||||
#endif
|
||||
if (x >= w) break;
|
||||
if (cells[x].codepoint == 0)
|
||||
{
|
||||
if (last0 < 0) last0 = x;
|
||||
}
|
||||
else if (cells[x].att.newline)
|
||||
{
|
||||
last0 = -1;
|
||||
if ((y != c2y) || (x != end_x))
|
||||
eina_strbuf_append_char(sb, '\n');
|
||||
break;
|
||||
}
|
||||
else if (cells[x].att.tab)
|
||||
{
|
||||
eina_strbuf_append_char(sb, '\t');
|
||||
x = ((x + 8) / 8) * 8;
|
||||
x--;
|
||||
}
|
||||
else
|
||||
{
|
||||
char txt[8];
|
||||
int txtlen;
|
||||
|
||||
if (last0 >= 0)
|
||||
{
|
||||
v = x - last0 - 1;
|
||||
last0 = -1;
|
||||
while (v >= 0)
|
||||
{
|
||||
eina_strbuf_append_char(sb, ' ');
|
||||
v--;
|
||||
}
|
||||
}
|
||||
txtlen = _util_codepoint_to_utf8(cells[x].codepoint, txt);
|
||||
if (txtlen > 0)
|
||||
eina_strbuf_append_length(sb, txt, txtlen);
|
||||
if ((x == (w - 1)) &&
|
||||
((x != c2x) || (y != c2y)))
|
||||
{
|
||||
if (!cells[x].att.autowrapped)
|
||||
eina_strbuf_append_char(sb, '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last0 >= 0)
|
||||
{
|
||||
if (y == c2y)
|
||||
{
|
||||
Eina_Bool have_more = EINA_FALSE;
|
||||
|
||||
for (x = end_x + 1; x < w; x++)
|
||||
{
|
||||
#if defined(SUPPORT_DBLWIDTH)
|
||||
if ((cells[x].codepoint == 0) &&
|
||||
(cells[x].att.dblwidth))
|
||||
{
|
||||
if (x < (w - 1)) x++;
|
||||
else break;
|
||||
}
|
||||
#endif
|
||||
if (((cells[x].codepoint != 0) &&
|
||||
(cells[x].codepoint != ' ')) ||
|
||||
(cells[x].att.newline) ||
|
||||
(cells[x].att.tab))
|
||||
{
|
||||
have_more = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!have_more)
|
||||
eina_strbuf_append_char(sb, '\n');
|
||||
else
|
||||
{
|
||||
for (x = last0; x <= end_x; x++)
|
||||
{
|
||||
#if defined(SUPPORT_DBLWIDTH)
|
||||
if ((cells[x].codepoint == 0) &&
|
||||
(cells[x].att.dblwidth))
|
||||
{
|
||||
if (x < (w - 1)) x++;
|
||||
else break;
|
||||
}
|
||||
#endif
|
||||
if (x >= w) break;
|
||||
eina_strbuf_append_char(sb, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
else eina_strbuf_append_char(sb, '\n');
|
||||
}
|
||||
}
|
||||
_grid_save_thaw();
|
||||
|
||||
if (!len) len = &len_backup;
|
||||
*len = eina_strbuf_length_get(sb);
|
||||
if (!*len)
|
||||
{
|
||||
eina_strbuf_free(sb);
|
||||
return NULL;
|
||||
}
|
||||
s = eina_strbuf_string_steal(sb);
|
||||
eina_strbuf_free(sb);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_link_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Event_Mouse_Down *ev;
|
||||
|
||||
ev = event;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
if (ev->button == 1)
|
||||
{
|
||||
sd->link.down.down = EINA_TRUE;
|
||||
sd->link.down.x = ev->canvas.x;
|
||||
sd->link.down.y = ev->canvas.y;
|
||||
}
|
||||
/* else if (ev->button == 3) */
|
||||
/* { */
|
||||
|
||||
/* } */
|
||||
}
|
||||
|
||||
static void
|
||||
_link_activate(Evas_Object *obj, Eina_Bool may_inline EINA_UNUSED)
|
||||
{
|
||||
Grid *sd;
|
||||
char buff[PATH_MAX], *s, *esc;
|
||||
const char *path = NULL, *cmd = NULL;
|
||||
Eina_Bool url = EINA_FALSE, email = EINA_FALSE, handled = EINA_FALSE;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||
|
||||
if (!sd->link.str) return;
|
||||
if (_util_link_is_url(sd->link.str))
|
||||
{
|
||||
if (casestartswith(sd->link.str, "file://"))
|
||||
path = sd->link.str + sizeof("file://") - 1;
|
||||
else
|
||||
url = EINA_TRUE;
|
||||
}
|
||||
else if (sd->link.str[0] == '/')
|
||||
path = sd->link.str;
|
||||
else if (_util_link_is_email(sd->link.str))
|
||||
email = EINA_TRUE;
|
||||
|
||||
if ((url) && (casestartswith(sd->link.str, "mailto:")))
|
||||
{
|
||||
email = EINA_TRUE;
|
||||
url = EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!(s = eina_str_escape(sd->link.str))) return;
|
||||
|
||||
if (email)
|
||||
{
|
||||
const char *p = s;
|
||||
|
||||
// run mail client
|
||||
cmd = "xdg-email";
|
||||
if (casestartswith(s, "mailto:"))
|
||||
p += sizeof("mailto:") - 1;
|
||||
|
||||
esc = ecore_file_escape_name(p);
|
||||
if (esc)
|
||||
{
|
||||
snprintf(buff, sizeof(buff), "%s %s", cmd, esc);
|
||||
free(esc);
|
||||
}
|
||||
}
|
||||
else if (path)
|
||||
{
|
||||
// locally accessible file
|
||||
cmd = "xdg-open";
|
||||
|
||||
esc = ecore_file_escape_name(s);
|
||||
if (esc)
|
||||
{
|
||||
/* int type; */
|
||||
/* type = media_src_type_get(sd->link.string); */
|
||||
/* if (may_inline && _should_inline(obj)) */
|
||||
/* { */
|
||||
/* if ((type == MEDIA_TYPE_IMG) || */
|
||||
/* (type == MEDIA_TYPE_SCALE) || */
|
||||
/* (type == MEDIA_TYPE_EDJE)) */
|
||||
/* { */
|
||||
/* evas_object_smart_callback_call(obj, "popup", NULL); */
|
||||
/* handled = EINA_TRUE; */
|
||||
/* } */
|
||||
/* else if (type == MEDIA_TYPE_MOV) */
|
||||
/* { */
|
||||
/* evas_object_smart_callback_call(obj, "popup", NULL); */
|
||||
/* handled = EINA_TRUE; */
|
||||
/* } */
|
||||
/* } */
|
||||
if (!handled)
|
||||
{
|
||||
/* if ((type == MEDIA_TYPE_IMG) || */
|
||||
/* (type == MEDIA_TYPE_SCALE) || */
|
||||
/* (type == MEDIA_TYPE_EDJE)) */
|
||||
/* { */
|
||||
/* if ((config->helper.local.image) && */
|
||||
/* (config->helper.local.image[0])) */
|
||||
/* cmd = config->helper.local.image; */
|
||||
/* } */
|
||||
/* else if (type == MEDIA_TYPE_MOV) */
|
||||
/* { */
|
||||
/* if ((config->helper.local.video) && */
|
||||
/* (config->helper.local.video[0])) */
|
||||
/* cmd = config->helper.local.video; */
|
||||
/* } */
|
||||
/* else */
|
||||
/* { */
|
||||
/* if ((config->helper.local.general) && */
|
||||
/* (config->helper.local.general[0])) */
|
||||
/* cmd = config->helper.local.general; */
|
||||
/* } */
|
||||
snprintf(buff, sizeof(buff), "%s %s", cmd, esc);
|
||||
free(esc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (url)
|
||||
{
|
||||
// remote file needs ecore-con-url
|
||||
cmd = "xdg-open";
|
||||
|
||||
esc = ecore_file_escape_name(s);
|
||||
if (esc)
|
||||
{
|
||||
/* int type; */
|
||||
|
||||
/* type = media_src_type_get(sd->link.string); */
|
||||
/* if (may_inline && _should_inline(obj)) */
|
||||
/* { */
|
||||
/* if ((type == MEDIA_TYPE_IMG) || */
|
||||
/* (type == MEDIA_TYPE_SCALE) || */
|
||||
/* (type == MEDIA_TYPE_EDJE)) */
|
||||
/* { */
|
||||
/* evas_object_smart_callback_call(obj, "popup", NULL); */
|
||||
/* handled = EINA_TRUE; */
|
||||
/* } */
|
||||
/* else if (type == MEDIA_TYPE_MOV) */
|
||||
/* { */
|
||||
/* evas_object_smart_callback_call(obj, "popup", NULL); */
|
||||
/* handled = EINA_TRUE; */
|
||||
/* } */
|
||||
/* } */
|
||||
if (!handled)
|
||||
{
|
||||
/* if ((type == MEDIA_TYPE_IMG) || */
|
||||
/* (type == MEDIA_TYPE_SCALE) || */
|
||||
/* (type == MEDIA_TYPE_EDJE)) */
|
||||
/* { */
|
||||
/* if ((config->helper.url.image) && */
|
||||
/* (config->helper.url.image[0])) */
|
||||
/* cmd = config->helper.url.image; */
|
||||
/* } */
|
||||
/* else if (type == MEDIA_TYPE_MOV) */
|
||||
/* { */
|
||||
/* if ((config->helper.url.video) && */
|
||||
/* (config->helper.url.video[0])) */
|
||||
/* cmd = config->helper.url.video; */
|
||||
/* } */
|
||||
/* else */
|
||||
/* { */
|
||||
/* if ((config->helper.url.general) && */
|
||||
/* (config->helper.url.general[0])) */
|
||||
/* cmd = config->helper.url.general; */
|
||||
/* } */
|
||||
snprintf(buff, sizeof(buff), "%s %s", cmd, esc);
|
||||
free(esc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free(s);
|
||||
return;
|
||||
}
|
||||
free(s);
|
||||
if (!handled) ecore_exe_run(buff, NULL);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_link_up_delay(void *data)
|
||||
{
|
||||
Grid *sd;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return EINA_FALSE;
|
||||
|
||||
sd->delayed_link_up_tmr = NULL;
|
||||
if (!sd->link.clicked) _link_activate(data, EINA_TRUE);
|
||||
sd->link.clicked = EINA_FALSE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_link_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Event_Mouse_Up *ev;
|
||||
|
||||
ev = event;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
if ((ev->button == 1) && (sd->link.down.down))
|
||||
{
|
||||
Evas_Coord dx, dy, size;
|
||||
|
||||
dx = abs(ev->canvas.x - sd->link.down.x);
|
||||
dy = abs(ev->canvas.y - sd->link.down.y);
|
||||
size = elm_config_finger_size_get();
|
||||
if ((dx <= size) && (dy <= size))
|
||||
{
|
||||
if (sd->delayed_link_up_tmr)
|
||||
ecore_timer_reset(sd->delayed_link_up_tmr);
|
||||
else
|
||||
{
|
||||
sd->delayed_link_up_tmr =
|
||||
ecore_timer_add(0.2, _cb_link_up_delay, data);
|
||||
}
|
||||
}
|
||||
sd->link.down.down = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_links_update(Evas_Object *obj, Grid *sd, Eina_Bool same_link, Eina_Bool same_geom)
|
||||
{
|
||||
Evas_Coord ox, oy, ow, oh;
|
||||
Evas_Object *o;
|
||||
int y = 0;
|
||||
|
||||
if (!sd) return;
|
||||
|
||||
if (!same_link)
|
||||
{
|
||||
/* FIXME: check link and reprobe */
|
||||
}
|
||||
|
||||
if (same_geom) return;
|
||||
if (sd->link.suspend) return;
|
||||
|
||||
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
||||
|
||||
EINA_LIST_FREE(sd->link.objs, o)
|
||||
evas_object_del(o);
|
||||
|
||||
if (!sd->link.str) return;
|
||||
|
||||
for (y = sd->link.y1; y <= sd->link.y2; y++)
|
||||
{
|
||||
o = edje_object_add(evas_object_evas_get(obj));
|
||||
evas_object_smart_member_add(o, obj);
|
||||
_theme_apply(o, "express/link");
|
||||
|
||||
if (y == sd->link.y1)
|
||||
{
|
||||
evas_object_move(o, ox + (sd->link.x1 * sd->font.chw),
|
||||
oy + (y * sd->font.chh));
|
||||
if (sd->link.y1 == sd->link.y2)
|
||||
evas_object_resize(o,
|
||||
((sd->link.x2 - sd->link.x1 + 1) * sd->font.chw),
|
||||
sd->font.chh);
|
||||
else
|
||||
evas_object_resize(o,
|
||||
((sd->grid.w - sd->link.x1) * sd->font.chw),
|
||||
sd->font.chh);
|
||||
}
|
||||
else if (y == sd->link.y2)
|
||||
{
|
||||
evas_object_move(o, ox, oy + (y * sd->font.chh));
|
||||
evas_object_resize(o, ((sd->link.x2 + 1) * sd->font.chw),
|
||||
sd->font.chh);
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_object_move(o, ox, oy + (y * sd->font.chh));
|
||||
evas_object_resize(o, (sd->grid.w * sd->font.chw),
|
||||
sd->font.chh);
|
||||
}
|
||||
|
||||
sd->link.objs = eina_list_append(sd->link.objs, o);
|
||||
evas_object_show(o);
|
||||
|
||||
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_cb_link_down, obj);
|
||||
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
|
||||
_cb_link_up, obj);
|
||||
/* evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, */
|
||||
/* _cb_link_move, obj); */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_links_remove(Grid *sd, Evas_Object *obj)
|
||||
{
|
||||
if (sd->link.str)
|
||||
{
|
||||
free(sd->link.str);
|
||||
sd->link.str = NULL;
|
||||
}
|
||||
|
||||
sd->link.x1 = -1;
|
||||
sd->link.y1 = -1;
|
||||
sd->link.x2 = -1;
|
||||
sd->link.y2 = -1;
|
||||
sd->link.suspend = EINA_FALSE;
|
||||
|
||||
_links_update(obj, sd, EINA_FALSE, EINA_FALSE);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
coord_back(int *x, int *y, int w, int h EINA_UNUSED)
|
||||
{
|
||||
(*x)--;
|
||||
if ((*x) < 0)
|
||||
{
|
||||
if ((*y) <= 0)
|
||||
{
|
||||
(*x)++;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
(*x) = (w - 1);
|
||||
(*y)--;
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
coord_forward(int *x, int *y, int w, int h)
|
||||
{
|
||||
(*x)++;
|
||||
if ((*x) >= w)
|
||||
{
|
||||
if ((*y) >= (h - 1))
|
||||
{
|
||||
(*x)--;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
(*x) = 0;
|
||||
(*y)++;
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
_link_find(Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r)
|
||||
{
|
||||
Grid *sd;
|
||||
char *s, endmatch = 0;
|
||||
int x1 = 0, x2 = 0, y1 = 0, y2 = 0, w = 0, h = 0, sc;
|
||||
size_t len = 0, plen = 0;
|
||||
Eina_Bool back = EINA_TRUE, forward = EINA_FALSE, esc = EINA_FALSE;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return NULL;
|
||||
|
||||
x1 = x2 = cx;
|
||||
y1 = y2 = cy;
|
||||
w = sd->grid.w;
|
||||
h = sd->grid.h;
|
||||
if ((w <= 0) || (h <= 0)) return NULL;
|
||||
sc = sd->scroll;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
plen = len;
|
||||
s = _selection_get(obj, x1, (y1 - sc), x2, (y2 - sc), &len);
|
||||
if (!s) break;
|
||||
if (back)
|
||||
{
|
||||
if (_util_link_is_protocol(s))
|
||||
{
|
||||
back = EINA_FALSE;
|
||||
forward = EINA_TRUE;
|
||||
|
||||
coord_back(&x1, &y1, w, h);
|
||||
free(s);
|
||||
plen = len;
|
||||
s = _selection_get(obj, x1, (y1 - sc), x2, (y2 - sc), &len);
|
||||
if (!s) break;
|
||||
|
||||
switch (s[0])
|
||||
{
|
||||
case '"': endmatch = '"'; break;
|
||||
case '\'': endmatch = '\''; break;
|
||||
case '`': endmatch = '`'; break;
|
||||
case '<': endmatch = '>'; break;
|
||||
case '[': endmatch = ']'; break;
|
||||
case '{': endmatch = '}'; break;
|
||||
case '(': endmatch = ')'; break;
|
||||
}
|
||||
|
||||
coord_forward(&x1, &y1, w, h);
|
||||
free(s);
|
||||
plen = len;
|
||||
s = _selection_get(obj, x1, (y1 - sc), x2, (y2 - sc), &len);
|
||||
if (!s) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (s[0])
|
||||
{
|
||||
case '"': endmatch = '"'; break;
|
||||
case '\'': endmatch = '\''; break;
|
||||
case '`': endmatch = '`'; break;
|
||||
case '<': endmatch = '>'; break;
|
||||
case '[': endmatch = ']'; break;
|
||||
case '{': endmatch = '}'; break;
|
||||
case '(': endmatch = ')'; break;
|
||||
}
|
||||
|
||||
if ((endmatch) || (isspace(s[0])))
|
||||
{
|
||||
back = EINA_FALSE;
|
||||
coord_forward(&x1, &y1, w, h);
|
||||
forward = EINA_TRUE;
|
||||
free(s);
|
||||
s = _selection_get(obj, x1, (y1 - sc), x2, (y2 - sc), &len);
|
||||
if (!s) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((forward) && (len >= 1))
|
||||
{
|
||||
char end;
|
||||
|
||||
end = s[len - 1];
|
||||
if (((len - plen) == 2) && (len >= 2))
|
||||
end = s[len - 2];
|
||||
|
||||
if ((end == endmatch) ||
|
||||
((!esc) && (isspace(end)) &&
|
||||
((end != '\n') || (end != '\r'))))
|
||||
{
|
||||
forward = EINA_FALSE;
|
||||
coord_back(&x2, &y2, w, h);
|
||||
endmatch = 0;
|
||||
}
|
||||
|
||||
esc = (end == '\\');
|
||||
}
|
||||
if ((back) && (!coord_back(&x1, &y1, w, h)))
|
||||
{
|
||||
back = EINA_FALSE;
|
||||
forward = EINA_TRUE;
|
||||
}
|
||||
if ((forward) && (!coord_forward(&x2, &y2, w, h)))
|
||||
forward = EINA_FALSE;
|
||||
if ((!back) && (!forward))
|
||||
{
|
||||
free(s);
|
||||
s = _selection_get(obj, x1, (y1 - sc), x2, (y2 - sc), &len);
|
||||
break;
|
||||
}
|
||||
free(s);
|
||||
s = NULL;
|
||||
}
|
||||
|
||||
if (s)
|
||||
{
|
||||
if ((len > 1) && (!endmatch))
|
||||
{
|
||||
Eina_Bool isf;
|
||||
|
||||
isf = _util_is_file(s);
|
||||
if ((isf) || (_util_link_is_email(s)) || (_util_link_is_url(s)))
|
||||
{
|
||||
if (x1r) *x1r = x1;
|
||||
if (y1r) *y1r = y1;
|
||||
if (x2r) *x2r = x2;
|
||||
if (y2r) *y2r = y2;
|
||||
|
||||
if ((isf) && (s[0] != '/'))
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = _util_local_path_get(obj, s);
|
||||
free(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_mouse_over_apply(Evas_Object *obj)
|
||||
{
|
||||
Grid *sd;
|
||||
char *str;
|
||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
Eina_Bool same_link = EINA_FALSE, same_geom = EINA_FALSE;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||
if ((sd->mouse.cx < 0) || (sd->mouse.cy < 0)) return;
|
||||
|
||||
str = _link_find(obj, sd->mouse.cx, sd->mouse.cy, &x1, &y1, &x2, &y2);
|
||||
if (!str)
|
||||
{
|
||||
_links_remove(sd, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sd->link.str) && (!strcmp(sd->link.str, str)))
|
||||
same_link = EINA_TRUE;
|
||||
|
||||
if (sd->link.str) free(sd->link.str);
|
||||
sd->link.str = str;
|
||||
|
||||
if ((x1 == sd->link.x1) && (y1 == sd->link.y1) &&
|
||||
(x2 == sd->link.x2) && (y2 == sd->link.y2))
|
||||
same_geom = EINA_TRUE;
|
||||
|
||||
if (((sd->link.suspend != 0) && (sd->link.objs)) ||
|
||||
((sd->link.suspend == 0) && (!sd->link.objs)))
|
||||
same_geom = EINA_FALSE;
|
||||
|
||||
sd->link.x1 = x1;
|
||||
sd->link.y1 = y1;
|
||||
sd->link.x2 = x2;
|
||||
sd->link.y2 = y2;
|
||||
|
||||
_links_update(obj, sd, same_link, same_geom);
|
||||
}
|
||||
|
||||
static void
|
||||
_mouse_over_suspend_pushpop(Evas_Object *obj, int dir)
|
||||
{
|
||||
Grid *sd;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||
|
||||
sd->link.suspend += dir;
|
||||
if (sd->link.suspend < 0) sd->link.suspend = 0;
|
||||
if (sd->link.suspend)
|
||||
{
|
||||
if (sd->anim) ecore_animator_del(sd->anim);
|
||||
sd->anim = NULL;
|
||||
}
|
||||
_smart_queue_update(obj, sd);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_delayed_size(void *data)
|
||||
{
|
||||
|
@ -35,6 +771,113 @@ _cb_delayed_size(void *data)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_mouse_over_delay(void *data)
|
||||
{
|
||||
Grid *sd;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return EINA_FALSE;
|
||||
|
||||
sd->delayed_mouse_over_tmr = NULL;
|
||||
_mouse_over_apply(data);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_mouse_move_job(void *data)
|
||||
{
|
||||
Grid *sd;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
sd->mouse_move_job = NULL;
|
||||
if (sd->delayed_mouse_over_tmr)
|
||||
ecore_timer_reset(sd->delayed_mouse_over_tmr);
|
||||
else
|
||||
{
|
||||
sd->delayed_mouse_over_tmr =
|
||||
ecore_timer_add(0.05, _cb_mouse_over_delay, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Event_Mouse_In *ev;
|
||||
int cx = 0, cy = 0;
|
||||
|
||||
ev = event;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
_coord_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
|
||||
sd->mouse.cx = cx;
|
||||
sd->mouse.cy = cy;
|
||||
_mouse_over_suspend_pushpop(data, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Event_Mouse_Out *ev;
|
||||
|
||||
ev = event;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
_mouse_over_suspend_pushpop(data, 1);
|
||||
|
||||
if ((ev->canvas.x == 0) || (ev->canvas.y == 0))
|
||||
{
|
||||
sd->mouse.cx = -1;
|
||||
sd->mouse.cy = -1;
|
||||
sd->link.suspend = EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int cx = 0, cy = 0;
|
||||
|
||||
_coord_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy);
|
||||
sd->mouse.cx = cx;
|
||||
sd->mouse.cy = cy;
|
||||
}
|
||||
|
||||
_links_remove(sd, data);
|
||||
|
||||
if (sd->delayed_mouse_over_tmr) ecore_timer_del(sd->delayed_mouse_over_tmr);
|
||||
sd->delayed_mouse_over_tmr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Grid *sd;
|
||||
Evas_Event_Mouse_Move *ev;
|
||||
int cx = 0, cy = 0;
|
||||
|
||||
ev = event;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
_coord_to_cursor(data, ev->cur.canvas.x, ev->cur.canvas.y, &cx, &cy);
|
||||
|
||||
if ((sd->mouse.cx == cx) && (sd->mouse.cy == cy)) return;
|
||||
|
||||
sd->mouse.cx = cx;
|
||||
sd->mouse.cy = cy;
|
||||
|
||||
if (sd->mouse_move_job) ecore_job_del(sd->mouse_move_job);
|
||||
sd->mouse_move_job = ecore_job_add(_cb_mouse_move_job, data);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
|
@ -60,6 +903,7 @@ _cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED
|
|||
if (evas_key_modifier_is_set(ev->modifiers, "Alt")) return;
|
||||
if (evas_key_modifier_is_set(ev->modifiers, "Shift")) return;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
sd->scroll -= (ev->z * 4);
|
||||
|
@ -88,6 +932,17 @@ _cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, v
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
|
||||
{
|
||||
Grid *sd;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return;
|
||||
|
||||
_links_remove(sd, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_selection_set(Evas_Object *obj, Eina_Bool enabled)
|
||||
{
|
||||
|
@ -115,6 +970,7 @@ _smart_add(Evas_Object *obj)
|
|||
evas_object_smart_data_set(obj, sd);
|
||||
_parent_sc.add(obj);
|
||||
|
||||
sd->obj = obj;
|
||||
sd->evas = evas_object_evas_get(obj);
|
||||
|
||||
/* create textgrid */
|
||||
|
@ -131,12 +987,23 @@ _smart_add(Evas_Object *obj)
|
|||
evas_object_show(sd->o_event);
|
||||
|
||||
/* TODO: finish callbacks */
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_IN,
|
||||
_cb_mouse_in, obj);
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_OUT,
|
||||
_cb_mouse_out, obj);
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_MOVE,
|
||||
_cb_mouse_move, obj);
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_cb_mouse_down, obj);
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_WHEEL,
|
||||
_cb_mouse_wheel, obj);
|
||||
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_KEY_DOWN,
|
||||
|
||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
|
||||
_cb_key_down, obj);
|
||||
evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT,
|
||||
_cb_focus_out, obj);
|
||||
|
||||
sd->link.suspend = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -245,6 +1112,7 @@ _smart_apply(Evas_Object *obj)
|
|||
int x, y, w;// h;
|
||||
int ch1 = 0, ch2 = 0, inv = 0;
|
||||
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||
|
||||
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
||||
|
@ -415,15 +1283,14 @@ _smart_size(Evas_Object *obj, int w, int h, Eina_Bool force)
|
|||
static Eina_Bool
|
||||
_smart_change(void *data)
|
||||
{
|
||||
Evas_Object *obj;
|
||||
Grid *sd;
|
||||
|
||||
obj = data;
|
||||
if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
|
||||
/* try to get the objects smart data */
|
||||
if (!(sd = evas_object_smart_data_get(data))) return EINA_FALSE;
|
||||
|
||||
sd->anim = NULL;
|
||||
|
||||
_smart_apply(obj);
|
||||
_smart_apply(data);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
@ -720,7 +1587,7 @@ _line_rewrap(Grid *sd, int y_start, int y_end, Grid_Cell *cells2, Grid_Save **ba
|
|||
}
|
||||
|
||||
static void
|
||||
_scroll(Grid *sd, int direction, int start_y EINA_UNUSED, int end_y EINA_UNUSED)
|
||||
_scroll(Grid *sd, int direction, int start_y, int end_y)
|
||||
{
|
||||
if (sd->scroll > 0)
|
||||
{
|
||||
|
@ -737,6 +1604,12 @@ _scroll(Grid *sd, int direction, int start_y EINA_UNUSED, int end_y EINA_UNUSED)
|
|||
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
if (sd->link.str)
|
||||
{
|
||||
if ((sd->link.y1 <= end_y) && (sd->link.y2 >= start_y))
|
||||
_links_remove(sd, sd->obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue