Eina: eina tiler example.
authorgastal <gastal@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 4 Aug 2011 22:05:46 +0000 (22:05 +0000)
committergastal <gastal@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 4 Aug 2011 22:05:46 +0000 (22:05 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@62113 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.ac
src/examples/Makefile.am
src/examples/eina_tiler_01.c [new file with mode: 0644]
src/include/eina_tiler.h

index b5996e5..440cb11 100644 (file)
@@ -346,6 +346,8 @@ if test "x${enable_ememoa}" = "xyes" ; then
    )
 fi
 
+PKG_CHECK_MODULES([ECORE_EVAS], [ecore-evas ecore], [build_tiler_example="yes"], [build_tiler_example="no"])
+AM_CONDITIONAL([BUILD_TILER_EXAMPLE], [test "x${build_tiler_example}" = "xyes"])
 
 ### Checks for header files
 AC_HEADER_ASSERT
@@ -738,6 +740,7 @@ echo "  Documentation........: ${build_doc}"
 echo "  Tests................: ${enable_tests}"
 echo "  Coverage.............: ${enable_coverage}"
 echo "  Examples.............: ${enable_build_examples}"
+echo "  Tiler Example........: ${build_tiler_example}"
 echo "  Examples installed...: ${enable_install_examples}"
 echo "  Benchmark............: ${enable_benchmark}"
 if test "x${enable_benchmark}" = "xyes" ; then
index 9feb138..72a3638 100644 (file)
@@ -36,7 +36,8 @@ SRCS = \
        eina_inlist_02.c \
        eina_inlist_03.c \
        eina_str_01.c \
-       eina_strbuf_01.c
+       eina_strbuf_01.c \
+       eina_tiler_01.c
 
 pkglib_PROGRAMS =
 
@@ -73,5 +74,11 @@ pkglib_PROGRAMS += \
        eina_inlist_03 \
        eina_str_01 \
        eina_strbuf_01
+
+if BUILD_TILER_EXAMPLE
+AM_CPPFLAGS += @ECORE_EVAS_CFLAGS@
+pkglib_PROGRAMS += eina_tiler_01
+eina_tiler_01_LDADD = @ECORE_EVAS_LIBS@
 endif
 
