~\newline


This example demonstrates how someone can set a perspective to be used by an Edje object, but setting a global perspective.

The A\+PI for setting a perspective for just one Edje object is almost the same and it\textquotesingle{}s trivial, so we are not doing that on this example.

Let\textquotesingle{}s go first to the main function, where we start creating our objects and loading the theme. We also set some variables that will be used globally in our program\+:

 
\begin{DoxyCodeInclude}
main(\textcolor{keywordtype}{int} argc \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keywordtype}{char} *argv[] \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}})
\{
   \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *edje\_file = PACKAGE\_DATA\_DIR\textcolor{stringliteral}{"/perspective.edj"};
   \textcolor{keyword}{struct }\_App  app;
   Ecore\_Evas  *ee;
   \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}}        *\mbox{\hyperlink{namespaceevas}{evas}};

   \textcolor{keywordflow}{if} (!\mbox{\hyperlink{group__Ecore__Evas__Group_ga32ddbb6457033ad435a177eb0c4fe235}{ecore\_evas\_init}}())
     \textcolor{keywordflow}{return} EXIT\_FAILURE;

   \textcolor{keywordflow}{if} (!\mbox{\hyperlink{group__Edje__General__Group_ga1c9c6594f38023c29fbfb2d0c8c675db}{edje\_init}}())
     \textcolor{keywordflow}{goto} shutdown\_ecore\_evas;

   \mbox{\hyperlink{group__Edje__Object__Animation_gac9b19ee918546740c0144904393a1acd}{edje\_frametime\_set}}(1.0 / 60.0);

   \textcolor{comment}{/* this will give you a window with an Evas canvas under the first}
\textcolor{comment}{    * engine available */}
   app.animating = \mbox{\hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE}};
   app.x = 0;
   app.y = 0;
   app.focal = 50;

\end{DoxyCodeInclude}


A boolean is used to indicate that we are animating.

We also set the {\ttfamily app.\+x} and {\ttfamily app.\+y} to (0, 0) because the original position of our text + rectangle part will be on top left. This is a convention that we are using in this example, and setting x, y to 1, 1 would mean bottom right. We do this to later define the name of the signals that we are sending to the theme.

After this, some boilerplate code to load the theme\+:


