link: display tooltip on colors like #ff00ff
This commit is contained in:
parent
f5fe32f70b
commit
127f0987ee
|
@ -549,7 +549,9 @@ _should_inline(const Evas_Object *obj)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* Need to be freed */
|
||||
/*
|
||||
* Returned string needs to be freed.
|
||||
* Does not handle colors */
|
||||
const char *
|
||||
termio_link_get(const Evas_Object *obj,
|
||||
Eina_Bool *from_escape_code)
|
||||
|
@ -1341,6 +1343,31 @@ _cb_link_move(void *data,
|
|||
}
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_color_tooltip_content(void *data,
|
||||
Evas_Object *obj,
|
||||
Evas_Object *_tt EINA_UNUSED)
|
||||
{
|
||||
Termio *sd = data;
|
||||
Evas_Object *o;
|
||||
|
||||
o = evas_object_rectangle_add(evas_object_evas_get(obj));
|
||||
evas_object_size_hint_min_set(o, 80, 80);
|
||||
evas_object_color_set(o,
|
||||
sd->link.color.r,
|
||||
sd->link.color.g,
|
||||
sd->link.color.b,
|
||||
sd->link.color.a);
|
||||
return o;
|
||||
}
|
||||
|
||||
static void
|
||||
_color_tooltip(Evas_Object *obj,
|
||||
Termio *sd)
|
||||
{
|
||||
elm_object_tooltip_content_cb_set(obj, _color_tooltip_content, sd, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_update_link(Termio *sd, Eina_Bool same_geom)
|
||||
{
|
||||
|
@ -1353,7 +1380,7 @@ _update_link(Termio *sd, Eina_Bool same_geom)
|
|||
EINA_SAFETY_ON_NULL_RETURN(sd);
|
||||
obj = sd->self;
|
||||
|
||||
if (sd->link.id)
|
||||
if (sd->link.id || sd->link.is_color)
|
||||
{
|
||||
same_geom = EINA_FALSE;
|
||||
}
|
||||
|
@ -1376,7 +1403,7 @@ _update_link(Termio *sd, Eina_Bool same_geom)
|
|||
else
|
||||
evas_object_del(o);
|
||||
}
|
||||
if (!sd->link.string)
|
||||
if (!sd->link.string && !sd->link.is_color)
|
||||
return;
|
||||
|
||||
popup_exists = main_term_popup_exists(sd->term);
|
||||
|
@ -1422,9 +1449,16 @@ _update_link(Termio *sd, Eina_Bool same_geom)
|
|||
_cb_link_up, obj);
|
||||
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE,
|
||||
_cb_link_move, obj);
|
||||
if ((!popup_exists) && link_is_email(sd->link.string))
|
||||
if (!popup_exists)
|
||||
{
|
||||
gravatar_tooltip(o, sd->config, sd->link.string);
|
||||
if (link_is_email(sd->link.string))
|
||||
{
|
||||
gravatar_tooltip(o, sd->config, sd->link.string);
|
||||
}
|
||||
if (sd->link.is_color)
|
||||
{
|
||||
_color_tooltip(o, sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1443,6 +1477,11 @@ termio_remove_links(Termio *sd)
|
|||
sd->link.y2 = -1;
|
||||
sd->link.suspend = 0;
|
||||
sd->link.id = 0;
|
||||
sd->link.is_color = EINA_FALSE;
|
||||
sd->link.color.r = 0;
|
||||
sd->link.color.g = 0;
|
||||
sd->link.color.b = 0;
|
||||
sd->link.color.a = 0;
|
||||
_update_link(sd, same_geom);
|
||||
}
|
||||
|
||||
|
@ -2362,6 +2401,18 @@ _smart_mouseover_apply(Termio *sd)
|
|||
&x1, &y1, &x2, &y2);
|
||||
if (!s)
|
||||
{
|
||||
uint8_t r = 0, g = 0, b = 0, a = 0;
|
||||
/* TODO: boris: check config */
|
||||
if (termio_color_find(sd->self, sd->mouse.cx, sd->mouse.cy,
|
||||
&x1, &y1, &x2, &y2, &r, &g, &b, &a))
|
||||
{
|
||||
sd->link.is_color = EINA_TRUE;
|
||||
sd->link.color.r = r;
|
||||
sd->link.color.g = g;
|
||||
sd->link.color.b = b;
|
||||
sd->link.color.a = a;
|
||||
goto found;
|
||||
}
|
||||
termio_remove_links(sd);
|
||||
return;
|
||||
}
|
||||
|
@ -2393,6 +2444,7 @@ _smart_mouseover_apply(Termio *sd)
|
|||
eina_stringshare_del(sd->link.string);
|
||||
sd->link.string = eina_stringshare_add(s);
|
||||
|
||||
found:
|
||||
if ((x1 == sd->link.x1) && (y1 == sd->link.y1) &&
|
||||
(x2 == sd->link.x2) && (y2 == sd->link.y2))
|
||||
same_geom = EINA_TRUE;
|
||||
|
|
|
@ -34,9 +34,16 @@ struct _Termio
|
|||
struct {
|
||||
const char *string;
|
||||
int x1, y1, x2, y2;
|
||||
Eina_Bool is_color;
|
||||
int suspend;
|
||||
uint16_t id;
|
||||
Eina_List *objs;
|
||||
struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
} color;
|
||||
struct {
|
||||
Evas_Object *dndobj;
|
||||
Evas_Coord x, y;
|
||||
|
|
|
@ -625,3 +625,231 @@ end:
|
|||
ty_sb_free(&sb);
|
||||
return s;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_is_authorized_in_color(const int codepoint)
|
||||
{
|
||||
switch (codepoint)
|
||||
{
|
||||
case '#': EINA_FALLTHROUGH;
|
||||
case '0': EINA_FALLTHROUGH;
|
||||
case '1': EINA_FALLTHROUGH;
|
||||
case '2': EINA_FALLTHROUGH;
|
||||
case '3': EINA_FALLTHROUGH;
|
||||
case '4': EINA_FALLTHROUGH;
|
||||
case '5': EINA_FALLTHROUGH;
|
||||
case '6': EINA_FALLTHROUGH;
|
||||
case '7': EINA_FALLTHROUGH;
|
||||
case '8': EINA_FALLTHROUGH;
|
||||
case '9': EINA_FALLTHROUGH;
|
||||
case 'a': EINA_FALLTHROUGH;
|
||||
case 'A': EINA_FALLTHROUGH;
|
||||
case 'b': EINA_FALLTHROUGH;
|
||||
case 'B': EINA_FALLTHROUGH;
|
||||
case 'c': EINA_FALLTHROUGH;
|
||||
case 'C': EINA_FALLTHROUGH;
|
||||
case 'd': EINA_FALLTHROUGH;
|
||||
case 'D': EINA_FALLTHROUGH;
|
||||
case 'e': EINA_FALLTHROUGH;
|
||||
case 'E': EINA_FALLTHROUGH;
|
||||
case 'f': EINA_FALLTHROUGH;
|
||||
case 'F':
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_parse_hex(char c, uint8_t *v)
|
||||
{
|
||||
if (c < '0')
|
||||
return EINA_FALSE;
|
||||
if (c <= '9')
|
||||
{
|
||||
*v = c - '0';
|
||||
return EINA_TRUE;
|
||||
}
|
||||
if (c < 'A')
|
||||
return EINA_FALSE;
|
||||
if (c <= 'F')
|
||||
{
|
||||
*v = 10 + c - 'A';
|
||||
return EINA_TRUE;
|
||||
}
|
||||
if (c < 'a')
|
||||
return EINA_FALSE;
|
||||
if (c <= 'f')
|
||||
{
|
||||
*v = 10 + c - 'a';
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_parse_2hex(char *s, uint8_t *v)
|
||||
{
|
||||
uint8_t v0, v1;
|
||||
if (!_parse_hex(s[0], &v0))
|
||||
return EINA_FALSE;
|
||||
if (!_parse_hex(s[1], &v1))
|
||||
return EINA_FALSE;
|
||||
*v = v0 << 4 | v1;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
termio_color_find(const Evas_Object *obj, int cx, int cy,
|
||||
int *x1r, int *y1r, int *x2r, int *y2r,
|
||||
uint8_t *rp, uint8_t *gp, uint8_t *bp, uint8_t *ap)
|
||||
{
|
||||
int x1, x2, y1, y2, w = 0, h = 0, sc;
|
||||
//const char authorized[] = "#0123456789aAbBcCdDeEfFrghsoltun() ,+/";
|
||||
Eina_Bool goback = EINA_TRUE,
|
||||
goforward = EINA_FALSE;
|
||||
struct ty_sb sb = {.buf = NULL, .gap = 0, .len = 0, .alloc = 0};
|
||||
Termpty *ty = termio_pty_get(obj);
|
||||
int res;
|
||||
char txt[8];
|
||||
int txtlen = 0;
|
||||
Eina_Bool found = EINA_FALSE;
|
||||
int codepoint;
|
||||
uint8_t r, g, b, a = 255;
|
||||
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ty, EINA_FALSE);
|
||||
|
||||
x1 = x2 = cx;
|
||||
y1 = y2 = cy;
|
||||
termio_size_get(obj, &w, &h);
|
||||
if ((w <= 0) || (h <= 0)) goto end;
|
||||
|
||||
sc = termio_scroll_get(obj);
|
||||
|
||||
termpty_backlog_lock();
|
||||
|
||||
y1 -= sc;
|
||||
y2 -= sc;
|
||||
|
||||
/* TODO: boris */
|
||||
res = _txt_at(ty, &x1, &y1, txt, &txtlen, &codepoint);
|
||||
if ((res != 0) || (txtlen == 0))
|
||||
goto end;
|
||||
if (!_is_authorized_in_color(codepoint))
|
||||
goto end;
|
||||
res = ty_sb_add(&sb, txt, txtlen);
|
||||
if (res < 0) goto end;
|
||||
|
||||
while (goback)
|
||||
{
|
||||
int new_x1 = x1, new_y1 = y1;
|
||||
|
||||
res = _txt_prev_at(ty, &new_x1, &new_y1, txt, &txtlen, &codepoint);
|
||||
if ((res != 0) || (txtlen == 0))
|
||||
{
|
||||
goback = EINA_FALSE;
|
||||
goforward = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
res = ty_sb_prepend(&sb, txt, txtlen);
|
||||
if (res < 0) goto end;
|
||||
if (!_is_authorized_in_color(codepoint))
|
||||
{
|
||||
ty_sb_lskip(&sb, txtlen);
|
||||
goback = EINA_FALSE;
|
||||
goforward = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
x1 = new_x1;
|
||||
y1 = new_y1;
|
||||
}
|
||||
|
||||
while (goforward)
|
||||
{
|
||||
int new_x2 = x2, new_y2 = y2;
|
||||
|
||||
/* Check if the previous char is a delimiter */
|
||||
res = _txt_next_at(ty, &new_x2, &new_y2, txt, &txtlen, &codepoint);
|
||||
if ((res != 0) || (txtlen == 0))
|
||||
{
|
||||
goforward = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_is_authorized_in_color(codepoint))
|
||||
{
|
||||
goforward = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
res = ty_sb_add(&sb, txt, txtlen);
|
||||
if (res < 0) goto end;
|
||||
|
||||
x2 = new_x2;
|
||||
y2 = new_y2;
|
||||
}
|
||||
|
||||
if (!sb.len)
|
||||
goto end;
|
||||
|
||||
if (sb.buf[0] == '#')
|
||||
{
|
||||
ty_sb_lskip(&sb, 1);
|
||||
switch (sb.len)
|
||||
{
|
||||
case 3:
|
||||
if ((!_parse_hex(sb.buf[0], &r)) ||
|
||||
(!_parse_hex(sb.buf[1], &g)) ||
|
||||
(!_parse_hex(sb.buf[2], &b)))
|
||||
goto end;
|
||||
r <<= 4;
|
||||
g <<= 4;
|
||||
b <<= 4;
|
||||
break;
|
||||
case 4:
|
||||
if ((!_parse_hex(sb.buf[0], &r)) ||
|
||||
(!_parse_hex(sb.buf[1], &g)) ||
|
||||
(!_parse_hex(sb.buf[2], &b)) ||
|
||||
(!_parse_hex(sb.buf[3], &a)))
|
||||
goto end;
|
||||
r <<= 4;
|
||||
g <<= 4;
|
||||
b <<= 4;
|
||||
a <<= 4;
|
||||
break;
|
||||
case 6:
|
||||
if ((!_parse_2hex(&sb.buf[0], &r)) ||
|
||||
(!_parse_2hex(&sb.buf[2], &g)) ||
|
||||
(!_parse_2hex(&sb.buf[4], &b)))
|
||||
goto end;
|
||||
break;
|
||||
case 8:
|
||||
if ((!_parse_2hex(&sb.buf[0], &r)) ||
|
||||
(!_parse_2hex(&sb.buf[2], &g)) ||
|
||||
(!_parse_2hex(&sb.buf[4], &b)) ||
|
||||
(!_parse_2hex(&sb.buf[6], &a)))
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
goto end;
|
||||
}
|
||||
found = EINA_TRUE;
|
||||
}
|
||||
|
||||
end:
|
||||
termpty_backlog_unlock();
|
||||
ty_sb_free(&sb);
|
||||
if (found)
|
||||
{
|
||||
if (rp) *rp = r;
|
||||
if (gp) *gp = g;
|
||||
if (bp) *bp = b;
|
||||
if (ap) *ap = a;
|
||||
if (x1r) *x1r = x1;
|
||||
if (y1r) *y1r = y1 + sc;
|
||||
if (x2r) *x2r = x2;
|
||||
if (y2r) *y2r = y2 + sc;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
#define _TERMIO_LINK_H__ 1
|
||||
|
||||
char *termio_link_find(const Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r);
|
||||
Eina_Bool
|
||||
termio_color_find(const Evas_Object *obj, int cx, int cy,
|
||||
int *x1r, int *y1r, int *x2r, int *y2r,
|
||||
uint8_t *rp, uint8_t *gp, uint8_t *bp, uint8_t *ap);
|
||||
Eina_Bool link_is_protocol(const char *str);
|
||||
Eina_Bool link_is_file(const char *str);
|
||||
Eina_Bool link_is_url(const char *str);
|
||||
|
|
Loading…
Reference in New Issue