+endif
diff --git a/src/examples/eina_tiler_01.c b/src/examples/eina_tiler_01.c
new file mode 100644 (file)
index 0000000..b2ff8be
--- /dev/null
@@ -0,0 +1,316 @@
+//Compile with:
+//gcc `pkg-config --cflags --libs ecore-evas ecore evas` eina_tiler_01.c -o eina_tiler_01 
+
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <Eina.h>
+
+#define WINDOW_PAD (20)
+
+static Eina_Tiler *tiler;
+static Eina_Rectangle *input_rects;
+static unsigned int input_count;
+static unsigned int input_idx = 0, input_color_idx = 0, output_color_idx = 0;
+static Eina_List *output_objs = NULL;
+static Evas_Coord maxw, maxh, winw, winh;
+static Evas *evas;
+
+static const struct color {
+   unsigned char r, g, b;
+} colors[] = {
+  {255, 0, 0},
+  {0, 255, 0},
+  {0, 0, 255},
+
+  {255, 128, 0},
+  {0, 255, 128},
+  {128, 0, 255},
+
+  {255, 255, 0},
+  {0, 255, 255},
+  {255, 0, 255},
+
+  {255, 0, 128},
+  {128, 255, 0},
+  {0, 128, 255},
+
+  {128, 128, 0},
+  {0, 128, 128},
+  {128, 0, 128},
+
+  {128, 0, 0},
+  {0, 128, 0},
+  {0, 0, 128},
+
+  {255, 128, 0},
+  {0, 255, 128},
+  {128, 0, 255},
+
+  {64, 64, 0},
+  {0, 64, 64},
+  {64, 0, 64},
+
+  {128, 128, 0},
+  {0, 128, 128},
+  {128, 0, 128},
+
+  {255, 0, 128},
+  {128, 255, 0},
+  {0, 128, 255},
+
+  {128, 64, 0},
+  {0, 128, 64},
+  {64, 0, 128},
+
+  {128, 0, 64},
+  {64, 128, 0},
+  {0, 64, 128}
+};
+
+#define MAX_COLORS (sizeof(colors) / sizeof(colors[0]))
+
+static void
+add_text(const char *text, int x, int y, int w)
+{
+   Evas_Object *o = evas_object_text_add(evas);
+   evas_object_color_set(o, 0, 0, 0, 255);
+   evas_object_move(o, x, y);
+   evas_object_resize(o, w, WINDOW_PAD);
+   evas_object_text_font_set(o, "Sans", 10);
+   evas_object_text_text_set(o, text);
+   evas_object_show(o);
+}
+
+static void
+output_rects_reset(void)
+{
+   Evas_Object *o;
+   EINA_LIST_FREE(output_objs, o)
+     evas_object_del(o);
+   output_color_idx = 0;
+}
+
+static void
+add_input_rect(const Eina_Rectangle *r)
+{
+   Evas_Object *o;
+   Evas_Coord bx, by;
+
+   bx = WINDOW_PAD;
+   by = WINDOW_PAD;
+
+   o = evas_object_rectangle_add(evas);
+#define C(comp) (((int)colors[input_color_idx].comp * 128) / 255)
+   evas_object_color_set(o, C(r), C(g), C(b), 128);
+#undef C
+   evas_object_move(o, r->x + bx, r->y + by);
+   evas_object_resize(o, r->w, r->h);
+   evas_object_show(o);
+
+   input_color_idx = (input_color_idx + 1) % MAX_COLORS;
+
+   bx += maxw + WINDOW_PAD;
+
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 32, 32, 32, 128);
+   evas_object_move(o, r->x + bx, r->y + by);
+   evas_object_resize(o, r->w, 1);
+   evas_object_layer_set(o, EVAS_LAYER_MAX);
+   evas_object_show(o);
+
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 32, 32, 32, 128);
+   evas_object_move(o, r->x + bx, r->y + by);
+   evas_object_resize(o, 1, r->h);
+   evas_object_layer_set(o, EVAS_LAYER_MAX);
+   evas_object_show(o);
+
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 32, 32, 32, 128);
+   evas_object_move(o, r->x + bx, r->y + by + r->h);
+   evas_object_resize(o, r->w, 1);
+   evas_object_layer_set(o, EVAS_LAYER_MAX);
+   evas_object_show(o);
+
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 32, 32, 32, 128);
+   evas_object_move(o, r->x + bx + r->w, r->y + by);
+   evas_object_resize(o, 1, r->h);
+   evas_object_layer_set(o, EVAS_LAYER_MAX);
+   evas_object_show(o);
+}
+
+static void
+add_output_rect(const Eina_Rectangle *r)
+{
+   Evas_Object *o = evas_object_rectangle_add(evas);
+#define C(comp) (((int)colors[output_color_idx].comp * 128) / 255)
+   evas_object_color_set(o, C(r), C(g), C(b), 128);
+#undef C
+   evas_object_move(o, r->x + maxw + 2 * WINDOW_PAD, r->y + WINDOW_PAD);
+   evas_object_resize(o, r->w, r->h);
+   evas_object_show(o);
+
+   output_color_idx = (output_color_idx + 1) % MAX_COLORS;
+
+   output_objs = eina_list_append(output_objs, o);
+}
+
+static Eina_Bool
+process_input(void *data)
+{
+   Eina_Iterator *itr;
+   Eina_Rectangle r, *r1;
+   unsigned int out = 0;
+
+   if (input_idx == input_count)
+     {
+        add_text("Done. Close the window to exit",
+                 WINDOW_PAD, winh - WINDOW_PAD, winw - 2 * WINDOW_PAD);
+        return EINA_FALSE;
+     }
+
+   output_rects_reset();
+
+   r = input_rects[input_idx];
+   printf("Iteration #%u: %dx%d%+d%+d\n", input_idx, r.w, r.h, r.x, r.y);
+   input_idx++;
+   add_input_rect(&r);
+
+   eina_tiler_rect_add(tiler, &r);
+   itr = eina_tiler_iterator_new(tiler);
+   EINA_ITERATOR_FOREACH(itr, r1)
+     {
+        printf("\tOutput #%u: %dx%d%+d%+d\n", out, r1->w, r1->h, r1->x, r1->y);
+        add_output_rect(r1);
+        out++;
+     }
+   eina_iterator_free(itr);
+
+   return EINA_TRUE;
+}
+
+static void
+usage(const char *progname)
+{
+   fprintf(stderr,
+           "Usage:\n\n"
+           "\t%s <rect1> ... <rectN>\n\n"
+           "with rectangles being in the format:\n"
+           "\tWIDTHxHEIGHT<+->X<+->Y\n"
+           "examples:\n"
+           "\t100x100+10+10 - width=100, height=100 at x=10, y=10\n"
+           "\t150x50+5+6    - width=150, height=50 at x=5, y=6\n",
+           progname);
+}
+
+int
+main(int argc, char *argv[])
+{
+   Ecore_Evas *ee;
+   Evas_Object *o;
+   int i;
+
+   if (argc < 2)
+     {
+        usage(argv[0]);
+        return -2;
+     }
+
+   input_rects = calloc(argc - 1, sizeof(Eina_Rectangle));
+   input_count = 0;
+   maxw = 0;
+   maxh = 0;
+   for (i = 1; i < argc; i++)
+     {
+        Eina_Rectangle *r = input_rects + input_count;
+        char sx, sy;
+
+        if (sscanf(argv[i], "%dx%d%c%d%c%d",
+                   &(r->w), &(r->h), &sx, &(r->x), &sy, &(r->y)) == 6)
+          {
+             if (sx == '-') r->x *= -1;
+             if (sy == '-') r->y *= -1;
+
+             if (maxw < r->x + r->w) maxw = r->x + r->w;
+             if (maxh < r->y + r->h) maxh = r->y + r->h;
+             input_count++;
+          }
+        else
+          fprintf(stderr, "ERROR: invalid rectangle ignored: %s\n", argv[i]);
+     }
+
+   if (input_count == 0)
+     {
+        fputs("ERROR: Could not find any valid rectangle. Exit!\n", stderr);
+        usage(argv[0]);
+        free(input_rects);
+        return -3;
+     }
+
+   if ((maxw == 0) || (maxh == 0))
+     {
+        fputs("ERROR: All rectangles with size 0x0. Exit!\n", stderr);
+        usage(argv[0]);
+        free(input_rects);
+        return -3;
+     }
+
+   ecore_evas_init();
+   ecore_init();
+   evas_init();
+   eina_init();
+
+   winw = 2 * maxw + 3 * WINDOW_PAD;
+   winh = maxh + 2 * WINDOW_PAD;
+
+   ee = ecore_evas_new(NULL, 0, 0, winw, winh, NULL);
+   if (!ee)
+     {
+        fputs("ERROR: Could not create window. Check ecore-evas install.\n",
+              stderr);
+        goto end;
+     }
+
+   evas = ecore_evas_get(ee);
+
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 255, 255, 255, 255);
+   evas_object_resize(o, winw, winh);
+   evas_object_show(o);
+
+   add_text("Input", WINDOW_PAD, 0, maxw);
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 200, 200, 200, 255);
+   evas_object_move(o, WINDOW_PAD, WINDOW_PAD);
+   evas_object_resize(o, maxw, maxh);
+   evas_object_show(o);
+
+   add_text("Output", maxw + 2 * WINDOW_PAD, 0, maxw);
+   o = evas_object_rectangle_add(evas);
+   evas_object_color_set(o, 200, 200, 200, 255);
+   evas_object_move(o, maxw + 2 * WINDOW_PAD, WINDOW_PAD);
+   evas_object_resize(o, maxw, maxh);
+   evas_object_show(o);
+
+   tiler = eina_tiler_new(maxw, maxh);
+   ecore_timer_add(2.0, process_input, NULL);
+
+   ecore_evas_show(ee);
+   ecore_main_loop_begin();
+
+   eina_list_free(output_objs);
+   eina_tiler_free(tiler);
+   ecore_evas_free(ee);
+
+ end:
+   free(input_rects);
+
+   eina_shutdown();
+   evas_shutdown();
+   ecore_shutdown();
+   ecore_evas_shutdown();
+
+   return 0;
+}
index cc6af75..5272099 100644 (file)
 #include "eina_rectangle.h"
 
 /**
+ * @page eina_tiler_example_01
+ * @dontinclude eina_tiler_01.c
+ *
+ * This is an example that illustrates how Eina_Tiler works for a given set of
+ * rectangles. The rectangles must be given in the command line in the form:
+ * <width>x<height>+<x offset>+<y offset>
+ * The example will show two panels, the first(input) will show the given
+ * rectangles(in different colors) and in the seconds(output) it will show the
+ * rectangles given by the tiler. The rectangles will be added one by one every
+ * two seconds. A lot of the example deals with actually painting the rectangles
+ * so we'll skip over quite a bit of code, but you can see all of it in @ref
+ * eina_tiler_01.c "eina_tiler_01.c".
+ *
+ * The first thing of note in our example is the creation of the tiler:
+ * @skipline eina_tiler_new
+ * @note @p maxw and @p maxh are calculated such that the tiler's size will
+ * fully encompass all given rectangles.
+ *
+ * We'll now look at the function that actually adds rectangles to our tiler. It
+ * first checks if we added all rectangles already and if so stops right there:
+ * @dontinclude eina_tiler_01.c
+ * @skip static Eina_Bool
+ * @until }
+ *
+ * Our function then clears all rectangles given to us by tiler from the last
+ * execution. It does this because each rectangle we add may change everything
+ * about the output of eina_tiler:
+ * @until output_rects_reset
+ *
+ * Next we get another rectangle, print it and show it in the input panel:
+ * @until add_input_rect
+ *
+ * We now come to the tiler stuff, we add our new rectangle to it and get a new
+ * iterator for the tiler:
+ * @until itr
+ *
+ * We now iterate over our tiler printing every rect it gives us and sowing it
+ * in the output panel:
+ * @until }
+ *
+ * We of course must remember to free our iterator and that's it for this
+ * function:
+ * @until }
+ *
+ * You should try many different inputs to see how the tiler works, here are a
+ * few suggestions:
+ * @li 100x100+0+0 100x100+200+200
+ * @li 100x100+0+0 100x100+5+5 100x100+10+10 100x100+15+15 100x100+20+20
+ * @li 100x100+0+0 100x100+100+100 100x100+200+0 100x100+0+200 100x100+200+200
+ * @li 10x10+0+0 10x10+10+10 10x10+20+0 10x10+0+20 10x10+20+20
+ *
+ * @example eina_tiler_01.c
+ */
+/**
  * @addtogroup Eina_Data_Types_Group Data Types
  *
  * @{
  * to re-render in the form of a set of non-overlapping rectangles that covers
  * the whole area that needs re-rendering.
  *
- * The following is pseudo-code showing some simple use of Eina_Tiler:
+ * The following is pseudo-code showing some simple use of Eina_Tiler:
  * @code
  * tiler = eina_tiler_new(MY_CANVAS_WIDTH, MY_CANVAS_HEIGHT);
  * EINA_LIST_FOREACH(list_of_areas_that_need_re_rendering, l, rect)
- *    eina_tiler_add(tiler, rect);
+ *   eina_tiler_add(tiler, rect);
  * itr = eina_tiler_iterator_new(tiler);
  * EINA_ITERATOR_FOREACH(itr, rect)
- *    my_function_that_repaints_areas_of_the_canvas(rect);
+ *   my_function_that_repaints_areas_of_the_canvas(rect);
  * @endcode
  *
  * @see eina_tiler_new()
  * the area that will be rendered into tiles. It's customary to, then create one
  * Eina_Tiler for each tile.
  *
+ * The following is pseudo-code showing a very simplified use of grid slicer
+ * together with Eina_Tiler:
+ * @code
+ * itr = eina_tile_grid_slicer_iterator_new(0, 0, MY_CANVAS_WIDTH, MY_CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
+ * EINA_ITERATOR_FOREACH(itr, grid_info)
+ *   {
+ *      tiler = eina_tiler_new(grid_info->rect.w, grid_info->rect.w);
+ *      EINA_LIST_FOREACH(list_of_areas_that_need_re_rendering_in_this_tile, l, rect)
+ *        eina_tiler_add(tiler, rect);
+ *      itr = eina_tiler_iterator_new(tiler);
+ *      EINA_ITERATOR_FOREACH(itr, rect)
+ *      my_function_that_repaints_areas_of_the_canvas(rect);
+ *   }
+ * @endcode
+ *
  * @see eina_tiler_new()
  * @see eina_tiler_rect_add()
  * @see eina_tile_grid_slicer_setup()