\begin{DoxyCodeInclude}

   ee = \mbox{\hyperlink{group__Ecore__Evas__Group_gac7f2cdbcb79635c34317c1183dd04cb0}{ecore\_evas\_new}}(NULL, 0, 0, WIDTH, HEIGHT, NULL);
   \textcolor{keywordflow}{if} (!ee) \textcolor{keywordflow}{goto} shutdown\_edje;

   \mbox{\hyperlink{group__Ecore__Evas__Group_ga3680b5c89157167318192157a5d24ec4}{ecore\_evas\_callback\_destroy\_set}}(ee, \_on\_destroy);
   \mbox{\hyperlink{group__Ecore__Evas__Group_gaac67f679c9027059a34519fbdea360df}{ecore\_evas\_callback\_resize\_set}}(ee, \_on\_canvas\_resize);
   \mbox{\hyperlink{group__Ecore__Evas__Group_ga3b2832e0373bbafae2bb7143618535c1}{ecore\_evas\_title\_set}}(ee, \textcolor{stringliteral}{"Edje Perspective Example"});

   \mbox{\hyperlink{group__Ecore__Evas__Group_gaa86c5abd200a02711aced53d27b9ddb2}{ecore\_evas\_data\_set}}(ee, \textcolor{stringliteral}{"app"}, &app);

   \mbox{\hyperlink{namespaceevas}{evas}} = \mbox{\hyperlink{group__Ecore__Evas__Group_ga75a7cc694b6069e78df47dab0b0f2d20}{ecore\_evas\_get}}(ee);

   app.bg = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(\mbox{\hyperlink{namespaceevas}{evas}});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(app.bg, 255, 255, 255, 255);
   evas\_object\_resize(app.bg, WIDTH, HEIGHT);
   evas\_object\_focus\_set(app.bg, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(app.bg);

\end{DoxyCodeInclude}


Now we are going to setup a callback to tell us that the animation has ended. We do this just to avoid sending signals to the theme while it\textquotesingle{}s animating.


\begin{DoxyCodeInclude}

   \mbox{\hyperlink{group__Evas__Object__Group__Events_ga23be30ac5cdfb780f1ff82e9108ec26b}{evas\_object\_event\_callback\_add}}(app.bg, 
      \mbox{\hyperlink{Evas__Common_8h_ad64cde0da38a60e7cb7905b3ab216968a336b86bad4f145f84c155e4922335584}{EVAS\_CALLBACK\_KEY\_DOWN}}, \_on\_bg\_key\_down, &app);

   app.edje\_obj = edje\_object\_add(\mbox{\hyperlink{namespaceevas}{evas}});

   edje\_object\_file\_set(app.edje\_obj, edje\_file, \textcolor{stringliteral}{"example/group"});
   evas\_object\_move(app.edje\_obj, 0, 0);
   evas\_object\_resize(app.edje\_obj, WIDTH, HEIGHT);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(app.edje\_obj);

   edje\_object\_signal\_callback\_add(app.edje\_obj, \textcolor{stringliteral}{"animation,end"}, \textcolor{stringliteral}{""}, \_animation\_end\_cb, &app);

\end{DoxyCodeInclude}


Finally, let\textquotesingle{}s create our perspective object, define its position, focal distance and z plane position, and set it as global\+:


\begin{DoxyCodeInclude}

   app.ps = \mbox{\hyperlink{group__Edje__Perspective_ga4ce415ab5a9f53ba55d921ab5c48a2f4}{edje\_perspective\_new}}(\mbox{\hyperlink{namespaceevas}{evas}});
   \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app.ps, 240, 160, 0, app.focal);
   \mbox{\hyperlink{group__Edje__Perspective_ga9e560272fb6b954a9e99eaad72a6755f}{edje\_perspective\_global\_set}}(app.ps, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

\end{DoxyCodeInclude}


Notice that if we wanted to set it just to our edje object, instead of setting the perspective as global to the entire canvas, we could just use edje\+\_\+object\+\_\+perspective\+\_\+set() instead of \mbox{\hyperlink{group__Edje__Perspective_ga9e560272fb6b954a9e99eaad72a6755f}{edje\+\_\+perspective\+\_\+global\+\_\+set()}}. The rest of the code would be exactly the same.

Now, let\textquotesingle{}s take a look at what we do in our callbacks.

The callback for key\+\_\+down is converting the arrow keys to a signal that represents where we want our text and rectangle moved to. It does that by using the following function\+:

 
\begin{DoxyCodeInclude}
\_part\_move(\textcolor{keyword}{struct} \_App *app, \textcolor{keywordtype}{int} dx, \textcolor{keywordtype}{int} dy)
\{
   \textcolor{keywordtype}{char} emission[64];

   \textcolor{keywordflow}{if} (app->animating)
     \textcolor{keywordflow}{return};

   app->x += dx;
   app->y += dy;
   \textcolor{keywordflow}{if} (app->x > 1)
     app->x = 1;
   \textcolor{keywordflow}{if} (app->x < 0)
     app->x = 0;
   \textcolor{keywordflow}{if} (app->y > 1)
     app->y = 1;
   \textcolor{keywordflow}{if} (app->y < 0)
     app->y = 0;

   snprintf(emission, \textcolor{keyword}{sizeof}(emission), \textcolor{stringliteral}{"move,%d,%d"}, app->x, app->y);
   edje\_object\_signal\_emit(app->edje\_obj, emission, \textcolor{stringliteral}{""});
   app->animating = \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}};
\}

\end{DoxyCodeInclude}


