summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2016-12-12 18:36:49 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-12-13 16:12:27 +0900
commitbcfc33fd00a46735c4dd957fd67a30ac275a96ad (patch)
tree909e9d0dbcce455541a1c36ac8408f325d36c471
parenta6b5765c3d79ea415abab10a3f112ad3b35137d4 (diff)
downloadefl-bcfc33fd00a46735c4dd957fd67a30ac275a96ad.tar.gz
elm_test: Add a test case for gfx filters
This adds a test window for the efl_gfx_filter (also known as evas filters). The builtin examples are not incredibly pretty but they showcase some of the most basic features. They also show that some of the filters need to be improved. Note that the code contains a lot of FIXME due to the incompleteness of our EO API. Also, Efl.Ui.Text still has quite a few issues (sizing, lack of a working change event, ...) so the UI doesn't even look as designed (a label is missing). Hopefully this should get fixed over time. Oh and this is mostly using EO APIs but that's a terrible idea as evas_object_text is not going to be exposed in EO land... except it's the only object implementing filter support (with image).
-rw-r--r--src/Makefile_Elementary.am3
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_gfx_filters.c375
3 files changed, 379 insertions, 1 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 042e806851..14dd6741ea 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -757,8 +757,8 @@ bin/elementary/test_eio.c \
bin/elementary/test_entry.c \
bin/elementary/test_entry_anchor.c \
bin/elementary/test_entry_anchor2.c \
-bin/elementary/test_external.c \
bin/elementary/test_events.c \
+bin/elementary/test_external.c \
bin/elementary/test_fileselector_button.c \
bin/elementary/test_fileselector.c \
bin/elementary/test_fileselector_entry.c \
@@ -775,6 +775,7 @@ bin/elementary/test_genlist.c \
bin/elementary/test_gesture_layer.c \
bin/elementary/test_gesture_layer2.c \
bin/elementary/test_gesture_layer3.c \
+bin/elementary/test_gfx_filters.c \
bin/elementary/test_glview_simple.c \
bin/elementary/test_glview.c \
bin/elementary/test_glview_manygears.c \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 6f1c9492bb..224e01e44f 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -298,6 +298,7 @@ void test_code_diff_inline(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info);
+void test_gfx_filters(void *data, Evas_Object *obj, void *event_info);
Evas_Object *win, *tbx; // TODO: refactoring
void *tt;
@@ -995,6 +996,7 @@ add_tests:
ADD_TEST(NULL, "Miscellaneous", "Accessibility2", test_access2);
ADD_TEST(NULL, "Miscellaneous", "Accessibility3", test_access3);
ADD_TEST(NULL, "Miscellaneous", "Font overlay", test_config_font_overlay);
+ ADD_TEST(NULL, "Miscellaneous", "Gfx Filters", test_gfx_filters);
//------------------------------//
ADD_TEST(NULL, "Widgets Disable/Enable", "Box", test_box_disable);
diff --git a/src/bin/elementary/test_gfx_filters.c b/src/bin/elementary/test_gfx_filters.c
index 8b13789179..04ac8e1785 100644
--- a/src/bin/elementary/test_gfx_filters.c
+++ b/src/bin/elementary/test_gfx_filters.c
@@ -1 +1,376 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+const int default_font_size = 48;
+
+typedef struct _Filter_Image
+{
+ const char *path;
+ const char *src_name;
+} Filter_Image;
+
+typedef struct _Filter
+{
+ const char *name;
+ const char *code;
+ const Filter_Image *images;
+} Filter;
+
+static const Filter_Image images[] = {
+ { "plant_01.jpg", "plant" },
+ { "rock_01.jpg", "rock" },
+ { "rock_02.jpg", "roll" },
+ { "sky_01.jpg", "sky" },
+ { "sky_04.jpg", "cloud" },
+ { "wood_01.jpg", "wood" },
+ { "icon_00.png", "love" },
+ { NULL, NULL }
+};
+
+static const Filter_Image images_wood[] = {
+ { "wood_01.jpg", "wood" },
+ { NULL, NULL },
+};
+
+static const Filter_Image images_cloud[] = {
+ { "sky_04.jpg", "cloud" },
+ { NULL, NULL },
+};
+
+/* builtin filter examples */
+static const Filter templates[] = {
+ { "Custom", NULL, NULL },
+ { "Black shadow",
+ "blur { 6, ox = 2, oy = 2, color = 'black' }\n"
+ "blend {}", NULL },
+ { "Fire glow",
+ "a = buffer { 'alpha' }\n"
+ "grow { 10, dst = a }\n"
+ "blur { 15, oy = -4, ox = 1, src = a, color = '#900' }\n"
+ "blur { 5, oy = -1, color = 'orange' }\n"
+ "blur { 2, color = 'yellow' }\n"
+ "grow { -2 }\n", NULL },
+ { "Outer glow",
+ "inv = function (x) return 255 - x end\n\n"
+ "a = buffer {'alpha'}\n"
+ "curve { inv, dst = a }\n\n"
+ "b = buffer { 'alpha' }\n"
+ "grow { 3, dst = b }\n\n"
+ "c = buffer {}\n"
+ "blur { 6, color = 'blue', dst = c, src = b }\n"
+ "blur { 2, color = 'cyan', dst = c, src = b }\n"
+ "mask { a, c }", NULL },
+ { "Inset light",
+ "inv = function (x) return 255 - x end\n\n"
+ "a = buffer {'alpha'}\n"
+ "curve { inv, dst = a }\n\n"
+ "b = buffer {}\n"
+ "blur { 2, ox = 1, oy = 1, src = a, dst = b, color = 'yellow' }\n\n"
+ "blend { color = 'black' }\n"
+ "mask { input, b }\n", NULL },
+ { "Rocking it",
+ "padding_set { 40 }\n"
+ "local len = state.scale * 10\n\n"
+ "a = buffer { 'alpha' }\n"
+ "grow { len / 2, dst = a }\n"
+ "blur { len * 2, oy = len, ox = len / 2, color = 'black', src = a }\n"
+ "for i = len,0,-1 do\n"
+ " c = 128 / len * (len - i)\n"
+ " blur { 2, oy = i, ox = i/2, color = color { c * 0.8, c * 0.9, c } }\n"
+ "end\n"
+ "blend {}\n", NULL },
+ { "Bumping on",
+ "a = buffer { 'alpha' }\n"
+ "grow { 2, dst = a }\n"
+ "blur { 4, src = a, dst = a }\n\n"
+ "bump { a, color = '#333', specular = 10, compensate = true, depth = 15 }\n", NULL },
+ { "Modern art",
+ "local inv = function (x) return 255 - x end\n\n"
+ "a = buffer {}\n"
+ "b = buffer {'alpha'}\n"
+ "blend { dst = a, ox = 6, oy = -6, color = '#0f0' }\n"
+ "blend { dst = a, ox = -6, oy = 6, color = '#f00' }\n"
+ "blend { dst = a, ox = -3, oy = -3, color = '#f8f' }\n"
+ "blend { dst = a, ox = 3, oy = 3, color = '#00f' }\n"
+ "curve { inv, dst = b }\n"
+ "blur { 20, color = '#fffa' }\n"
+ "mask { a, b }\n", NULL },
+ { "Forestry",
+ "wood = buffer { src = 'wood' }\n"
+ "mask { wood, fillmode = 'stretch' }", images_wood },
+ { "Displaced cloud",
+ "cloud = buffer { src = 'cloud' }\n"
+ "displace { cloud, intensity = 10, fillmode = 'stretch' }", images_cloud },
+};
+
+
+static void
+_spinner_fill(Eo *obj)
+{
+ const Filter *f;
+ size_t k;
+
+ for (k = 0; k < EINA_C_ARRAY_LENGTH(templates); k++)
+ {
+ f = &templates[k];
+ elm_spinner_special_value_add(obj, (double) k, f->name);
+ }
+ elm_spinner_editable_set(obj, EINA_FALSE);
+ elm_spinner_min_max_set(obj, 0, k - 1);
+ elm_obj_spinner_wrap_set(obj, 1);
+}
+
+static void
+_spinner_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eo *win = data;
+ Eo *text, *code, *spinner;
+ int k;
+
+ text = efl_key_wref_get(win, "text");
+ code = efl_key_wref_get(win, "code");
+ spinner = efl_key_wref_get(win, "spinner");
+ k = (int) round(elm_spinner_value_get(spinner));
+ if (k > 0)
+ {
+ const Filter *f = &templates[k];
+
+ efl_gfx_filter_program_set(text, f->code, f->name);
+ efl_text_set(code, f->code);
+
+ if (f->images)
+ {
+ for (size_t j = 0; f->images[j].path; j++)
+ {
+ const char *name = f->images[j].src_name;
+ Eo *source_obj = efl_name_find(win, name);
+ efl_gfx_filter_source_set(text, name, source_obj);
+ }
+ }
+ }
+}
+
+static void
+_code_changed(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Eo *win = data;
+ Eo *text, *code, *spinner;
+ Eina_Strbuf *buf = NULL;
+ const char *source;
+
+ text = efl_key_wref_get(win, "text");
+ code = efl_key_wref_get(win, "code");
+ spinner = efl_key_wref_get(win, "spinner");
+
+ source = efl_text_get(code);
+ {
+ // Fix up paragrah separators from the UTF-8 input. :(
+ const char *paragraph = "\u2029";
+
+ if (source && strstr(source, paragraph))
+ {
+ buf = eina_strbuf_new();
+ eina_strbuf_append(buf, source);
+ eina_strbuf_replace_all(buf, paragraph, "\n");
+ source = eina_strbuf_string_get(buf);
+ }
+ }
+
+ elm_spinner_value_set(spinner, 0);
+ efl_gfx_filter_program_set(text, source, elm_spinner_special_value_get(spinner, 0));
+ eina_strbuf_free(buf);
+}
+
+static void
+_code_changed_hack(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ Efl_Future *p = efl_loop_job(efl_loop_get(data), NULL);
+ efl_future_then(p, _code_changed, NULL, NULL, data);
+}
+
+static void
+_text_resize(void *data EINA_UNUSED, const Efl_Event *ev)
+{
+ int w = 0, h = 0;
+
+ efl_gfx_size_get(ev->object, &w, &h);
+ efl_gfx_size_hint_min_set(ev->object, w, h);
+}
+
+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)
+{
+ Eina_Strbuf *buf;
+ Eo *win = data;
+ Eo *img = ev->object;
+ Eo *code, *text;
+ const char *name;
+
+ name = efl_name_get(img);
+ if (!name) return;
+
+ code = efl_key_wref_get(win, "code");
+ text = efl_key_wref_get(win, "text");
+
+ buf = eina_strbuf_new();
+ eina_strbuf_append_printf(buf, "%s = buffer { src = '%s' }\n", name, name);
+
+ eina_strbuf_append(buf, efl_text_get(code));
+ efl_text_set(code, eina_strbuf_string_get(buf));
+ eina_strbuf_free(buf);
+
+ efl_gfx_filter_source_set(text, name, ev->object);
+}
+
+static void
+_font_size_change(void *data, const Efl_Event *ev)
+{
+ Eo *win = data;
+ Eo *text;
+ const char *font;
+
+ text = efl_key_wref_get(win, "text");
+ efl_text_properties_font_get(text, &font, NULL);
+ efl_text_properties_font_set(text, font, elm_spinner_value_get(ev->object));
+}
+
+void
+test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ Eo *win, *box, *box2, *o, *text, *spinner, *code, *split;
+
+ win = efl_add(EFL_UI_WIN_STANDARD_CLASS, NULL,
+ efl_text_set(efl_added, "Gfx Filter Editor"),
+ efl_ui_win_autodel_set(efl_added, 1));
+
+ box = efl_add(EFL_UI_BOX_CLASS, win,
+ efl_orientation_set(efl_added, EFL_ORIENT_DOWN),
+ efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0));
+
+ efl_content_set(win, box);
+
+ {
+ 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, -1.0, 0.0),
+ efl_gfx_visible_set(efl_added, 1));
+ efl_pack(box, box2);
+
+ /* FIXME: Efl.Ui.Text doesn't work as expected. */
+ o = efl_add(EFL_UI_TEXT_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 0.0, 1.0),
+ efl_gfx_size_hint_align_set(efl_added, 1.0, 0.5),
+ efl_gfx_visible_set(efl_added, 1));
+ efl_text_set(o, "Filter:");
+ efl_pack(box2, o);
+
+ o = spinner = efl_add(ELM_SPINNER_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
+ efl_gfx_size_hint_align_set(efl_added, -1.0, 0.5),
+ efl_gfx_visible_set(efl_added, 1));
+ _spinner_fill(o);
+ efl_pack(box2, o);
+ spinner = o;
+
+ o = efl_add(ELM_SPINNER_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 0.0, 1.0),
+ efl_gfx_size_hint_align_set(efl_added, -1.0, 0.5),
+ elm_spinner_min_max_set(efl_added, 6, 120),
+ elm_spinner_value_set(efl_added, default_font_size),
+ efl_event_callback_add(efl_added, ELM_SPINNER_EVENT_DELAY_CHANGED, _font_size_change, win),
+ efl_gfx_visible_set(efl_added, 1));
+
+ efl_pack(box2, o);
+ }
+
+ {
+ 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_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++)
+ {
+ 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_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),
+ 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);
+ }
+
+ efl_gfx_visible_set(box2, 1);
+ }
+
+ /* FIXME: No panes in EO APIs. */
+ o = split = efl_add(ELM_PANES_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
+ efl_gfx_size_hint_align_set(efl_added, -1.0, -1.0),
+ efl_orientation_set(efl_added, EFL_ORIENT_HORIZONTAL),
+ efl_gfx_visible_set(efl_added, 1));
+ efl_pack(box, split);
+
+ {
+ o = box2 = efl_add(EFL_UI_BOX_STACK_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 1.0, 0.0),
+ efl_gfx_size_hint_align_set(efl_added, -1.0, -1.0),
+ efl_pack_align_set(efl_added, 0.5, 0.5));
+ efl_content_set(efl_part(split, "top"), box2);
+
+ /* FIXME: No textblock support! TEXT is not part of EO public API. */
+ o = text = evas_object_text_add(evas_object_evas_get(win));
+ efl_event_callback_add(o, EFL_GFX_EVENT_RESIZE, _text_resize, NULL);
+ efl_text_properties_font_set(o, "Sans:style=Bold", default_font_size);
+ efl_canvas_object_scale_set(text, elm_config_scale_get());
+ efl_text_set(o, "EFL");
+ efl_gfx_visible_set(o, 1);
+ efl_pack(box2, o);
+ }
+
+ {
+ o = code = efl_add(EFL_UI_TEXT_EDITABLE_CLASS, win,
+ efl_gfx_size_hint_weight_set(efl_added, 1.0, 1.0),
+ efl_gfx_size_hint_align_set(efl_added, -1.0, -1.0),
+ efl_ui_text_scrollable_set(efl_added, 1));
+ efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed, win);
+
+ // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+ efl_event_callback_add(o, EFL_EVENT_KEY_DOWN, _code_changed_hack, win);
+
+ efl_content_set(efl_part(split, "bottom"), code);
+ }
+
+ efl_key_wref_set(win, "text", text);
+ efl_key_wref_set(win, "code", code);
+ efl_key_wref_set(win, "spinner", spinner);
+ efl_event_callback_add(spinner, ELM_SPINNER_EVENT_CHANGED, _spinner_cb, win);
+ elm_spinner_value_set(spinner, 1.0);
+ _spinner_cb(win, NULL);
+
+ efl_gfx_size_set(win, 500, 600);
+ efl_gfx_visible_set(win, 1);
+}