[evas] Examples on the last block of documented
authorglima <glima@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 10 Jun 2011 21:32:02 +0000 (21:32 +0000)
committerglima <glima@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Fri, 10 Jun 2011 21:32:02 +0000 (21:32 +0000)
 functions.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@60209 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/examples.dox
src/examples/Makefile.am
src/examples/evas-events.c [new file with mode: 0644]
src/lib/Evas.h

index ccc7720..c537822 100644 (file)
  * @include evas-load-error-str.c
  * @example evas-load-error-str.c
  */
+
+/**
+ * @page Example_Evas_Events Evas' canvas events example
+ *
+ * @include evas-events.c
+ * @example evas-events.c
+ */
index a632d82..5fb714b 100644 (file)
@@ -42,6 +42,10 @@ pkglib_PROGRAMS += evas_load_error_str
 evas_load_error_str_SOURCES = evas-load-error-str.c
 evas_load_error_str_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
 
+pkglib_PROGRAMS += evas_events
+evas_events_SOURCES = evas-events.c
+evas_events_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
+
 endif # if BUILD_EXAMPLES
 
 filesdir = $(datadir)/$(PACKAGE)/examples
diff --git a/src/examples/evas-events.c b/src/examples/evas-events.c
new file mode 100644 (file)
index 0000000..655ca27
--- /dev/null
@@ -0,0 +1,262 @@
+/**
+ * Simple Evas example illustrating how to interact with canvas
+ * events and other canvas operations.
+ *
+ * You'll need at least one engine built for it (excluding the buffer
+ * one) and the png image loader also built. See stdout/stderr for
+ * output.
+ *
+ * @verbatim
+ * gcc -o evas-events evas-events.c `pkg-config --libs --cflags ecore-evas`
+ * @endverbatim
+ */
+
+#ifdef HAVE_CONFIG_H
+
+#include "config.h"
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define WIDTH  (320)
+#define HEIGHT (240)
+
+static const char *img_path = PACKAGE_EXAMPLES_DIR "/enlightenment.png";
+
+struct test_data
+{
+   Ecore_Evas  *ee;
+   Evas        *canvas;
+   Eina_Bool    obscured;
+   Evas_Object *img, *img2, *bg;
+   Ecore_Timer *resize_timer, *freeze_timer;
+};
+
+static struct test_data d = {0};
+
+/* here just to keep our example's window size and background image's
+ * size in synchrony */
+static void
+_canvas_resize_cb(Ecore_Evas *ee)
+{
+   int w, h;
+
+   ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+   evas_object_resize(d.bg, w, h);
+}
+
+static void
+/* called when our rectangle gets focus */
+_object_focus_in_cb(void *data __UNUSED__,
+                    Evas *e,
+                    void *event_info)
+{
+   fprintf(stdout, "An object got focused: %s\n",
+           evas_object_name_get(event_info));
+
+   fprintf(stdout, "Let's recheck it: %s\n",
+           evas_object_name_get(evas_focus_get(e)));
+}
+
+static void
+_render_flush_cb(void *data __UNUSED__,
+                 Evas *e __UNUSED__,
+                 void *event_info __UNUSED__)
+{
+   fprintf(stdout, "Canvas is about to flush its rendering pipeline!\n");
+}
+
+static Eina_Bool
+/* put some action in the canvas */
+_resize_cb(void *data __UNUSED__)
+{
+   int w, h, cw, ch;
+
+   evas_object_geometry_get(d.img, NULL, NULL, &w, &h);
+   ecore_evas_geometry_get(d.ee, NULL, NULL, &cw, &ch);
+
+   if (w < cw)
+     evas_object_resize(d.img, cw, ch);
+   else
+     evas_object_resize(d.img, cw / 2, ch / 2);
+
+   return EINA_TRUE; /* re-issue the timer */
+}
+
+static Eina_Bool
+/* let's have our events back */
+_thaw_cb(void *data __UNUSED__)
+{
+   fprintf(stdout, "Canvas was frozen %d times, now thawing.\n",
+           evas_event_freeze_get(d.canvas));
+   evas_event_thaw(d.canvas);
+   return EINA_FALSE; /* do not re-issue the timer */
+}
+
+static void
+_on_keydown(void        *data __UNUSED__,
+            Evas        *evas,
+            Evas_Object *o __UNUSED__,
+            void        *einfo)
+{
+   const Evas_Modifier *mods;
+   Evas_Event_Key_Down *ev = einfo;
+
+   fprintf(stdout, "we've got key input: %s\n", ev->keyname);
+
+   if (strcmp(ev->keyname, "a") == 0) /* toggle animation timer */
+     {
+        if (d.resize_timer != NULL)
+          {
+             fprintf(stdout, "Stopping animation timer\n");
+             ecore_timer_del(d.resize_timer);
+             d.resize_timer = NULL;
+          }
+        else
+          {
+             fprintf(stdout, "Re-issuing animation timer\n");
+             d.resize_timer = ecore_timer_add(2, _resize_cb, NULL);
+          }
+        return;
+     }
+
+   if (strcmp(ev->keyname, "d") == 0) /* delete canvas' callbacks */
+     {
+        fprintf(stdout, "Deleting canvas event callbacks\n");
+        evas_event_callback_del_full(evas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
+                                     _render_flush_cb, NULL);
+        evas_event_callback_del_full(
+          evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
+          _object_focus_in_cb, NULL);
+        return;
+     }
+
+   if (strcmp(ev->keyname, "f") == 0) /* freeze input for 3 seconds */
+     {
+        fprintf(stdout, "Freezing input for 3 seconds\n");
+        evas_event_freeze(evas);
+        d.freeze_timer = ecore_timer_add(3, _thaw_cb, NULL);
+        return;
+     }
+
+   mods = evas_key_modifier_get(evas);
+   if (evas_key_modifier_is_set(mods, "Control") &&
+       (strcmp(ev->keyname, "o") == 0)) /* add an obscured
+                                         * rectangle to the middle
+                                         * of the canvas */
+     {
+        fprintf(stdout, "Toggling obscured rectangle on canvas\n");
+        if (!d.obscured)
+          {
+             int w, h;
+             evas_output_viewport_get(evas, NULL, NULL, &w, &h);
+             evas_obscured_rectangle_add(evas, w / 4, h / 4, w / 2, h / 2);
+          }
+        else
+          {
+             int w, h;
+             Eina_Rectangle *rect;
+             Eina_List *updates, *l;
+
+             evas_output_viewport_get(evas, NULL, NULL, &w, &h);
+             evas_obscured_clear(evas);
+
+             /* we have to flag a damage region here because
+              * evas_obscured_clear() doesn't change the canvas'
+              * state. we'd have to wait for an animation step, for
+              * example, to get the result, without it */
+             evas_damage_rectangle_add(evas, 0, 0, w, h);
+
+             updates = evas_render_updates(evas);
+
+             EINA_LIST_FOREACH(updates, l, rect)
+               {
+                  fprintf(stdout, "Rectangle (%d, %d, %d, %d) on canvas got a"
+                          " rendering update.\n", rect->x, rect->y, rect->w,
+                          rect->h);
+               }
+             evas_render_updates_free(updates);
+          }
+        d.obscured = !d.obscured;
+     }
+}
+
+int
+main(void)
+{
+   int err;
+
+   if (!ecore_evas_init())
+     return EXIT_FAILURE;
+
+   /* this will give you a window with an Evas canvas under the first
+    * engine available */
+   d.ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
+   if (!d.ee)
+     goto error;
+
+   ecore_evas_callback_resize_set(d.ee, _canvas_resize_cb);
+   ecore_evas_show(d.ee);
+
+   /* the canvas pointer, de facto */
+   d.canvas = ecore_evas_get(d.ee);
+
+   evas_event_callback_add(d.canvas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
+                           _render_flush_cb, NULL);
+   if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
+     {
+        fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
+        goto panic;
+     }
+
+   evas_event_callback_add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
+                           _object_focus_in_cb, NULL);
+   if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
+     {
+        fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
+        goto panic;
+     } /* two canvas event callbacks */
+
+   d.bg = evas_object_rectangle_add(d.canvas);
+   evas_object_name_set(d.bg, "our dear rectangle");
+   evas_object_color_set(d.bg, 255, 255, 255, 255); /* white bg */
+   evas_object_move(d.bg, 0, 0); /* at canvas' origin */
+   evas_object_resize(d.bg, WIDTH, HEIGHT); /* covers full canvas */
+   evas_object_show(d.bg);
+
+   evas_object_focus_set(d.bg, EINA_TRUE);
+   evas_object_event_callback_add(
+     d.bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, NULL);
+
+   d.img = evas_object_image_filled_add(d.canvas);
+   evas_object_image_file_set(d.img, img_path, NULL);
+   err = evas_object_image_load_error_get(d.img);
+   if (err != EVAS_LOAD_ERROR_NONE)
+     {
+        goto panic;
+     }
+   else
+     {
+        evas_object_move(d.img, 0, 0);
+        evas_object_resize(d.img, WIDTH, HEIGHT);
+        evas_object_show(d.img);
+     }
+
+   d.resize_timer = ecore_timer_add(2, _resize_cb, NULL);
+
+   ecore_main_loop_begin();
+
+   ecore_evas_free(d.ee);
+   ecore_evas_shutdown();
+   return 0;
+
+error:
+   fprintf(stderr, "you got to have at least one evas engine built and linked"
+                   " up to ecore-evas for this example to run properly.\n");
+panic:
+   ecore_evas_shutdown();
+   return -1;
+}
index e48980d..1f4d6d7 100644 (file)
@@ -1288,9 +1288,26 @@ EAPI void              evas_damage_rectangle_add         (Evas *e, int x, int y,
  * @note This is a <b>very low level function</b>, which most of
  * Evas' users wouldn't care about.
  *
+ * @note This function does <b>not</b> flag the canvas as having its
+ * state changed. If you want to re-render it afterwards expecting new
+ * contents, you have to add "damage" regions yourself (see
+ * evas_damage_rectangle_add()).
+ *
  * @see evas_obscured_clear()
  * @see evas_render_updates()
  *
+ * Example code follows.
+ * @dontinclude evas-events.c
+ * @skip add an obscured
+ * @until evas_obscured_clear(evas);
+ *
+ * In that example, pressing the "Ctrl" and "o" keys will impose or
+ * remove an obscured region in the middle of the canvas. You'll get
+ * the same contents at the time the key was pressed, if toggling it
+ * on, until you toggle it off again (make sure the animation is
+ * running on to get the idea better). See the full @ref
+ * Example_Evas_Events "example".
+ *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_obscured_rectangle_add       (Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
@@ -1308,7 +1325,12 @@ EAPI void              evas_obscured_rectangle_add       (Evas *e, int x, int y,
  * @note This is a <b>very low level function</b>, which most of
  * Evas' users wouldn't care about.
  *
- * @see evas_obscured_rectangle_add()
+ * @note This function does <b>not</b> flag the canvas as having its
+ * state changed. If you want to re-render it afterwards expecting new
+ * contents, you have to add "damage" regions yourself (see
+ * evas_damage_rectangle_add()).
+ *
+ * @see evas_obscured_rectangle_add() for an example
  * @see evas_render_updates()
  *
  * @ingroup Evas_Canvas
@@ -1331,6 +1353,17 @@ EAPI void              evas_obscured_clear               (Evas *e) EINA_ARG_NONN
  * grab an Evas' canvas update regions and paint them back, using the
  * canvas' pixmap, on a displaying system working below Evas.
  *
+ * @note Evas is a stateful canvas. If no operations changing its
+ * state took place since the last rendering action, you won't see no
+ * changes and this call will be a no-op.
+ *
+ * Example code follows.
+ * @dontinclude evas-events.c
+ * @skip add an obscured
+ * @until d.obscured = !d.obscured;
+ *
+ * See the full @ref Example_Evas_Events "example".
+ *
  * @ingroup Evas_Canvas
  */
 EAPI Eina_List        *evas_render_updates               (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
@@ -1343,6 +1376,8 @@ EAPI Eina_List        *evas_render_updates               (Evas *e) EINA_WARN_UNU
  * This function removes the region from the render updates list. It
  * makes the region doesn't be render updated anymore.
  *
+ * @see evas_render_updates() for an example
+ *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_render_updates_free          (Eina_List *updates);
@@ -1979,27 +2014,22 @@ EAPI Eina_Bool         evas_pointer_inside_get           (const Evas *e) EINA_WA
  * others the @p event_info pointer is going to be @c NULL.
  *
  * Example:
- * @code
- * extern Evas *e;
- * extern void *my_data;
- * void focus_in_callback(void *data, Evas *e, void *event_info);
- * void focus_out_callback(void *data, Evas *e, void *event_info);
+ * @dontinclude evas-events.c
+ * @skip evas_event_callback_add(d.canvas, EVAS_CALLBACK_RENDER_FLUSH_PRE
+ * @until two canvas event callbacks
  *
- * evas_event_callback_add(e, EVAS_CALLBACK_CANVAS_FOCUS_IN, focus_in_callback,
- *                         my_data);
- * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
- *   {
- *     fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
- *     exit(-1);
- *   }
- * evas_event_callback_add(e, EVAS_CALLBACK_CANVAS_FOCUS_OUT,
- *                         focus_out_callback, my_data);
- * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
- *   {
- *     fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
- *     exit(-1);
- *   }
- * @endcode
+ * Looking to the callbacks registered above,
+ * @dontinclude evas-events.c
+ * @skip called when our rectangle gets focus
+ * @until let's have our events back
+ *
+ * we see that the canvas flushes its rendering pipeline
+ * (#EVAS_CALLBACK_RENDER_FLUSH_PRE) whenever the @c _resize_cb
+ * routine takes place: it has to redraw that image at a different
+ * size. Also, the callback on an object being focused comes just
+ * after we focus it explicitly, on code.
+ *
+ * See the full @ref Example_Evas_Events "example".
  *
  * @note Be careful not to add the same callback multiple times, if
  * that's not what you want, because Evas won't check if a callback
@@ -2056,14 +2086,11 @@ EAPI void             *evas_event_callback_del              (Evas *e, Evas_Callb
  * would be to remove an exact match of a callback.
  *
  * Example:
- * @code
- * extern Evas *e;
- * void *my_data;
- * void focus_in_callback(void *data, Evas *e, void *event_info);
+ * @dontinclude evas-events.c
+ * @skip evas_event_callback_del_full(evas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
+ * @until _object_focus_in_cb, NULL);
  *
- * my_data = evas_event_callback_del_full(object, EVAS_CALLBACK_CANVAS_FOCUS_IN,
- *                                        focus_in_callback, my_data);
- * @endcode
+ * See the full @ref Example_Evas_Events "example".
  *
  * @note For deletion of canvas events callbacks filtering by just
  * type and function pointer, user evas_event_callback_del().
@@ -2160,16 +2187,19 @@ EAPI void              evas_post_event_callback_remove_full (Evas *e, Evas_Objec
  * interface when you're populating a view or changing the layout.
  *
  * Example:
- * @code
- * extern Evas *evas;
- * extern Evas_Object *object;
+ * @dontinclude evas-events.c
+ * @skip freeze input for 3 seconds
+ * @until }
+ * @dontinclude evas-events.c
+ * @skip let's have our events back
+ * @until }
  *
- * evas_event_freeze(evas);
- * evas_object_move(object, 50, 100);
- * evas_object_resize(object, 200, 200);
- * // more realistic code would be a toolkit or Edje doing some UI changes here
- * evas_event_thaw(evas);
- * @endcode
+ * See the full @ref Example_Evas_Events "example".
+ *
+ * If you run that example, you'll see the canvas ignoring all input
+ * events for 3 seconds, when the "f" key is pressed. In a more
+ * realistic code we would be freezing while a toolkit or Edje was
+ * doing some UI changes, thawing it back afterwards.
  */
 EAPI void              evas_event_freeze                 (Evas *e) EINA_ARG_NONNULL(1);
 
@@ -4356,6 +4386,7 @@ EAPI Evas_Render_Op            evas_object_render_op_get        (const Evas_Obje
  * Retrieve the object that currently has focus.
  *
  * @param e The Evas canvas to query for focused object on.
+ * @return The object that has focus or NULL if there is not one.
  *
  * Evas can have (at most) one of its objects focused at a time.
  * Focused objects will be the ones having <b>key events</b> delivered
@@ -4375,7 +4406,16 @@ EAPI Evas_Render_Op            evas_object_render_op_get        (const Evas_Obje
  * @see evas_object_key_grab
  * @see evas_object_key_ungrab
  *
- * @return The object that has focus or NULL if there is not one.
+ * Example:
+ * @dontinclude evas-events.c
+ * @skip evas_event_callback_add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
+ * @until evas_object_focus_set(d.bg, EINA_TRUE);
+ * @dontinclude evas-events.c
+ * @skip called when our rectangle gets focus
+ * @until }
+ *
+ * In this example the @c event_info is exactly a pointer to that
+ * focused rectangle. See the full @ref Example_Evas_Events "example".
  *
  * @ingroup Evas_Object_Group_Find
  */
@@ -8612,6 +8652,14 @@ EAPI int               evas_string_char_len_get          (const char *str) EINA_
  * to your display engine's documentation when using evas through an
  * Ecore helper wrapper when you need the <code>keyname</code>s.
  *
+ * Example:
+ * @dontinclude evas-events.c
+ * @skip mods = evas_key_modifier_get(evas);
+ * @until {
+ *
+ * All the other @c evas_key functions behave on the same manner. See
+ * the full @ref Example_Evas_Events "example".
+ *
  * @ingroup Evas_Canvas
  */