Notice that, after sending the signal to the Edje object, we set our boolean to store that we are animating now. It will only be unset when we receive a signal from the theme that the animation has ended.

Now, on the key\+\_\+down code, we just call this function when the arrows or \char`\"{}\+Pg\+Up\char`\"{} or \char`\"{}\+Pg\+Down\char`\"{} keys are pressed\+:


\begin{DoxyCodeInclude}


\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_on\_bg\_key\_down(\textcolor{keywordtype}{void} *data, \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *e \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *o 
      \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keywordtype}{void} *event\_info)
\{
   \textcolor{keyword}{struct }\_App *app = data;
   \mbox{\hyperlink{struct__Evas__Event__Key__Down}{Evas\_Event\_Key\_Down}} *ev = event\_info;

   \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"h"}))
     \{
        printf(commands);
        \textcolor{keywordflow}{return};
     \}
   \textcolor{comment}{// just moving the part and text}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Down"}))
     \{
        \_part\_move(app, 0, 1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Up"}))
     \{
        \_part\_move(app, 0, -1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Left"}))
     \{
        \_part\_move(app, -1, 0);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Right"}))
     \{
        \_part\_move(app, 1, 0);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Prior"}))
     \{
        \_part\_move(app, -1, -1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Next"}))
     \{
        \_part\_move(app, 1, 1);
     \}
   \textcolor{comment}{// adjusting the perspective focal point distance}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"KP\_Add"}))
     \{
        app->focal += 5;
        \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app->ps, 240, 160, 0, app->focal);
        edje\_object\_calc\_force(app->edje\_obj);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"KP\_Subtract"}))
     \{
        app->focal -= 5;
        \textcolor{keywordflow}{if} (app->focal < 5)
          app->focal = 5;

        \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app->ps, 240, 160, 0, app->focal);
        edje\_object\_calc\_force(app->edje\_obj);
     \}
   \textcolor{comment}{// exiting}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Escape"}))
     \mbox{\hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}}();
   \textcolor{keywordflow}{else}
     \{
        printf(\textcolor{stringliteral}{"unhandled key: %s\(\backslash\)n"}, ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}});
        printf(commands);
     \}

\end{DoxyCodeInclude}


Notice that we also do something else when the numeric keyboard \char`\"{}+\char`\"{} and \char`\"{}-\/\char`\"{} keys are pressed. We change the focal distance of our global perspective, and that will affect the part that has a map rotation applied to it, with perspective enabled. We also need to call edje\+\_\+object\+\_\+calc\+\_\+force(), otherwise the Edje object has no way to know that we changed the global perspective.

Try playing with these keys and see what happens to the animation when the value of the focal distance changes.

Finally we add a callback for the animation ended signal\+:


\begin{DoxyCodeInclude}
\_animation\_end\_cb(\textcolor{keywordtype}{void} *data, \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *o \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *emission 
      \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *source \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}})
\{
   \textcolor{keyword}{struct }\_App *app = data;

   app->animating = \mbox{\hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE}};
\}

\end{DoxyCodeInclude}


The example\textquotesingle{}s window should look like this picture\+:

  
\begin{DoxyImageNoCaption}
  \mbox{\includegraphics[width=\textwidth]{edje-perspective-example}}
\end{DoxyImageNoCaption}


The full source code follows\+: 
\begin{DoxyCodeInclude}

\textcolor{preprocessor}{#ifdef HAVE\_CONFIG\_H}
\textcolor{preprocessor}{# include "config.h"}
\textcolor{preprocessor}{#else}
\textcolor{preprocessor}{# define EINA\_UNUSED}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#ifndef PACKAGE\_DATA\_DIR}
\textcolor{preprocessor}{#define PACKAGE\_DATA\_DIR "."}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#include <Ecore.h>}
\textcolor{preprocessor}{#include <\mbox{\hyperlink{Ecore__Evas_8h}{Ecore\_Evas.h}}>}
\textcolor{preprocessor}{#include <\mbox{\hyperlink{Edje_8h}{Edje.h}}>}

\textcolor{preprocessor}{#define WIDTH  480}
\textcolor{preprocessor}{#define HEIGHT 320}

\textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{char} commands[] = \(\backslash\)
  \textcolor{stringliteral}{"commands are:\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tDown - move part down\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tUp -  move part up\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tLeft - move part left\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tRight - move part right\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tPrior - move part up-left\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tNext - move part down-right\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tInsert - increase focal\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tSuppr - decrease focal\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)tEsc - exit\(\backslash\)n"}
  \textcolor{stringliteral}{"\(\backslash\)th - print help\(\backslash\)n"};

\textcolor{keyword}{struct }\_App \{
    \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *edje\_obj;
    \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *bg;
    \mbox{\hyperlink{group__Edje_gaa34f2bebed885cea3d891858ad7c2e2b}{Edje\_Perspective}} *ps;
    \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}} animating;
    \textcolor{keywordtype}{int} x, y; \textcolor{comment}{// relative position of part in the screen}
    \textcolor{keywordtype}{int} focal;
\};

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_on\_destroy(Ecore\_Evas *ee \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}})
\{
   \mbox{\hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}}();
\}

\textcolor{comment}{/* here just to keep our example's window size and background image's}
\textcolor{comment}{ * size in synchrony */}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_on\_canvas\_resize(Ecore\_Evas *ee)
\{
   \textcolor{keywordtype}{int} w, h;
   \textcolor{keyword}{struct }\_App *app = \mbox{\hyperlink{group__Ecore__Evas__Group_gae00d4a4feb8aec5de03e464fe21a1d30}{ecore\_evas\_data\_get}}(ee, \textcolor{stringliteral}{"app"});

   \mbox{\hyperlink{group__Ecore__Evas__Group_ga931aadf4603731e73e8a84e4b14f1493}{ecore\_evas\_geometry\_get}}(ee, NULL, NULL, &w, &h);
   evas\_object\_resize(app->bg, w, h);
   evas\_object\_resize(app->edje\_obj, w, h);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_part\_move(\textcolor{keyword}{struct} \_App *app, \textcolor{keywordtype}{int} dx, \textcolor{keywordtype}{int} dy)
\{
   \textcolor{keywordtype}{char} emission[64];

   \textcolor{keywordflow}{if} (app->animating)
     \textcolor{keywordflow}{return};

   app->x += dx;
   app->y += dy;
   \textcolor{keywordflow}{if} (app->x > 1)
     app->x = 1;
   \textcolor{keywordflow}{if} (app->x < 0)
     app->x = 0;
   \textcolor{keywordflow}{if} (app->y > 1)
     app->y = 1;
   \textcolor{keywordflow}{if} (app->y < 0)
     app->y = 0;

   snprintf(emission, \textcolor{keyword}{sizeof}(emission), \textcolor{stringliteral}{"move,%d,%d"}, app->x, app->y);
   edje\_object\_signal\_emit(app->edje\_obj, emission, \textcolor{stringliteral}{""});
   app->animating = \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}};
\}


\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_on\_bg\_key\_down(\textcolor{keywordtype}{void} *data, \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *e \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *o 
      \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keywordtype}{void} *event\_info)
\{
   \textcolor{keyword}{struct }\_App *app = data;
   \mbox{\hyperlink{struct__Evas__Event__Key__Down}{Evas\_Event\_Key\_Down}} *ev = event\_info;

   \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"h"}))
     \{
        printf(commands);
        \textcolor{keywordflow}{return};
     \}
   \textcolor{comment}{// just moving the part and text}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Down"}))
     \{
        \_part\_move(app, 0, 1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Up"}))
     \{
        \_part\_move(app, 0, -1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Left"}))
     \{
        \_part\_move(app, -1, 0);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Right"}))
     \{
        \_part\_move(app, 1, 0);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Prior"}))
     \{
        \_part\_move(app, -1, -1);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Next"}))
     \{
        \_part\_move(app, 1, 1);
     \}
   \textcolor{comment}{// adjusting the perspective focal point distance}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"KP\_Add"}))
     \{
        app->focal += 5;
        \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app->ps, 240, 160, 0, app->focal);
        edje\_object\_calc\_force(app->edje\_obj);
     \}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"KP\_Subtract"}))
     \{
        app->focal -= 5;
        \textcolor{keywordflow}{if} (app->focal < 5)
          app->focal = 5;

        \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app->ps, 240, 160, 0, app->focal);
        edje\_object\_calc\_force(app->edje\_obj);
     \}
   \textcolor{comment}{// exiting}
   \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (!strcmp(ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}}, \textcolor{stringliteral}{"Escape"}))
     \mbox{\hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}}();
   \textcolor{keywordflow}{else}
     \{
        printf(\textcolor{stringliteral}{"unhandled key: %s\(\backslash\)n"}, ev->\mbox{\hyperlink{struct__Evas__Event__Key__Down_a70473bba88a1afaee180a54150513824}{key}});
        printf(commands);
     \}
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
\_animation\_end\_cb(\textcolor{keywordtype}{void} *data, \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *o \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *emission 
      \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *source \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}})
\{
   \textcolor{keyword}{struct }\_App *app = data;

   app->animating = \mbox{\hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE}};
\}

\textcolor{keywordtype}{int}
main(\textcolor{keywordtype}{int} argc \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}}, \textcolor{keywordtype}{char} *argv[] \mbox{\hyperlink{group__Eina__Types__Group_ga82d751be730f849719ca292f9558be87}{EINA\_UNUSED}})
\{
   \textcolor{keyword}{const} \textcolor{keywordtype}{char}  *edje\_file = PACKAGE\_DATA\_DIR\textcolor{stringliteral}{"/perspective.edj"};
   \textcolor{keyword}{struct }\_App  app;
   Ecore\_Evas  *ee;
   \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}}        *\mbox{\hyperlink{namespaceevas}{evas}};

   \textcolor{keywordflow}{if} (!\mbox{\hyperlink{group__Ecore__Evas__Group_ga32ddbb6457033ad435a177eb0c4fe235}{ecore\_evas\_init}}())
     \textcolor{keywordflow}{return} EXIT\_FAILURE;

   \textcolor{keywordflow}{if} (!\mbox{\hyperlink{group__Edje__General__Group_ga1c9c6594f38023c29fbfb2d0c8c675db}{edje\_init}}())
     \textcolor{keywordflow}{goto} shutdown\_ecore\_evas;

   \mbox{\hyperlink{group__Edje__Object__Animation_gac9b19ee918546740c0144904393a1acd}{edje\_frametime\_set}}(1.0 / 60.0);

   \textcolor{comment}{/* this will give you a window with an Evas canvas under the first}
\textcolor{comment}{    * engine available */}
   app.animating = \mbox{\hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{EINA\_FALSE}};
   app.x = 0;
   app.y = 0;
   app.focal = 50;

   ee = \mbox{\hyperlink{group__Ecore__Evas__Group_gac7f2cdbcb79635c34317c1183dd04cb0}{ecore\_evas\_new}}(NULL, 0, 0, WIDTH, HEIGHT, NULL);
   \textcolor{keywordflow}{if} (!ee) \textcolor{keywordflow}{goto} shutdown\_edje;

   \mbox{\hyperlink{group__Ecore__Evas__Group_ga3680b5c89157167318192157a5d24ec4}{ecore\_evas\_callback\_destroy\_set}}(ee, \_on\_destroy);
   \mbox{\hyperlink{group__Ecore__Evas__Group_gaac67f679c9027059a34519fbdea360df}{ecore\_evas\_callback\_resize\_set}}(ee, \_on\_canvas\_resize);
   \mbox{\hyperlink{group__Ecore__Evas__Group_ga3b2832e0373bbafae2bb7143618535c1}{ecore\_evas\_title\_set}}(ee, \textcolor{stringliteral}{"Edje Perspective Example"});

   \mbox{\hyperlink{group__Ecore__Evas__Group_gaa86c5abd200a02711aced53d27b9ddb2}{ecore\_evas\_data\_set}}(ee, \textcolor{stringliteral}{"app"}, &app);

   \mbox{\hyperlink{namespaceevas}{evas}} = \mbox{\hyperlink{group__Ecore__Evas__Group_ga75a7cc694b6069e78df47dab0b0f2d20}{ecore\_evas\_get}}(ee);

   app.bg = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(\mbox{\hyperlink{namespaceevas}{evas}});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(app.bg, 255, 255, 255, 255);
   evas\_object\_resize(app.bg, WIDTH, HEIGHT);
   evas\_object\_focus\_set(app.bg, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(app.bg);

   \mbox{\hyperlink{group__Evas__Object__Group__Events_ga23be30ac5cdfb780f1ff82e9108ec26b}{evas\_object\_event\_callback\_add}}(app.bg, 
      \mbox{\hyperlink{Evas__Common_8h_ad64cde0da38a60e7cb7905b3ab216968a336b86bad4f145f84c155e4922335584}{EVAS\_CALLBACK\_KEY\_DOWN}}, \_on\_bg\_key\_down, &app);

   app.edje\_obj = edje\_object\_add(\mbox{\hyperlink{namespaceevas}{evas}});

   edje\_object\_file\_set(app.edje\_obj, edje\_file, \textcolor{stringliteral}{"example/group"});
   evas\_object\_move(app.edje\_obj, 0, 0);
   evas\_object\_resize(app.edje\_obj, WIDTH, HEIGHT);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(app.edje\_obj);

   edje\_object\_signal\_callback\_add(app.edje\_obj, \textcolor{stringliteral}{"animation,end"}, \textcolor{stringliteral}{""}, \_animation\_end\_cb, &app);

   app.ps = \mbox{\hyperlink{group__Edje__Perspective_ga4ce415ab5a9f53ba55d921ab5c48a2f4}{edje\_perspective\_new}}(\mbox{\hyperlink{namespaceevas}{evas}});
   \mbox{\hyperlink{group__Edje__Perspective_gaeee5dfe8b3f428583e4f8a846f0b0d15}{edje\_perspective\_set}}(app.ps, 240, 160, 0, app.focal);
   \mbox{\hyperlink{group__Edje__Perspective_ga9e560272fb6b954a9e99eaad72a6755f}{edje\_perspective\_global\_set}}(app.ps, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

   printf(commands);

   \mbox{\hyperlink{group__Ecore__Evas__Group_ga4953047ff97d4f1b0d75a7d513d4f317}{ecore\_evas\_show}}(ee);

   \mbox{\hyperlink{group__Ecore__Main__Loop__Group_gaf103b9f668bb3e4fed12e52c6180132d}{ecore\_main\_loop\_begin}}();

   \mbox{\hyperlink{group__Ecore__Evas__Group_gad3ec61f2aa03df4d3dbfd0d311e0c8dc}{ecore\_evas\_free}}(ee);
   \mbox{\hyperlink{group__Ecore__Evas__Group_gab8fa311077f749190c9b622f672b2214}{ecore\_evas\_shutdown}}();
   \mbox{\hyperlink{group__Edje__General__Group_ga01041f6702f2d81bf10c3e41899805cb}{edje\_shutdown}}();

   \textcolor{keywordflow}{return} EXIT\_SUCCESS;

 shutdown\_edje:
   \mbox{\hyperlink{group__Edje__General__Group_ga01041f6702f2d81bf10c3e41899805cb}{edje\_shutdown}}();
 shutdown\_ecore\_evas:
   \mbox{\hyperlink{group__Ecore__Evas__Group_gab8fa311077f749190c9b622f672b2214}{ecore\_evas\_shutdown}}();

   \textcolor{keywordflow}{return} EXIT\_FAILURE;
\}
\end{DoxyCodeInclude}


The full .edc file 
\begin{DoxyCodeInclude}
collections \{
   group \{
      name: "example/group";

      min: 480 320;

      parts \{
         part \{
            name: "bg";
            type: RECT;
            mouse\_events: 1;

            description \{
               state: "default" 0.0;
            \}
         \} // bg

         part \{
            name: "rectangle";
            type: RECT;
            mouse\_events: 0;

            description \{
               state: "default" 0.0;
               color: 255 0 0 128;

               rel1 \{
                  offset: -5 -5;
                  to: "title";
               \}
               rel2 \{
                  offset: 4 4;
                  to: "title";
               \}

               map \{
                  on: 1;
                  perspective\_on: 1;
                  rotation \{
                     x: 45;
                  \}
               \}
            \}
         \} // rectangle

         part \{
            name: "title";
            type: TEXT;
            mouse\_events: 0;

            description \{
               state: "default" 0.0;
               color: 200 200 200 255;

               align: 0.0 0.5;

               rel1.relative: 0.1 0.1;
               rel2.relative: 0.1 0.1;

               text \{
                  text: "Perspective example";
                  font: "Sans";
                  size: 16;
                  min: 1 1;
               \}

               map \{
                  on: 1;
                  perspective\_on: 1;
                  rotation \{
                     x: 45;
                  \}
               \}
            \}

            description \{
               state: "right" 0.0;
               inherit: "default" 0.0;

               rel1.relative: 0.5 0.1;
               rel2.relative: 0.5 0.1;
            \}
            description \{
               state: "bottom" 0.0;
               inherit: "default" 0.0;

               rel1.relative: 0.1 0.9;
               rel2.relative: 0.1 0.9;
            \}
            description \{
               state: "bottomright" 0.0;
               inherit: "default" 0.0;

               rel1.relative: 0.5 0.9;
               rel2.relative: 0.5 0.9;
            \}
         \} // title
      \}

      programs \{
         program \{
            name: "move,right";
            signal: "move,1,0";
            action: STATE\_SET "right" 0.0;
            transition: SINUSOIDAL 1.0;
            target: "title";
            after: "animation,end";
         \}
         program \{
            name: "move,bottom";
            signal: "move,0,1";
            action: STATE\_SET "bottom" 0.0;
            transition: SINUSOIDAL 1.0;
            target: "title";
            after: "animation,end";
         \}
         program \{
            name: "move,bottomright";
            signal: "move,1,1";
            action: STATE\_SET "bottomright" 0.0;
            transition: SINUSOIDAL 1.0;
            target: "title";
            after: "animation,end";
         \}
         program \{
            name: "move,default";
            signal: "move,0,0";
            action: STATE\_SET "default" 0.0;
            transition: SINUSOIDAL 1.0;
            target: "title";
            after: "animation,end";
         \}

         program \{
            name: "animation,end";
            action: SIGNAL\_EMIT "animation,end" "";
         \}
      \}
   \}
\}
\end{DoxyCodeInclude}


To compile use this command\+: \begin{DoxyVerb}* gcc -o edje-perspective edje-perspective.c -DPACKAGE_BIN_DIR=\"/Where/enlightenment/is/installed/bin\"
* -DPACKAGE_LIB_DIR=\"/Where/enlightenment/is/installed/lib\"
* -DPACKAGE_DATA_DIR=\"/Where/enlightenment/is/installed/share\"
* `pkg-config --cflags --libs evas ecore ecore-evas edje`
*
* edje_cc perspective.edc
* \end{DoxyVerb}
 