Evas Map, little clarifications and an overview example

SVN revision: 61010
This commit is contained in:
Iván Briano 2011-07-04 15:22:53 +00:00
parent 53d0a3fe82
commit c10661b430
6 changed files with 474 additions and 17 deletions

View File

@ -368,3 +368,121 @@
* @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
*/

View File

@ -77,6 +77,10 @@ evas_aspect_hints_DEPS = $(srcdir)/aspect.edc
evas_aspect_hints_SOURCES = evas-aspect-hints.c
evas_aspect_hints_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@ @EDJE_LIBS@
pkglib_PROGRAMS += evas_map_utils
evas_map_utils_SOURCES = evas-map-utils.c
evas_map_utils_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
aspect.edj: ${evas_aspect_hints_DEPS}
.edc.edj:
@ -92,7 +96,9 @@ if INSTALL_EXAMPLES
#put here additional data when installing examples
files_DATA += $(srcdir)/enlightenment.png \
$(srcdir)/red.png
$(srcdir)/red.png \
$(srcdir)/im1.png \
$(srcdir)/cube1.png
files_DATA += \
$(EDCS) \
@ -104,7 +110,8 @@ files_DATA += \
$(srcdir)/evas-events.c \
$(srcdir)/evas-aspect-hints.c \
$(srcdir)/evas-hints.c \
$(srcdir)/evas-stacking.c
$(srcdir)/evas-stacking.c \
$(srcdir)/evas-map-utils.c
endif
EXTRA_DIST = $(EDCS) \
@ -118,4 +125,6 @@ EXTRA_DIST = $(EDCS) \
$(srcdir)/evas-hints.c \
$(srcdir)/evas-stacking.c \
$(srcdir)/enlightenment.png \
$(srcdir)/red.png
$(srcdir)/red.png \
$(srcdir)/im1.png \
$(srcdir)/cube1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -0,0 +1,321 @@
/*
* 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -3820,19 +3820,24 @@ EAPI Eina_Bool evas_object_propagate_events_get (const Evas_Object *ob
* 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
@ -3867,10 +3872,10 @@ EAPI void evas_object_map_source_set (Evas_Object *obj, Evas
/**
* 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);
@ -4044,7 +4049,7 @@ EAPI void evas_map_util_rotate (Evas_Map *
*
* 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.
*
@ -4067,7 +4072,7 @@ EAPI void evas_map_util_zoom (Evas_Map *
* 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.
@ -4148,7 +4153,7 @@ EAPI Eina_Bool evas_map_util_clockwise_get (Evas_Map *
* 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()
@ -4188,7 +4193,8 @@ EAPI Eina_Bool evas_map_smooth_get (const Evas_Map *m);
*
* 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.
@ -4238,7 +4244,7 @@ EAPI int evas_map_count_get (const Evas_Map *m) EINA
/**
* 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
@ -4351,6 +4357,9 @@ EAPI void evas_map_point_color_set (Evas_Map *m, int idx,
* @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