* @include evas-stacking.c
* @example evas-stacking.c
*/
+
+/**
+ * @page Example_Evas_Map_Overview Evas Map - Overview
+ * @dontinclude evas-map-utils.c
+ *
+ * Down to the very bottom, Map is simple: it takes an object and transforms
+ * the way it will be shown on screen. But using it properly can be a bit
+ * troublesome.
+ *
+ * For the most common operations there are utility functions that help in
+ * setting up the map to achieve the desired effects. Now we'll go through
+ * an overview of the map API and some of the things that can be done with
+ * it.
+ *
+ * The full code can be found @ref evas-map-utils.c "here".
+ *
+ * To show how some funtions work, this example listens to keys pressed to
+ * toggle several options.
+ * @skip typedef
+ * @until App_Data
+ * @until ;
+ *
+ * In this program, we divide the window in four quadrants, each holding an
+ * object that will have different map configurations applied to them in each
+ * call to an animator function.
+ * @skip static Eina_Bool
+ * @until evas_output_size_get
+ *
+ * Let's first create a map and set some of our options to it. Only four
+ * points maps are supported, so we'll stick to that magic number. We can
+ * set a color for each vertex or apply one for all of them at once
+ * @until evas_map_util_points_color_set
+ *
+ * For the first object, we'll have a plain rectangle. At its cration, this
+ * rectangle was set to be semi-transparent, but whether its own alpha is
+ * used will be defined by the map's alpha setting. If the map's alpha is
+ * disabled, then the object will be completely opaque. The map's own color,
+ * however, will use any alpha set to it.
+ *
+ * So we get our object, initialize our map geometry to match the rectangle
+ * and make it rotate around its own center, then apply the map to the
+ * object so it takes effect.
+ * @until evas_object_map_enable_set
+ *
+ * The second object is an image. Here we don't have any color set for the
+ * object, but the image itself contains an alpha channel that will not be
+ * affected by the map settings, so even with alpha set to be off, the image
+ * will still be transparent. Color applied to the map will tint it though.
+ * Since setting a map copies it into the object, we can reuse the same one
+ * we created before. We initialize it to the new object while all other
+ * options are kept the same. Notice that no rotation will be done here, as
+ * that's just an utility function that takes the coordinates set for each
+ * point of the map and transforms it accordingly.
+ * @until evas_map_util_points_populate_from_object_full
+ *
+ * This time the object is a bit farther into the screen, by using a @c z
+ * value higher than 0 to init the map. We also need to map the image used
+ * by the object, so Evas knows how to transform it properly. For this we
+ * use the evas_map_point_image_uv_set() to tell the map what coordinate
+ * within the image corresponds to each point of the map.
+ * @until evas_map_point_image_uv_set(m, 3
+ *
+ * This object will also be rotated, but in all three axis and around some
+ * other point, not its center, chosen mostly at random. If enabled, lighting
+ * will be applied to, from a light source at the center of the window.
+ * @until evas_object_map_enable_set
+ *
+ * For the third object we are doing, once more, a 3D rotation, but this time
+ * perspective will be applied to our map to make it look more realistic.
+ * The lighting source also follows the mouse cursor and it's possible to
+ * toggle backface culling, so that the object is hidden whenever we are
+ * not seeing its front face.
+ * @until evas_object_map_enable_set
+ *
+ * And we free this map, since since we messed too much with it and for the
+ * last object we want something cleaner.
+ * @until evas_map_free
+ *
+ * The last object is actually two. One image, with an image set to it, and
+ * one image proxying the first one with evas_object_image_source_set(). This
+ * way, the second object will show whatever content its source has.
+ * This time we'll be using a map more manually to simulate a simple reflection
+ * of the original image.
+ *
+ * We know that the reflection object is placed just like the original, so
+ * we take a shortcut by just getting the geometry of our to-be-mapped object.
+ * We also need to get the image size of the source.
+ * @until evas_object_image_size_get
+ *
+ * For this we'll create a map shaped so that it begins at the base of our
+ * image and it expands horizontally as it grows (downwards) in height.
+ * @until evas_map_point_coord_set(m, 3
+ *
+ * Since the reflection should show the image inverted, we need to map it
+ * this way. The first point of the map (top-left) will be mapped to the
+ * mapped to the first pixel of the last row. There's no horizontal reflection
+ * and we want the full width of the image, but as we map its upper side ww
+ * will only take two thirds of the image.
+ * @until evas_map_point_image_uv_set(m, 3
+ *
+ * Finally, to fade out our reflection we set the colors for each point in
+ * the map. The two at the top need to be visible, but we'll tone them down
+ * a bit and make them a bit translucent. The other two will go straight to
+ * full transparency. Evas interpolates the colors from one point to the next,
+ * so this will make them fade out.
+ * @until evas_object_map_enable_set
+ *
+ * Close up by freeing the map and do some other things needed to keep stuff
+ * moving in our animations and we are done.
+ * @until }
+ *
+ * The rest of the program is setup and listening to key events. Nothing that
+ * matters within the scope of this example, so we are going to skip it.
+ * Refer to it @ref evas-map-utils.c "here" however to see how everything
+ * fits together.
+ *
+ * @example evas-map-utils.c
+ */
--- /dev/null
+/*
+ * gcc -o evas-map-utils evas-map-utils.c `pkg-config --cflags --libs evas ecore ecore-evas`
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define __UNUSED__
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#define WIDTH 480
+#define HEIGHT 480
+
+typedef struct
+{
+ Ecore_Evas *ee;
+ Evas *canvas;
+ struct {
+ int r, g, b, a;
+ } colors[6];
+ int colors_index;
+ int frame;
+ Eina_Bool alpha : 1;
+ Eina_Bool smooth : 1;
+ Eina_Bool backface_culling : 1;
+ Eina_Bool apply_perspective : 1;
+ Eina_Bool apply_lighting : 1;
+} App_Data;
+
+static const char *help_string =
+ "Valid commands:\n"
+ "\ta - toggle alpha for maps\n"
+ "\ts - toggle smooth for maps\n"
+ "\tc - switch map color\n"
+ "\tb - toggle backface culling\n"
+ "\tp - toggle perspective\n"
+ "\tl - toggle lighting\n"
+ "\th - prints this help\n";
+
+static Eina_Bool
+_anim_cb(void *data)
+{
+ App_Data *ad = data;
+ Evas_Map *m;
+ const Evas_Map *old_map;
+ Evas_Object *o;
+ int r, g, b, a;
+ int win_w, win_h, img_w, img_h;
+ Evas_Coord x, y, w, h;
+
+ evas_output_size_get(ad->canvas, &win_w, &win_h);
+
+ m = evas_map_new(4);
+ evas_map_smooth_set(m, ad->smooth);
+ evas_map_alpha_set(m, ad->alpha);
+
+ r = ad->colors[ad->colors_index].r;
+ g = ad->colors[ad->colors_index].g;
+ b = ad->colors[ad->colors_index].b;
+ a = ad->colors[ad->colors_index].a;
+ evas_map_util_points_color_set(m, r, g, b, a);
+
+ o = evas_object_name_find(ad->canvas, "obj1");
+ evas_object_geometry_get(o, &x, &y, &w, &h);
+
+ evas_map_util_points_populate_from_object(m, o);
+ evas_map_util_rotate(m, 3 * ad->frame, x + (w / 2), y + (h / 2));
+ evas_object_map_set(o, m);
+ evas_object_map_enable_set(o, EINA_TRUE);
+
+ o = evas_object_name_find(ad->canvas, "obj2");
+ evas_object_geometry_get(o, &x, &y, &w, &h);
+ evas_object_image_size_get(o, &img_w, &img_h);
+
+ evas_map_util_points_populate_from_object_full(m, o, 100);
+ evas_map_point_image_uv_set(m, 0, 0, 0);
+ evas_map_point_image_uv_set(m, 1, img_w, 0);
+ evas_map_point_image_uv_set(m, 2, img_w, img_h);
+ evas_map_point_image_uv_set(m, 3, 0, img_h);
+ evas_map_util_3d_rotate(m, ad->frame * 6, ad->frame * 6, ad->frame * 6,
+ x + (w / 3), y + 10, 0);
+ if (ad->apply_lighting)
+ evas_map_util_3d_lighting(m, win_w / 2, win_h / 2, -100,
+ 255, 255, 255, 0, 0, 0);
+ evas_object_map_set(o, m);
+ evas_object_map_enable_set(o, EINA_TRUE);
+
+ o = evas_object_name_find(ad->canvas, "obj3");
+ evas_object_geometry_get(o, &x, &y, &w, &h);
+ evas_object_image_size_get(o, &img_w, &img_h);
+
+ evas_map_util_points_populate_from_geometry(m, x, y + (h / 2), w, h, -20);
+ evas_map_point_image_uv_set(m, 0, 0, 0);
+ evas_map_point_image_uv_set(m, 1, img_w, 0);
+ evas_map_point_image_uv_set(m, 2, img_w, img_h);
+ evas_map_point_image_uv_set(m, 3, 0, img_h);
+ evas_map_util_3d_rotate(m, 20, ad->frame * 6, 0,
+ x + (w / 2), y + (w / 2), w / 2);
+
+ if (ad->apply_perspective)
+ evas_map_util_3d_perspective(m, x + (w / 2), y + (h / 2), 0, 256);
+ if (ad->apply_lighting)
+ {
+ Evas_Coord mx, my;
+ evas_pointer_canvas_xy_get(ad->canvas, &mx, &my);
+ evas_map_util_3d_lighting(m, mx, my, -256,
+ 255, 255, 255, 0, 0, 0);
+ }
+ if (ad->backface_culling)
+ {
+ if (evas_map_util_clockwise_get(m))
+ evas_object_show(o);
+ else
+ evas_object_hide(o);
+ }
+ else
+ evas_object_show(o);
+ evas_object_map_set(o, m);
+ evas_object_map_enable_set(o, EINA_TRUE);
+
+ evas_map_free(m);
+
+ o = evas_object_name_find(ad->canvas, "obj4");
+ evas_object_geometry_get(o, &x, &y, &w, &h);
+ evas_object_image_size_get(evas_object_image_source_get(o), &img_w, &img_h);
+
+ m = evas_map_new(4);
+ evas_map_point_coord_set(m, 0, x, y + h, 0);
+ evas_map_point_coord_set(m, 1, x + w, y + h, 0);
+ evas_map_point_coord_set(m, 2, win_w - 10, win_h - 30, 0);
+ evas_map_point_coord_set(m, 3, (win_w / 2) + 10, win_h - 30, 0);
+ evas_map_point_image_uv_set(m, 0, 0, img_h);
+ evas_map_point_image_uv_set(m, 1, img_w, img_h);
+ evas_map_point_image_uv_set(m, 2, img_w, 2 * (img_h / 3));
+ evas_map_point_image_uv_set(m, 3, 0, 2 * (img_h / 3));
+ evas_map_point_color_set(m, 0, 200, 200, 200, 150);
+ evas_map_point_color_set(m, 1, 200, 200, 200, 150);
+ evas_map_point_color_set(m, 2, 0, 0, 0, 0);
+ evas_map_point_color_set(m, 3, 0, 0, 0, 0);
+ evas_object_map_set(o, m);
+ evas_object_map_enable_set(o, EINA_TRUE);
+
+ evas_map_free(m);
+
+ ad->frame = (ad->frame + 1) % 60;
+
+ return EINA_TRUE;
+}
+
+static void
+_on_keydown(void *data, Evas *e, Evas_Object *o, void *event)
+{
+ App_Data *ad = data;
+ Evas_Event_Key_Down *ev = event;
+ const Evas_Modifier *mods;
+
+ mods = evas_key_modifier_get(ad->canvas);
+ switch (ev->keyname[0])
+ {
+ case 'a':
+ ad->alpha = !ad->alpha;
+ break;
+ case 's':
+ ad->smooth = !ad->smooth;
+ break;
+ case 'c':
+ ad->colors_index = (ad->colors_index + 1) % 6;
+ break;
+ case 'b':
+ ad->backface_culling = !ad->backface_culling;
+ break;
+ case 'p':
+ ad->apply_perspective = !ad->apply_perspective;
+ break;
+ case 'l':
+ ad->apply_lighting = !ad->apply_lighting;
+ break;
+ case 'h':
+ puts(help_string);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+_objs_fit(Evas *e)
+{
+ Evas_Object *o;
+ int w, h;
+
+ evas_output_size_get(e, &w, &h);
+ w /= 2;
+ h /= 2;
+
+ o = evas_object_name_find(e, "obj1");
+ evas_object_move(o, w / 4, h / 4);
+ evas_object_resize(o, w / 2, h / 2);
+
+ o = evas_object_name_find(e, "obj2");
+ evas_object_move(o, 5 * w / 4, h / 4);
+ evas_object_resize(o, w / 2, h / 2);
+
+ o = evas_object_name_find(e, "obj3");
+ evas_object_move(o, w / 4, 5 * h / 4);
+ evas_object_resize(o, w / 2, h / 2);
+
+ o = evas_object_name_find(e, "obj4_source");
+ evas_object_move(o, 5 * w / 4, 5 * h / 4);
+ evas_object_resize(o, w / 2, h / 2);
+
+ o = evas_object_name_find(e, "obj4");
+ evas_object_move(o, 5 * w / 4, 5 * h / 4);
+ evas_object_resize(o, w / 2, h / 2);
+}
+
+static void
+_on_resize(void *data __UNUSED__, Evas *e, Evas_Object *o __UNUSED__, void *event __UNUSED__)
+{
+ _objs_fit(e);
+}
+
+static void
+_on_free(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event __UNUSED__)
+{
+ ecore_main_loop_quit();
+}
+
+int
+main(void)
+{
+ Evas_Object *bg, *o, *osrc;
+ static App_Data d = {
+ .ee = NULL,
+ .canvas = NULL,
+ .colors = {
+ { 255, 255, 255, 255 },
+ { 128, 128, 0, 128 },
+ { 255, 0, 0, 255 },
+ { 64, 128, 255, 255 },
+ { 11, 23, 58, 132 },
+ { 0, 0, 0, 255 }
+ },
+ .colors_index = 0,
+ .frame = 0,
+ .alpha = EINA_FALSE,
+ .smooth = EINA_FALSE,
+ .backface_culling = EINA_FALSE,
+ .apply_perspective = EINA_TRUE,
+ .apply_lighting = EINA_TRUE
+ };
+
+ if (!ecore_evas_init())
+ return EXIT_FAILURE;
+
+ d.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
+ if (!d.ee)
+ goto error;
+
+ d.canvas = ecore_evas_get(d.ee);
+
+ bg = evas_object_image_filled_add(d.canvas);
+ evas_object_image_file_set(bg, "cube1.png", NULL);
+ ecore_evas_object_associate(d.ee, bg, 0);
+ evas_object_focus_set(bg, EINA_TRUE);
+ evas_object_move(bg, 0, 0);
+ evas_object_resize(bg, WIDTH, HEIGHT);
+ evas_object_show(bg);
+
+ o = evas_object_rectangle_add(d.canvas);
+ evas_object_name_set(o, "obj1");
+ evas_object_color_set(o, 128, 0, 200, 200);
+ evas_object_show(o);
+
+ o = evas_object_image_filled_add(d.canvas);
+ evas_object_name_set(o, "obj2");
+ evas_object_image_file_set(o, "enlightenment.png", NULL);
+ evas_object_show(o);
+
+ o = evas_object_image_filled_add(d.canvas);
+ evas_object_name_set(o, "obj3");
+ evas_object_image_file_set(o, "enlightenment.png", NULL);
+ evas_object_show(o);
+
+ osrc = evas_object_image_filled_add(d.canvas);
+ evas_object_image_file_set(osrc, "im1.png", NULL);
+ evas_object_name_set(osrc, "obj4_source");
+ evas_object_show(osrc);
+
+ o = evas_object_image_filled_add(d.canvas);
+ evas_object_image_source_set(o, osrc);
+ evas_object_name_set(o, "obj4");
+ evas_object_show(o);
+
+ _objs_fit(d.canvas);
+
+ evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, &d);
+ evas_object_event_callback_add(bg, EVAS_CALLBACK_RESIZE, _on_resize, NULL);
+ evas_object_event_callback_add(bg, EVAS_CALLBACK_FREE, _on_free, NULL);
+
+ ecore_animator_add(_anim_cb, &d);
+
+ ecore_main_loop_begin();
+
+ 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;
+}
* care. The impact on performance depends on engine in
* use. Software is quite optimized, but not as fast as OpenGL.
*
+ * Examples:
+ * @li @ref Example_Evas_Map_Overview
+ *
* @ingroup Evas_Object_Group
+ *
+ * @{
*/
/**
* Enable or disable the map that is set.
*
- * This enables the map that is set or disables it. On enable, the object
- * geometry will be saved, and the new geometry will change (position and
- * size) to reflect the map geometry set. If none is set yet, this may be
- * an undefined geometry, unless you have already set the map with
- * evas_object_map_set(). It is suggested you first set a map with
- * evas_object_map_set() with valid useful coordinates then enable and
- * disable the map with evas_object_map_enable_set() as needed.
+ * Enable or disable the use of map for the object @p obj.
+ * On enable, the object geometry will be saved, and the new geometry will
+ * change (position and size) to reflect the map geometry set.
+ *
+ * If the object doesn't have a map set (with evas_object_map_set()), the
+ * initial geometry will be undefined. It is adviced to always set a map
+ * to the object first, and then call this function to enable its use.
*
* @param obj object to enable the map on
* @param enabled enabled state
/**
* Get the map source object
*
- * See evas_object_map_source_set()
- *
* @param obj object to set the map source of
* @return the object set as the source
+ *
+ * @see evas_object_map_source_set()
*/
EAPI Evas_Object *evas_object_map_source_get (const Evas_Object *obj);
*
* Like evas_map_util_rotate(), this zooms the points of the map from a center
* point. That center is defined by @p cx and @p cy. The @p zoomx and @p zoomy
- * parameters specific how much to zoom in the X and Y direction respectively.
+ * parameters specify how much to zoom in the X and Y direction respectively.
* A value of 1.0 means "don't zoom". 2.0 means "dobule the size". 0.5 is
* "half the size" etc. All coordinates are canvas global coordinates.
*
* around the X, Y and Z axes. The Z axis points "into" the screen with low
* values at the screen and higher values further away. The X axis runs from
* left to right on the screen and the Y axis from top to bottom. Like with
- * evas_map_util_rotate(0 you provide a center point to rotate around (in 3D).
+ * evas_map_util_rotate() you provide a center point to rotate around (in 3D).
*
* @param m map to change.
* @param dx amount of degrees from 0.0 to 360.0 to rotate arount X axis.
* number for @p count will work). That is empty and ready to be modified
* with evas_map calls.
*
- * @param count number of points in the map. *
+ * @param count number of points in the map.
* @return a newly allocated map or @c NULL on errors.
*
* @see evas_map_free()
*
* This sets alpha flag for map rendering. If the object is a type that has
* its own alpha settings, then this will take precedence. Only image objects
- * have this currently. Fits stops alpha blending of the map area, and is
+ * have this currently.
+ * Setting this off stops alpha blending of the map area, and is
* useful if you know the object and/or all sub-objects is 100% solid.
*
* @param m map to modify. Must not be NULL.
/**
* Change the map point's coordinate.
*
- * This sets the fixen point's coordinate in the map. Note that points
+ * This sets the fixed point's coordinate in the map. Note that points
* describe the outline of a quadrangle and are ordered either clockwise
* or anit-clock-wise. It is suggested to keep your quadrangles concave and
* non-complex, though these polygon modes may work, they may not render
* @see evas_object_map_set()
*/
EAPI void evas_map_point_color_get (const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
+/**
+ * @}
+ */
/**
* @defgroup Evas_Object_Group_Size_Hints Size Hints