forked from enlightenment/efl
evas: Implement filter_data_set for textblock
This is a function that allows passing variables from C or EDC to the filter's Lua code. Useful in particular for color classes from EDC. This data would be the global data but we could eventually add a markup tag to specify a data value per filter instance. For now a single data value per tb object should be more than enough though.
This commit is contained in:
parent
4453044d84
commit
1512741b48
|
@ -43,8 +43,9 @@ static const Filter_Image images_cloud[] = {
|
|||
static const Filter templates[] = {
|
||||
{ "Custom", NULL, NULL },
|
||||
{ "Black shadow",
|
||||
"if not myColor then myColor = color('yellow') end\n"
|
||||
"blur { 6, ox = 2, oy = 2, color = 'black' }\n"
|
||||
"blend {}", NULL },
|
||||
"blend { color = myColor }", NULL },
|
||||
{ "Fire glow",
|
||||
"a = buffer { 'alpha' }\n"
|
||||
"grow { 10, dst = a }\n"
|
||||
|
@ -71,8 +72,8 @@ static const Filter templates[] = {
|
|||
"blend { color = 'black' }\n"
|
||||
"mask { input, b }\n", NULL },
|
||||
{ "Rocking it",
|
||||
"padding_set { 40 }\n"
|
||||
"local len = state.scale * 10\n\n"
|
||||
"padding_set { len * 2 }\n"
|
||||
"a = buffer { 'alpha' }\n"
|
||||
"grow { len / 2, dst = a }\n"
|
||||
"blur { len * 2, oy = len, ox = len / 2, color = 'black', src = a }\n"
|
||||
|
@ -221,12 +222,6 @@ _textblock_resize(void *data EINA_UNUSED, const Efl_Event *ev)
|
|||
efl_gfx_size_hint_min_set(ev->object, w + l + r, h + t + b);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_img_tooltip(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *tt)
|
||||
{
|
||||
return efl_add(EFL_UI_TEXT_CLASS, tt, efl_text_set(efl_added, efl_name_get(tt)));
|
||||
}
|
||||
|
||||
static void
|
||||
_img_click(void *data, const Efl_Event *ev)
|
||||
{
|
||||
|
@ -274,6 +269,24 @@ _flip_click(void *data, const Efl_Event *ev EINA_UNUSED)
|
|||
efl_ui_flip_go(flip, EFL_UI_FLIP_CROSS_FADE);
|
||||
}
|
||||
|
||||
static void
|
||||
_colsel_cb(void *data, const Efl_Event *ev)
|
||||
{
|
||||
Eo *win = data;
|
||||
Eo *colsel = ev->object;
|
||||
Eo *text, *tb;
|
||||
int r = 0, g = 0, b = 0, a = 255;
|
||||
char buf[64];
|
||||
|
||||
text = efl_key_wref_get(win, "text");
|
||||
tb = efl_key_wref_get(win, "textblock");
|
||||
elm_colorselector_color_get(colsel, &r, &g, &b, &a);
|
||||
sprintf(buf, "color(%d, %d, %d, %d)", r, g, b, a);
|
||||
|
||||
efl_gfx_filter_data_set(text, efl_name_get(colsel), buf, 1);
|
||||
efl_gfx_filter_data_set(tb, efl_name_get(colsel), buf, 1);
|
||||
}
|
||||
|
||||
void
|
||||
test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
|
@ -332,36 +345,63 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
|
|||
}
|
||||
|
||||
{
|
||||
size_t k;
|
||||
|
||||
box2 = efl_add(EFL_UI_BOX_CLASS, win,
|
||||
efl_orientation_set(efl_added, EFL_ORIENT_HORIZONTAL),
|
||||
efl_gfx_size_hint_weight_set(efl_added, 1.0, 0.0),
|
||||
efl_gfx_size_hint_align_set(efl_added, 0.0, 0.5),
|
||||
efl_gfx_size_hint_align_set(efl_added, -1.0, 0.5),
|
||||
efl_pack_padding_set(efl_added, 5, 5, 1),
|
||||
efl_gfx_size_hint_margin_set(efl_added, 5, 5, 5, 5),
|
||||
efl_pack_align_set(efl_added, 0, 0.5));
|
||||
efl_pack(box, box2);
|
||||
|
||||
for (k = 0; k < EINA_C_ARRAY_LENGTH(images); k++)
|
||||
for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(images); k++)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (!images[k].path) break;
|
||||
snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), images[k].path);
|
||||
o = efl_add(EFL_UI_IMAGE_CLASS, win,
|
||||
efl_gfx_size_hint_weight_set(efl_added, 1.0, 0.0),
|
||||
efl_gfx_size_hint_weight_set(efl_added, 0.0, 0.0),
|
||||
efl_gfx_size_hint_align_set(efl_added, 0.5, 0.5),
|
||||
efl_gfx_size_hint_max_set(efl_added, ELM_SCALE_SIZE(48), ELM_SCALE_SIZE(48)),
|
||||
efl_gfx_size_hint_min_set(efl_added, ELM_SCALE_SIZE(48), ELM_SCALE_SIZE(48)),
|
||||
efl_file_set(efl_added, buf, NULL),
|
||||
efl_name_set(efl_added, images[k].src_name),
|
||||
elm_object_tooltip_text_set(efl_added, images[k].src_name),
|
||||
efl_gfx_visible_set(efl_added, 1));
|
||||
elm_object_tooltip_content_cb_set(o, _img_tooltip, NULL, NULL); // GRRRRR
|
||||
efl_event_callback_add(o, EFL_UI_EVENT_CLICKED, _img_click, win);
|
||||
efl_pack(box2, o);
|
||||
}
|
||||
|
||||
const struct { int r, g, b, a; } colors[] = {
|
||||
{ 255, 255, 255, 255 },
|
||||
{ 0, 0, 0, 255 },
|
||||
{ 64, 64, 64, 255 },
|
||||
{ 128, 128, 128, 255 },
|
||||
{ 196, 196, 196, 255 },
|
||||
{ 255, 0, 0, 255 },
|
||||
{ 0, 255, 0, 255 },
|
||||
{ 0, 0, 255, 255 },
|
||||
{ 255, 255, 0, 255 },
|
||||
{ 255, 0, 255, 255 },
|
||||
{ 0, 255, 255, 255 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
o = efl_add(ELM_COLORSELECTOR_CLASS, win,
|
||||
efl_gfx_size_hint_weight_set(efl_added, 1.0, 0),
|
||||
efl_gfx_size_hint_align_set(efl_added, -1.0, 0),
|
||||
elm_colorselector_mode_set(efl_added, ELM_COLORSELECTOR_PALETTE),
|
||||
efl_gfx_size_hint_max_set(efl_added, -1, ELM_SCALE_SIZE(48 * 2)),
|
||||
efl_name_set(efl_added, "myColor"),
|
||||
elm_object_tooltip_text_set(efl_added, "Pick a color to use as variable 'myColor'"),
|
||||
efl_event_callback_add(efl_added, ELM_COLORSELECTOR_EVENT_CHANGED, _colsel_cb, win),
|
||||
efl_gfx_visible_set(efl_added, 1));
|
||||
efl_pack(box2, o);
|
||||
|
||||
for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(colors); k++)
|
||||
elm_colorselector_palette_color_add(o, colors[k].r, colors[k].g, colors[k].b, colors[k].a);
|
||||
|
||||
efl_gfx_visible_set(box2, 1);
|
||||
}
|
||||
|
||||
|
@ -402,16 +442,16 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
|
|||
efl_pack_align_set(efl_added, 0.5, 0.5));
|
||||
efl_pack(flip, box2);
|
||||
|
||||
const char *codes[] = {
|
||||
"padding_set{20} blur{3} blend{}",
|
||||
"blur{15,color='red'} blend{}",
|
||||
"blend{}"
|
||||
const struct { const char *name, *code; } programs [] = {
|
||||
{ "one", "blur { 5, color = 'darkblue' } blend {}" },
|
||||
{ "two", "blur { 15, color = 'red' } blend {}" },
|
||||
{ "main", "blend {}" }
|
||||
};
|
||||
const char *names[] = {
|
||||
"one",
|
||||
"two",
|
||||
"main"
|
||||
|
||||
const struct { const char *name, *value; int exec; } prg_data [] = {
|
||||
{ "myColor", "color(255, 0, 255)", EINA_TRUE },
|
||||
};
|
||||
|
||||
const char *tbtxt = "Classic <gfx_filter='one'>hello</> world!<br>"
|
||||
"And <gfx_filter='two'>This filter over<br>"
|
||||
"multiple lines</> :)<br/>"
|
||||
|
@ -422,8 +462,10 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
|
|||
efl_event_callback_add(o, EFL_GFX_EVENT_RESIZE, _textblock_resize, NULL);
|
||||
Evas_Textblock_Style *st = evas_textblock_style_new();
|
||||
evas_textblock_style_set(st, "DEFAULT='font=Sans font_size=20 color=#FFF wrap=word'");
|
||||
for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(codes); k++)
|
||||
efl_gfx_filter_program_set(o, codes[k], names[k]);
|
||||
for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(programs); k++)
|
||||
efl_gfx_filter_program_set(o, programs[k].code, programs[k].name);
|
||||
for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(prg_data); k++)
|
||||
efl_gfx_filter_data_set(o, prg_data[k].name, prg_data[k].value, prg_data[k].exec);
|
||||
evas_object_textblock_style_set(o, st);
|
||||
evas_object_textblock_text_markup_set(o, tbtxt);
|
||||
efl_canvas_object_scale_set(o, elm_config_scale_get());
|
||||
|
|
|
@ -368,6 +368,7 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text, Efl.Canvas.Filter.Internal)
|
|||
Efl.Canvas.Object.paragraph_direction { get; set; }
|
||||
Efl.Text.text { get; set; }
|
||||
Efl.Gfx.Filter.filter_program { get; set; }
|
||||
Efl.Gfx.Filter.filter_data { get; set; }
|
||||
Efl.Canvas.Filter.Internal.filter_dirty;
|
||||
Efl.Canvas.Filter.Internal.filter_input_render;
|
||||
Efl.Canvas.Filter.Internal.filter_state_prepare;
|
||||
|
|
|
@ -461,6 +461,7 @@ _efl_canvas_filter_internal_efl_gfx_filter_filter_source_set(Eo *eo_obj, Evas_Fi
|
|||
eina_hash_add(fcow->sources, pb->name, pb);
|
||||
evas_filter_program_source_set_all(fcow->chain, fcow->sources);
|
||||
evas_filter_program_data_set_all(fcow->chain, fcow->data);
|
||||
evas_filter_program_parse(fcow->chain, fcow->code);
|
||||
|
||||
// Update object
|
||||
update:
|
||||
|
@ -658,6 +659,7 @@ _efl_canvas_filter_internal_efl_gfx_filter_filter_data_set(Eo *eo_obj, Evas_Filt
|
|||
fcow->data = eina_inlist_append(fcow->data, EINA_INLIST_GET(db));
|
||||
}
|
||||
evas_filter_program_data_set_all(fcow->chain, fcow->data);
|
||||
evas_filter_program_parse(fcow->chain, fcow->code);
|
||||
fcow->changed = 1;
|
||||
}
|
||||
FCOW_END(fcow, pd);
|
||||
|
|
|
@ -597,6 +597,7 @@ struct _Evas_Object_Textblock
|
|||
} formatted, native;
|
||||
struct {
|
||||
Efl_Canvas_Text_Filter_Program *programs;
|
||||
Evas_Filter_Data_Binding *data_bindings;
|
||||
} gfx_filter;
|
||||
Eina_Bool redraw : 1;
|
||||
Eina_Bool changed : 1;
|
||||
|
@ -4344,6 +4345,7 @@ _filter_program_find(Efl_Canvas_Text_Data *o, const char *name)
|
|||
{
|
||||
Efl_Canvas_Text_Filter_Program *prg;
|
||||
|
||||
if (!name) return NULL;
|
||||
EINA_INLIST_FOREACH(o->gfx_filter.programs, prg)
|
||||
{
|
||||
if (eina_streq(name, prg->name))
|
||||
|
@ -4361,9 +4363,11 @@ _format_filter_program_get(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Format
|
|||
Evas_Filter_Program *pgm;
|
||||
|
||||
filter = fmt->gfx_filter;
|
||||
if (!filter->name) return NULL;
|
||||
if (!filter) return NULL;
|
||||
|
||||
program = _filter_program_find(o, filter->name);
|
||||
if (!program) return NULL;
|
||||
|
||||
if (program->changed)
|
||||
{
|
||||
evas_filter_program_del(program->pgm);
|
||||
|
@ -4372,8 +4376,8 @@ _format_filter_program_get(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Format
|
|||
pgm = program->pgm;
|
||||
if (!pgm)
|
||||
{
|
||||
// TODO: data set
|
||||
pgm = evas_filter_program_new(program->name, EINA_FALSE);
|
||||
evas_filter_program_data_set_all(pgm, EINA_INLIST_GET(o->gfx_filter.data_bindings));
|
||||
if (!evas_filter_program_parse(pgm, program->code))
|
||||
{
|
||||
evas_filter_program_del(pgm);
|
||||
|
@ -12844,13 +12848,34 @@ _efl_canvas_text_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_
|
|||
efl_destructor(efl_super(eo_obj, MY_CLASS));
|
||||
}
|
||||
|
||||
// testing this macro...
|
||||
#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
|
||||
|
||||
static void
|
||||
evas_object_textblock_free(Evas_Object *eo_obj)
|
||||
{
|
||||
Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||
Efl_Canvas_Text_Filter_Program *prg;
|
||||
Evas_Filter_Data_Binding *db;
|
||||
|
||||
_evas_object_textblock_clear(eo_obj);
|
||||
evas_object_textblock_style_set(eo_obj, NULL);
|
||||
|
||||
EINA_INLIST_FREE(o->gfx_filter.programs, prg)
|
||||
{
|
||||
EINA_INLIST_REMOVE(o->gfx_filter.programs, prg);
|
||||
eina_stringshare_del(prg->name);
|
||||
eina_stringshare_del(prg->code);
|
||||
free(prg);
|
||||
}
|
||||
EINA_INLIST_FREE(o->gfx_filter.data_bindings, db)
|
||||
{
|
||||
EINA_INLIST_REMOVE(o->gfx_filter.data_bindings, db);
|
||||
eina_stringshare_del(db->name);
|
||||
eina_stringshare_del(db->value);
|
||||
free(db);
|
||||
}
|
||||
|
||||
while (evas_object_textblock_style_user_peek(eo_obj))
|
||||
{
|
||||
evas_object_textblock_style_user_pop(eo_obj);
|
||||
|
@ -13659,10 +13684,10 @@ _efl_canvas_text_efl_gfx_filter_filter_program_set(Eo *eo_obj, Efl_Canvas_Text_D
|
|||
}
|
||||
eina_stringshare_replace(&prg->code, code);
|
||||
prg->changed = EINA_TRUE;
|
||||
|
||||
pd->format_changed = EINA_TRUE;
|
||||
_evas_textblock_invalidate_all(pd);
|
||||
_evas_textblock_changed(pd, eo_obj);
|
||||
|
||||
evas_object_change(eo_obj, obj);
|
||||
}
|
||||
|
||||
|
@ -13674,6 +13699,83 @@ _efl_canvas_text_efl_gfx_filter_filter_program_get(Eo *obj EINA_UNUSED, Efl_Canv
|
|||
ERR("Invalid API definition for this object! 'name' needs to be an @in or @inout value!");
|
||||
}
|
||||
|
||||
static Evas_Filter_Data_Binding *
|
||||
_filter_data_binding_find(Efl_Canvas_Text_Data *pd, const char *name)
|
||||
{
|
||||
Evas_Filter_Data_Binding *db;
|
||||
|
||||
if (!name) return NULL;
|
||||
EINA_INLIST_FOREACH(pd->gfx_filter.data_bindings, db)
|
||||
if (!strcmp(db->name, name))
|
||||
return db;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_text_efl_gfx_filter_filter_data_set(Eo *obj, Efl_Canvas_Text_Data *pd, const char *name, const char *value, Eina_Bool execute)
|
||||
{
|
||||
Efl_Canvas_Text_Filter_Program *prg;
|
||||
Evas_Filter_Data_Binding *db;
|
||||
|
||||
if (!name) return;
|
||||
db = _filter_data_binding_find(pd, name);
|
||||
if (db)
|
||||
{
|
||||
if (eina_streq(db->value, value) && (db->execute == execute))
|
||||
return;
|
||||
if (!value)
|
||||
{
|
||||
EINA_INLIST_REMOVE(pd->gfx_filter.data_bindings, db);
|
||||
eina_stringshare_del(db->name);
|
||||
eina_stringshare_del(db->value);
|
||||
free(db);
|
||||
}
|
||||
}
|
||||
else if (!value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
db = calloc(1, sizeof(*db));
|
||||
pd->gfx_filter.data_bindings = (Evas_Filter_Data_Binding *)
|
||||
eina_inlist_append(EINA_INLIST_GET(pd->gfx_filter.data_bindings), EINA_INLIST_GET(db));
|
||||
db->name = eina_stringshare_add(name);
|
||||
}
|
||||
eina_stringshare_replace(&db->value, value);
|
||||
db->execute = execute;
|
||||
|
||||
EINA_INLIST_FOREACH(pd->gfx_filter.programs, prg)
|
||||
{
|
||||
if (!prg->code) continue;
|
||||
if (strstr(prg->code, name))
|
||||
prg->changed = EINA_TRUE;
|
||||
}
|
||||
|
||||
pd->format_changed = EINA_TRUE;
|
||||
_evas_textblock_invalidate_all(pd);
|
||||
_evas_textblock_changed(pd, obj);
|
||||
evas_object_change(obj, efl_data_scope_get(obj, EFL_CANVAS_OBJECT_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_canvas_text_efl_gfx_filter_filter_data_get(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *pd, const char *name, const char **value, Eina_Bool *execute)
|
||||
{
|
||||
Evas_Filter_Data_Binding *db;
|
||||
|
||||
db = _filter_data_binding_find(pd, name);
|
||||
if (!db)
|
||||
{
|
||||
if (value) *value = NULL;
|
||||
if (execute) *execute = EINA_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value) *value = db->value;
|
||||
if (execute) *execute = db->execute;
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_coords_recalc(Evas_Object *eo_obj,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
|
|
Loading…
Reference in New Issue