Wiki pages event_effect_pg created: 1 main + 5 Events PG + 4 Effects PG + images + index

Signed-off-by: Clément Bénier <clement.benier@openwide.fr>
This commit is contained in:
Clément Bénier 2015-08-24 10:31:36 +02:00 committed by Cedric BAIL
parent e34bce0427
commit a322ef7106
28 changed files with 3348 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
media/event_effect_flow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -59,6 +59,7 @@ Go check the current available version of EFL on each distro/platform:
* [[program_guide/basic_application_structure_pg|Basic Application structure PG]]
* [[program_guide/containers_pg|Containers PG]]
* [[program_guide/widgets_pg|Widgets PG]]
* [[program_guide/event_effect_pg|Event and Effect PG]]
=== Samples ===

View File

@ -0,0 +1,441 @@
~~Title: Ecore Animator~~
{{page>index}}
----
===== Ecore Animator =====
Ecore provides a facility for animations called ''Ecore_Animator''. Ecore animators use the Ecore main loop for creating animations, running a specific action on each tick of a timer in the main loop.
=== Table of Contents ===
* [[#Create_an_Ecore_Animation|Create an Ecore Animation]]
* [[#Creating_an_Animation_with_a_Finite_Duration|Creating an Animation with a Finite Duration]]
* [[#Position_Mappings|Position Mappings]]
* [[#Using_Position_Mappings|Using Position Mappings]]
* [[#Creating_an_Infinite_Animation|Creating an Infinite Animation]]
* [[#Chaining_Animations|Chaining Animations]]
* [[#Pausing_and_Resuming_Animations|Pausing and Resuming Animations]]
* [[#Freeing_Up_Memory|Freeing Up Memory]]
* [[#Frametime|Frametime]]
* [[#Custom_Timer|Custom Timer]]
=== Related Info ===
* [[/tutorial/effects_tutorial|Effects Tutorial]]
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Ecore__Animator__Group.html|Ecore Animator Functions API]] ([[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/ecore_main.html|Ecore API]])
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/tutorial_ecore_animator.html|Ecore animator example]]
==== Create an Ecore Animation ====
To create an Ecore animation:
- Determine the duration of the animation.
- Define a callback function that performs the animation with that duration.
To use Ecore animators in your application, you must include the ''<Ecore.h>''
file. This file is included by default if you are already using the
''<Elementary.h>'' file in your application. You then declare an
''Ecore_Animator*'' variable and use the variable in the ''ecore_animator_*''
functions.
The following example shows how to create a simple animation with a finite
duration:
<code c>
static Eina_Bool
_do_animation(void *data, double pos)
{
evas_object_move(data, 100 * pos, 100 * pos);
// Do some more animating...
}
</code>
<code c>
ecore_animator_timeline_add(2, _do_animation, my_evas_object);
</code>
In the above example, we create a linear transition to move ''my_evas_object''
from position (0,0) to position (100,100) in 2 seconds.
==== Creating an Animation with a Finite Duration ====
Most of the time, you will want to create animations that last for a
predefined time.
The ''ecore_animator_timeline_add()'' function allows you to define an
animator that is automatically deleted after the animation is finished:
<code c>
Ecore_Animator* ecore_animator_timeline_add(double runtime,
Ecore_Timeline_Cb func,
const void *data
)
</code>
* ''runtime'' is the duration of the animation in seconds. The duration is not affected by frame rate.
* ''func'' is the callback function that performs the animation.
* ''data'' is the parameter passed to the callback function. This is usually the Evas object to animate.
<note>
The callback function can return ''ECORE_CALLBACK_RENEW'' to keep the animator
running or ''ECORE_CALLBACK_CANCEL''> to stop the animator and have it be
deleted automatically at any time. The callback function is also passed a
timeline position parameter with a value between 0.0 (start) to 1.0 (end) to
indicate where along the timeline the animator is running.
</note>
The following example performs a linear horizontal translation of 500 pixels
in 8 seconds:
<code c>
static Eina_Bool
_my_animation(void *data, double pos)
{
Evas_Object *obj = data; // Get the target object
int x, y, w, h; // Target object geometry
evas_object_geometry_get(obj, &x, &y, &w, &h); // Get current object position and size attributes
evas_object_move(obj, 500 * pos, y); // Linear translation of the Evas object
}
</code>
<code c>
ecore_animator_timeline_add(8, _my_animation, my_evas_object);
</code>
==== Position Mappings ====
The ''Ecore_Pos_Map'' position mappings are used to define the evolution of a
given position in accordance with the desired effects. The value ranges from
0.0 to 1.0 on a given timeline. This position variation allows you to apply
dynamic changes to any attribute of your Evas object, such as position, width,
height, scale, angle, and color.
Ecore supports the following position mappings (with the listed v1 and v2
parameters):
* ''ECORE_POS_MAP_LINEAR'': linear 0.0 - 1.0
* v1: not used
* v2: not used
* ''ECORE_POS_MAP_ACCELERATE'': start slow, then speed up
* v1: not used
* v2: not used
* ''ECORE_POS_MAP_DECELERATE'': start fast, then slow down
* v1: not used
* v2: not used
* ''ECORE_POS_MAP_SINUSOIDAL'': start slow, speed up, then slow down at the end
* v1: not used
* v2: not used
* ''ECORE_POS_MAP_ACCELERATE_FACTOR'': start slow, then speed up
* v1: power factor: 0.0 is linear, 1.0 is standard acceleration, 2.0 is a much more pronounced acceleration (squared), 4.0 is cubed, and so on
* v2: not used
* ''ECORE_POS_MAP_DECELERATE_FACTOR'': start fast, then slow down
* v1: power factor: 0.0 is linear, 1.0 is standard deceleration, 2.0 is a much more pronounced deceleration (squared), 3.0 is cubed, and so on
* v2: not used
* ''ECORE_POS_MAP_SINUSOIDAL_FACTOR'': start slow, speed up, then slow down at the end
* v1: power factor: 0.0 is linear, 1.0 is a standard sinusoidal, 2.1 is a much more pronounced sinusoidal (squared), 3.0 is cubed, and so on
* v2: not used
* ''ECORE_POS_MAP_DIVISOR_INTERP'': start at gradient * v1, interpolated via power of v2 curve
* v1: multiplication factor for gradient
* v2: curve value
* ''ECORE_POS_MAP_BOUNCE'': start at 0.0, then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with a decay factor of v1
* v1: bounce decay factor
* v2: number of bounces
* ''ECORE_POS_MAP_SPRING'': start at 0.0, then "wobble" like a spring until rest position at 1.0, and wobble v2 times, with a decay factor of v1
* v1: wobble decay factor
* v2: number of wobbles
{{ :event_effect_ecore_animator_position_mapping.png }}
==== Using Position Mappings ====
When using the animation callback function, the animator passes a timeline
position parameter with a value between 0.0 (start) and 1.0 (end) to indicate
where along the timeline the animator is running.
If you want to create a non-linear animation, map the position value to one of
several curves and mappings:
<code c>
double ecore_animator_pos_map(double pos,
Ecore_Pos_Map map,
double v1,
double v2
)
</code>
* ''pos'' is the current position value, which ranges from 0.0 to 1.0.
* ''map'' is the position mapping you want to apply.
* ''v1'' is the first parameter (v1) to pass to the position mapping.
* ''v2'' is the second parameter (v2) to pass to the position mapping.
<note>
The v1 and v2 arguments are specific to the chosen position mapping. For
example, if you are using ''ECORE_POS_MAP_BOUNCE'', v1 represents the
bouncing level and v2 the number of bounces.
</note>
The following example performs a transition that bounces 7 times, diminishing
by a factor of 1.8 over 5 seconds:
<code c>
static Eina_Bool
_my_animation_callback(void *data, double pos)
{
Evas_Object *obj = data; // Get the target object
int x, y, w, h; // Target object geometry
double frame = pos; // Actual position variation
frame = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7); //Get frame relative position depending on desired effect
evas_object_geometry_get(obj, &x, &y, &w, &h); // Get current object position and size attributes
evas_object_move(obj, x, 600 * frame); // Move the Evas object according to desired effect
return EINA_TRUE;
}
</code>
<code c>
ecore_animator_timeline_add(5, _my_animation_callback, my_evas_object);
</code>
==== Creating an Infinite Animation ====
If you want the animation to run for an unspecified amount of time, use the
''ecore_animator_add()'' function. This function works the same way as the
''ecore_animation_timeline_add()'' function, except its interval is based on
frame rate. Using frame rate as the basis benefits performance, especially if
you define multiple animations, since you may want to have a different timer
for each callback function.
<code c>
Ecore_Animator* ecore_animator_add(Ecore_Task_Cb func,
const void *data
)
</code>
* ''func'' is the callback function that performs the animation.
* ''data'' is the parameter passed to the callback function. This is usually the Evas object to animate.
<note>
The function returns a pointer to an ''Ecore_Animator'' object, which you can
use to adjust the animation.
</note>
The following example creates a rectangle sliding from left to right and back
again. When the rectangle hits one edge of the screen, it changes direction.
<code c>
static Eina_Bool
_slide_back_and_forth(void *data)
{
typedef enum {LEFT, RIGHT} direction_t; // Direction datatype
static int x = 0; // Initial position
static direction_t direction = RIGHT; // Initial direction
if (x >= 250)
direction = LEFT; // Change direction
else if (x <= 0)
direction = RIGHT; // Change direction
if (direction == RIGHT)
evas_object_move(data, ++x, 350); // Slide to right
else if (direction == LEFT)
evas_object_move(data, --x, 350); // Slide to left
return EINA_TRUE;
}
int
main(int argc, char *argv[])
{
// Declarations
// Ecore Evas init
// Draw Evas objects
// Animations go here
anim = ecore_animator_add(_slide_back_and_forth, rectangle);
// Ecore main loop
// Free memory
}
</code>
<note>
To use this code, you have to merge it with the Ecore transition example
above.
</note>
==== Chaining Animations ====
You may sometimes want to delay animating an object. This can be useful if,
for example, you want to start an animation only after another one has
finished.
You can simply set a delay to the second animation equal to the duration of
the first animation:
<code c>
static int runtime = 5;
static int delay = runtime;
static Eina_Bool
_start_fold_animation(void *data)
{
ecore_animator_timeline_add(runtime, _fold_animation, data);
return EINA_FALSE;
}
static Eina_Bool
_start_unfold_animation(void *data)
{
ecore_animator_timeline_add(runtime, _unfold_animation, data);
return EINA_FALSE;
}
_start_fold_animation(my_evas_object);
ecore_timer_add(delay, _start_unfold_animation, my_evas_object);
</code>
==== Pausing and Resuming Animations ====
You can pause and resume Ecore animations. To pause a running animation, use
the ''ecore_animator_freeze()'' function:
The parameter is the ''Ecore_Animator'' to pause.
<code c>
ecore_animator_freeze(Ecore_Animator *animator)
</code>
To resume the paused animation, use the ''ecore_animator_thaw()'' function:
<code c>
ecore_animation_thaw(Ecore_Animator *animator)
</code>
The parameter is the ''Ecore_Animator'' to resume.
The following example pauses a transition after 5 seconds and resumes it after
5 more seconds:
<code c>
static Eina_Bool
_freeze_animation(void *data)
{
ecore_animator_freeze(data);
return EINA_FALSE;
}
static Eina_Bool
_thaw_animation(void *data)
{
ecore_animator_thaw(data);
return EINA_FALSE;
}
ecore_timer_add(5, _freeze_animation, animator);
ecore_timer_add(10, _thaw_animation, animator);
</code>
==== Freeing Up Memory ====
When you create an animation that does not have a timeout, you will have to
manually free up the memory allocated to the ''Ecore_Animator'' object. By
comparison, if the animation has a timeout, Ecore implements the mechanisms to
automatically delete the animator from the list of pointers: When your
animation callback returns 0 or ''ECORE_CALLBACK_CANCEL'', the animator
manager takes care of freeing up the allocated memory.
To manually free up the memory, delete the pointer by using the
''ecore_animator_del()'' function:
<code c>
ecore_animator_del(Ecore_Animator *animator)
</code>
The argument is the ''Ecore_Animator'' whose memory allocation to free up.
Regardless of the type of animation, it is good practice to always ensure that
the allocated memory is freed up before the program exits:
<code c>
if (animator != NULL)
ecore_animator_del(animator);
</code>
==== Frametime ====
In most cases, you will want to use the default timer
''ECORE_ANIMATOR_SOURCE_TIMER''. This timer ticks every "frametime" seconds
and allows you to perform transitions within a predefined timeline. The timer
uses the system clock to tick over every Nth second, with the default being
1/30th of a second.
To tweak performance, you can change the frametime value:
The argument is the new frametime value.
<code c>
ecore_animator_frametime_set(double frametime)
</code>
<note>
Too small a value can cause performance issues, whereas too high a value can
cause your animation to seem jerky.
</note>
If you want to get the current frametime value, use the
''ecore_animator_frametime_get()'' function.
==== Custom Timer ====
You may want to specify a custom timer to match your animation to third-party
events. For example, the filling speed of a progress bar will mainly depend on
the time it takes for a task to complete and the velocity at which the
remaining time estimation evolves. This kind of animation requires you to use
a custom timer.
To use a custom timer, first set ''ECORE_ANIMATOR_SOURCE_CUSTOM'' as the timer
source, and then drive the timer based on an input tick source (such as
another application via IPC or a vertical blanking interrupt):
<code c>
void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func,
const void *data
)
</code>
* ''func'' is the callback function to call on the tick start.
* ''data'' is the data to pass to the callback function.
<code c>
void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func,
const void *data
)
</code>
* ''func'' is the callback function to call on the tick end.
* ''data'' is the data to pass to the callback function to set the functions that will be called to start and stop the ticking source.
Next, trigger a tick over one frame:
<code c>
ecore_animator_custom_tick(void)
</code>
The following example supposes a progress bar that will be refreshed every
time some progress occurs:
<code c>
ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
void _on_progress_update()
{
// Called when some progress occurs
ecore_animator_custom_tick(); // Tick (next frame in progress bar animation)
}
</code>
Finally, to get the current animator source, use the ''ecore_animator_source_get()'' function.
\\
------------
{{page>index}}

View File

@ -0,0 +1,303 @@
~~Title: Ecore Events~~
{{page>index}}
----
===== Ecore Events =====
Ecore events are used for low-level handling of events such as key presses,
network connections, and communication with sub-processes.
The low-level handling of key presses is particularly useful for shortcuts:
instead of adding a signal handler to a specific graphical element, you can
add one globally. This guarantees that no matter which widget is currently
receiving events, the shortcut is caught.
Note that ecore events are also used to implement new graphical back-ends, but
they are low-level and not useful for most applications.
=== Table of Contents ===
* [[#Ecore_Events_Useful_for_Shortcuts|Ecore Events Useful for Shortcuts]]
* [[#Add_an_Event_Handler:_ecore_event_handler_add()|Add an Event Handler: ecore_event_handler_add()]]
* [[#Remove_an_Event_Handler:_ecore_event_handler_del()|Remove an Event Handler: ecore_event_handler_del()]]
* [[#Send_Events_to_the_Main_Loop_Yourself:_ecore_event_add()|Send Events to the Main Loop Yourself: ecore_event_add()]]
* [[#Create_Your_Own_Type_of_Events:_ecore_event_type_new()|Create Your Own Type of Events: ecore_event_type_new()]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Ecore__Event__Group.html|Ecore Event functions API]]
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/ecore_event_example_01_c.html|Ecore Event Example]]
==== Ecore Events Useful for Shortcuts ====
There are eight ecore events for shortcuts:
<code c>
int ECORE_EVENT_KEY_DOWN;
int ECORE_EVENT_KEY_UP;
int ECORE_EVENT_MOUSE_BUTTON_DOWN;
int ECORE_EVENT_MOUSE_BUTTON_UP;
int ECORE_EVENT_MOUSE_MOVE;
int ECORE_EVENT_MOUSE_WHEEL;
int ECORE_EVENT_MOUSE_IN;
int ECORE_EVENT_MOUSE_OUT;
</code>
The callbacks receive additional data through a ''void *'' object, whose type
depends on the event that has been received.
* for ''ECORE_EVENT_KEY_DOWN'' and ''ECORE_EVENT_KEY_UP'':
<code c>
typedef struct _Ecore_Event_Key Ecore_Event_Key;
struct _Ecore_Event_Key
{
const char *keyname;
const char *key;
const char *string;
const char *compose;
Ecore_Window window;
Ecore_Window root_window;
Ecore_Window event_window;
unsigned int timestamp;
unsigned int modifiers;
int same_screen;
};
</code>
* for ''ECORE_EVENT_MOUSE_BUTTON_DOWN'' and ''ECORE_EVENT_MOUSE_BUTTON_UP'':
<code c>
typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button;
struct _Ecore_Event_Mouse_Button
{
Ecore_Window window;
Ecore_Window root_window;
Ecore_Window event_window;
unsigned int timestamp;
unsigned int modifiers;
unsigned int buttons;
unsigned int double_click;
unsigned int triple_click;
int same_screen;
int x;
int y;
struct
{
int x;
int y;
} root;
struct
{
int device; // 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers)
double radius, radius_x, radius_y; // Radius of press point - radius_x and y if its an ellipse (radius is the average of the 2)
double pressure; // Pressure - 1.0 == normal, > 1.0 == more, 0.0 == none
double angle; // Angle relative to perpendicular (0.0 == perpendicular), in degrees
double x, y; // Same as x, y root.x, root.y, but with sub-pixel precision, if available
struct
{
double x;
double y;
} root;
} multi;
};
</code>
* for ''ECORE_EVENT_MOUSE_MOVE'' and ''ECORE_EVENT_MOUSE_WHEEL'':
<code c>
typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel;
struct _Ecore_Event_Mouse_Wheel
{
Ecore_Window window;
Ecore_Window root_window;
Ecore_Window event_window;
unsigned int timestamp;
unsigned int modifiers;
int same_screen;
int direction;
int z;
int x;
int y;
struct
{
int x;
int y;
} root;
};
</code>
* for ''ECORE_EVENT_MOUSE_IN ''and ''ECORE_EVENT_MOUSE_OUT'':
<code c>
typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move;
struct _Ecore_Event_Mouse_Move
{
Ecore_Window window;
Ecore_Window root_window;
Ecore_Window event_window;
unsigned int timestamp;
unsigned int modifiers;
int same_screen;
int x;
int y;
struct
{
int x;
int y;
} root;
struct
{
int device; // 0 if normal mouse, 1+ for other mouse-devices (eg multi-touch - other fingers)
double radius, radius_x, radius_y; // radius of press point - radius_x and y if it is an ellipse (radius is the average of the two)
double pressure; // pressure - 1.0 == normal, > 1.0 == more, 0.0 == none
double angle; // angle relative to perpendicular (0.0 == perpendicular), in degrees
double x, y; // same as x, y root.x, root.y, but with sub-pixel precision, if available
struct
{
double x, y;
} root;
} multi;
};
</code>
==== Add an Event Handler: ecore_event_handler_add() ====
The ''ecore_event_handler_add()'' function enables registering a callback for
the given event. Its prototype is:
<code c>
Ecore_Event_Handler* ecore_event_handler_add(int type,
Ecore_Event_Handler_Cb func,
const void* data
)
</code>
* ''type'' is an identifier for the event; for example, if you wish to receive notifications when keys are pressed, give ''ECORE_EVENT_KEY_DOWN''.
* ''func'' is the callback that is called when the event takes place.
* ''data'' is a pointer to additional data that is given as the argument to the callback; it is optional and ''NULL'' is an acceptable value.
* return value is a pointer to the event handler, which can be used later to uninstall the handler.
The type of the callback function is defined as follows.
<code c>
Eina_Bool (* Ecore_Event_Handler_Cb) (void *data, int type, void *event)
</code>
The callback function declaration is similar to:
<code c>
Eina_Bool some_ecore_event_cb(void *data, int type, void *event);
</code>
* ''data'' is the same as the ''data'' which was given as a parameter to ''ecore_event_handler_add()''.
* ''type'' is the same as the type which was given as a parameter to ''ecore_event_handler_add()''.
* ''event'' is an object whose actual type depends on the value of the ''type'' parameter and is one of ''Ecore_Event_Key'', ''Ecore_Event_Mouse_Button'', ''Ecore_Event_Mouse_Wheel'', ''Ecore_Event_Mouse_Move''.
* The return value is either ''ECORE_CALLBACK_PASS_ON'', to allow other callbacks for that event be called, or ''ECORE_CALLBACK_DONE'' to not call them.
The code below is a short example of how to set a global variable to
''EINA_TRUE'' when the Control key is pressed.
<code c>
Eina_Bool ctrl_pressed = EINA_FALSE;
static Eina_Bool
_key_down_cb(void *data __UNUSED__, int type __UNUSED__, void *ev)
{
// The callback is used with the ECORE_EVENT_KEY_DOWN signal: the
// parameter "void *ev" is therefore of the actual type Ecore_Event_Key
// The following renders its fields accessible
Ecore_Event_Key *event = ev;
// Test whether the key that is pressed is Ctrl.
if (!strcmp("Control_L", event-&gt;key))
{
// If it is, store that piece of information
ctrl_pressed = EINA_TRUE;
}
// Let the event continue to other callbacks which have not been called yet
return ECORE_CALLBACK_PASS_ON;
}
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down_cb, NULL);
</code>
==== Remove an Event Handler: ecore_event_handler_del() ====
To remove an event handler, use the ''ecore_event_handler_del()'' function.
The prototype is:
<code c>
void* ecore_event_handler_del(Ecore_Event_Handler *event_handler)
</code>
* event_handler is the value returned by ''ecore_event_handler_add()''.
* The return value is the data pointer that was used in the corresponding ''call to ecore_event_handler_add()''.
==== Send Events to the Main Loop Yourself: ecore_event_add() ====
You can send events to the main-loop, which helps to handle actions of various
origins through the same codepath. Note that this is a thread-safe operation.
To send an event, use the ''ecore_event_add()'' function. The prototype is
<code c>
Ecore_Event* ecore_event_add(int type,
void* ev,
Ecore_End_Cb func_free,
void* func_free_data
)
</code>
* ''type'' is the event type. For example, ECORE_EVENT_KEY_DOWN.
* ''ev'' is the event data. It is given as a parameter to the callback.
* ''func_free'' is a function to free ev after the callback is called. It is optional: ''NULL'' is an acceptable value.
* ''func_free_data'' is a pointer to additional data that is given as an argument to the ''func_free'' callback. It is optional: ''NULL'' is an acceptable value.
The type of the ''func_free'' function is defined as follows.
<code c>
void (* Ecore_End_Cb)(void *user_data, void *func_free_data)
</code>
The callback function declaration is thus similar to
<code c>
void some_func_free(void *user_data, void *func_free_data);
</code>
==== Create Your Own Type of Events: ecore_event_type_new() ====
You can create your own events. It also helps to use a single codepath.
The function for creating your own events is ''ecore_event_type_new()''. The
prototype is:
<code c>
int ecore_event_type_new(void);
</code>
It generates a new unique identifier, which you can use as ''type'' in the
functions described above.
\\
-----
{{page>index}}

View File

@ -0,0 +1,463 @@
~~Title: Edje Animation~~
{{page>index}}
----
===== Edje Animation =====
The Edje animations are based on a very simple principle: going from one state to another. If you want to animate something with Edje, you must define two states and move from the first state to the second.
=== Table of Contents ===
* [[#Animating_a_Rectangle|Animating a Rectangle]]
* [[#Actions|Actions]]
* [[#Transitions|Transitions]]
* [[#Chaining_Edje_Programs|Chaining Edje Programs]]
* [[#Playing_on_Signals|Playing on Signals]]
* [[#Rotate_with_Edje|Rotate with Edje]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/edcref.html|Edje Data Collection Reference]]
==== Animating a Rectangle ====
This example shows how to animate a rectangle. It is positioned in the top left corner of the window and is moved to the bottom right corner in five seconds. To do that with Edje, define a ''part'' called "rectangle" with the ''type RECT:'' this part has two descriptions (or states). In the first state, the rectangle is in is the top left corner. In the second state, it is in is the bottom right corner. To create the transition, set this EDC code for Edje to switch the object from its current state to another.
<code c>
collections
{
group
{
name: "main";
parts
{
part
{
name: "rectangle";
type: RECT;
description
{
state: "default" 0.0;
align: 0.0 0.0;
rel1 {relative: 0.0 0.0;}
rel2 {relative: 0.3 0.1;}
color: 0 0 255 255;
}
description
{
state: "default" 0.5;
align: 0.0 0.0;
rel1 {relative: 0.7 0.9;}
rel2 {relative: 1.0 1.0;}
color: 0 0 255 255;
}
}
}
programs
{
program
{
name: "animation,state1";
source: "";
signal: "load";
action: STATE_SET "default" 0.5;
target: "rectangle";
transition: LINEAR 5;
}
}
}
}
</code>
The "rectangle" part has two descriptions that share the same name, but have a different "version".
<code c>
part
{
name: "rectangle";
type: RECT;
description
{
state: "default" 0.0;
}
description
{
state: "default" 0.5;
}
}
</code>
The program defines when and how to move from one state to another. A program is called upon reception of a signal from a source. Here the program is called when the signal load is received from any source.
<code c>
program
{
name: "animation,state1";
source: "";
signal: "load";
}
</code>
An action is performed upon the signal reception. In this example, the state is changed.
<code c>
action: STATE_SET "default" 0.5;
</code>
The program has a target, here the "rectangle".
<code c>
target: "rectangle";
</code>
The program uses a transition to perform the action.
<code c>
transition: LINEAR 5;
</code>
This example produces a blue rectangle that moves from the upper left to the lower right corner with a linear transition in five seconds.
==== Actions ====
The Edje programs are not only for animations. There are different actions, for example ''STATE_SET'' and ''ACTION_STOP''. You may also send signals with ''SIGNAL_EMIT''.
The ''STATE_SET'' action changes the state of the "target".
In the following example, the state of the part named "image" changes to "default" "0.0".
<code c>
program
{
name: "animate";
signal: "animate";
action: STATE_SET "default" 0.0;
transition: LINEAR 3.0;
target: "image";
}
</code>
The ''ACTION_STOP'' stops the program specified by "target".
<code c>
program
{
name: "animate_stop";
signal: "animate_stop";
action: ACTION_STOP;
target: "animate_loop";
}
</code>
The previous example stops the program defined as "target" named ''animate_loop''. This program runs on the ''animate_stop'' signal.
The ''SIGNAL_EMIT'' emits a signal that is used to communicate with the application directly from the theme.
The following example emits a signal ''frame_move'' "start" when it receives the signal ''mouse,down,*'' from the ''video_over'' part. In other words, it sends the signal ''frame_move'' "start" when the mouse is pressed in the ''video_over'' part.
<code c>
program
{
name: "video_move_start";
signal: "mouse,down,*";
source: "video_mover";
action: SIGNAL_EMIT "frame_move" "start";
}
</code>
==== Transitions ====
The transitions available are:
* ''LIN'' or ''LINEAR'': makes a linear transition and takes the duration in seconds as the parameter
* ''SIN'' or ''SINUSOIDAL'': makes a sinusoidal transition and takes the duration in seconds as the parameter
* ''ACCEL'' or ''ACCELERATE'': makes an accelerated transition and takes the duration in seconds as the parameter
* ''DECEL'' or ''DECELERATE'': makes a decelerated transition and takes the duration in seconds as the parameter
* ''ACCEL_FAC'' or ''ACCELERATE_FACTOR'': makes an accelerated transition and takes the duration and the factor as the parameters
* ''DECEL_FAC'' or ''DECELERATE_FACTOR'': makes a decelerated transition and takes the duration and the factor as the parameters
* ''SIN_FAC'' or ''SINUSOIDAL_FACTOR'': makes a sinusoidal transition and takes the duration and the factor as the parameters
* <li>the duration
* the initial gradient start (0.0 is horizontal, 1.0 is diagonal (linear), 2.0 is twice the gradient of linear, and so on)
* an integer factor that defines how much the value swings outside the gradient to come back to the final resting spot at the end. 0.0 for the third parameter is equivalent to linear interpolation. Note that DIVIS may exceed 1.0.
* the duration
* how much the bounce decays, with 0.0 giving linear decay per bounce, and higher values giving more decay
* the number of bounces (rounded down to the nearest integer value)
* the duration
* the decay, with the level exceeding 1.0 on the outer swings
* the number of spring swings
There are graphical representations of these effects in the ''Ecore_Evas'' section above.
==== Chaining Edje Programs ====
To define a couple of Edje programs and chain them, we can, for example, create a program to make the rectangle return to its initial state with another transition (such as ''BOUNCE'').
Use the statement ''after'' in the first ''program''. ''after'' takes the name of the transition to run when the program is done.
<code c>
after: "animation,state0";
</code>
This is how to add the bounce animation. To return the blue rectangle to its initial position with a ''BOUNCE'' transition: it bounces with a factor of 1.8, six times. This program is only to be used at the end of the first one, so it does not have any signal statement.
<code c>
program
{
name: "animation,state0";
source: "";
signal: "";
action: STATE_SET "default" 0.0;
target: "rectangle";
transition: BOUNCE 5 1.8 6;
}
</code>
==== Playing on Signals ====
The programs start when they receive a signal from a source. Edje handles many kind of signals, including mouse events.
<note>
<strong>Note: </strong>To show the signals, use <code>edje_player -p myfile.edj</code>.
</note>
For example, in another transition the rectangle is left clicked. The corresponding signal name is ''mouse,clicked,1''.
For this transition, define a new state. This state changes the color and the position of the rectangle.
<code c>
// To be place in the "part" definition
description
{
state: "color" 0.0;
rel1 {relative: 0.3 0.3;}
rel2 {relative: 0.7 0.4;}
color: 255 0 0 255;
}
</code>
The program is as follows:
<code c>
program
{
name: "animation,color";
source: "rectangle";
signal: "mouse,clicked,1";
action: STATE_SET "color" 0.0;
target: "rectangle";
transition: SIN 2;
}
</code>
This starts when the rectangle is left clicked.
If you want to send a signal from your application when you use signals to start transitions, create a program waiting for your own special signal. For example:
<code c>
program
{
name: "animation,menu_side,hide";
source: "MenuButton";
signal: "hide,sidemenu";
action: STATE_SET "default" 1.0;
target: "menu/side";
transition: LINEAR 0.2;
}
</code>
This program changes the state of the target named ''animation,menu_side,hide'' to ''"default" 1.0''. It waits for the ''hide,sidemenu'' signal emitted by a source called ''MenuButton''.
<code c>
edje_object_signal_emit(layout, "hide,sidemenu", "MenuButton");
</code>
This statement sends a signal named ''hide,sidemenu'' with a source named ''MenuButton'' to the object called ''layout''.
The ''edje_object_signal_emit'' function emits a signal on an ''Evas_Object'' part of the application.
<code c>
edje_object_signal_emit(Evas_Object *obj,
const char *emission,
const char *source)
</code>
If you use the Elementary in the application, you can use ''elm_object_signal_emit''. It functions exactly the same way as ''edje_object_signal_emit'' and takes the same parameters.
<note>
<strong>Note: </strong>To find a complete example, use <code>elm_object_signal_emit</code> in the <a href="/documentation/tutorials/native-application/ui/ui-control/menu-0">Menu Tutorial</a>.
</note>
==== Rotate with Edje ====
The Edje library allows you to rotate objects, using the ''map'' statement. For example, if you want to rotate the blue rectangle on a right click, you must define a new rotate state. To enable the ''map'' on you object you must add a ''map'' part to your default state.
<code c>
map
{
on: 1;
smooth: 1;
perspective_on: 1;
rotation.x: 0;
rotation.y: 0;
rotation.z: 0;
}
</code>
To add a new rotate state with a rotation around any axis, do the following.
<code c>
description
{
state: "rotate" 0.0;
inherit: "default" 0.0;
map.rotation.z: 120;
}
</code>
This rotate state inherits all the default state properties, but changes the value of ''map.rotation.z'' from 0° to 120°.
To set a program to run the rotate state, do the following.
<code c>
program
{
name: "animation,rotate";
source: "rectangle";
signal: "mouse,clicked,3";
action: STATE_SET "rotate" 0.0;
target: "rectangle";
transition: LIN 5;
}
</code>
This program runs on a right click on the rectangle object.
The complete code of this example is as follows.
<code c>
collections
{
group
{
name: "main";
parts
{
part
{
name: "rectangle";
type: RECT;
description
{
state: "default" 0.0;
align: 0.0 0.0;
rel1 {relative: 0.0 0.0;}
rel2 {relative: 0.3 0.1;}
map
{
on: 1;
smooth: 1;
perspective_on: 1;
rotation
{
z: 0;
x: 0;
y: 0;
}
}
color: 0 0 255 255;
}
description
{
state: "default" 0.5;
align: 0.0 0.0;
rel1 {relative: 0.7 0.9;}
rel2 {relative: 1.0 1.0;}
color: 0 0 255 255;
}
description
{
state: "color" 0.0;
rel1 {relative: 0.3 0.3;}
rel2 {relative: 0.7 0.4;}
color: 255 0 0 255;
}
description
{
state: "rotate" 0.0;
inherit: "default" 0.0;
map.rotation.z: 120;
}
}
}
programs
{
program
{
name: "animation,state1";
source: "";
signal: "load";
action: STATE_SET "default" 0.5;
target: "rectangle";
transition: LINEAR 1;
after: "animation,state0";
}
program
{
name: "animation,state0";
source: "";
signal: "";
action: STATE_SET "default" 0.0;
target: "rectangle";
transition: BOUNCE 2 1.8 26;
}
program
{
name: "animation,color";
source: "rectangle";
signal: "mouse,clicked,1";
action: STATE_SET "color" 0.0;
target: "rectangle";
transition: SIN 2;
}
program
{
name: "animation,rotate";
source: "rectangle";
signal: "mouse,clicked,3";
action: STATE_SET "rotate" 0.0;
target: "rectangle";
transition: LIN 5;
}
}
}
}
</code>
\\
------
{{page>index}}

View File

@ -0,0 +1,121 @@
~~Title: Edje Events~~
{{page>index}}
----
===== Edje Events =====
Edje themes have ''program'' sections. These are small sections triggered upon
the reception of a signal that can execute actions, such as changing the state
of an edje part and running another program.
For more information on themes and programs, see the [[/coming_soon|Edje
guide]].
=== Table of Contents ===
* [[#Basic_Usage,_for_a_Single_Part|Basic Usage, for a Single Part]]
* [[#Usual_Usage_for_Parts_Aggregated_in_Groups:_with_Layouts|Usual Usage for Parts Aggregated in Groups: with Layouts]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/edcref.html|Edje Data Collection Reference]]
==== Basic Usage for a Single Part ====
An example ''program'' is shown below:
<code c>
program
{
name: "change_color";
signal: "mouse,clicked,*";
source: "*";
action: SIGNAL_EMIT "got.a.click" "color_changer";
}
</code>
This is a program named "change_color", which triggers on mouse clicks on the
current part and emits a signal "got.a.click". The source is set to
"color_changer".
To catch this signal from the C side, you need to use either
''edje_object_signal_callback_add()'' or ''elm_object_signal_callback_add()''.
The only difference between the two is that the previous one operates on an
edje object and the latter one on an elementary object. Unless you do not use
Elementary at all, use the Elementary variant.
The prototypes of these two functions are shown below.
<code c>
void edje_object_signal_callback_add(Edje_Object *obj,
const char *emission,
const char *source,
Edje_Signal_Cb func,
void *data
)
</code>
<code c>
void elm_object_signal_callback_add(Evas_Object *obj,
const char *emission,
const char *source,
Edje_Signal_Cb func,
void *data
)
</code>
* ''obj'' the object which emits the signal that you react on.
* ''emission'' is the signal name ("*" acts as a wildcard).
* ''source'' is the signal source (the second parameter to ''SIGNAL_EMIT'' above). ("*" acts as a wildcard.)
* ''func'' is the callback when ''emission'' and ''source'' match.
* ''data'' is a pointer to additional data to pass that is given as the argument to the callback. It is optional and NULL is an acceptable value.
The type of the callback function is defined as follows.
<code c>
void (*Edje_Signal_Cb) (void *data, Evas_Object *obj, const char *emission, const char *source);
</code>
The callback function definition is similar to
<code c>
void func(void *data, Evas_Object *obj, const char *emission, const char *source);
</code>
* ''data'' is the same as the data which was given as parameter to either ''edje_object_signal_callback_add()'' or ''elm_object_signal_callback_add()''.
* ''obj'' is the object which emits the signal.
* ''emission'' is the signal name.
* ''source'' is the signal source.
==== Usual Usage for Parts Aggregated in Groups: with Layouts ====
Most of the time, edje and elementary are used together. In particular, you
can define a group in Edje and use it as a layout in Elementary. This enables
doing the theming and object placement in Edje while benefiting from the
higher-level functions of Elementary. This is achieved through ''layouts'',
which contain several parts and are explained in the
[[/program_guide/containers/layout|Layout Container guide]].
Since there are several parts in a layout, it is not possible to use
''elm_object_signal_callback_add()'' and
''edje_object_signal_callback_add()'', as they require a single emitter
object. The solution is to use the dedicated function
''elm_layout_signal_callback_add()''. Its prototype is shown below.
<code c>
void elm_layout_signal_callback_add(Evas_Object *obj,
const char *emission,
const char *source,
Edje_Signal_Cb func,
void *data
)
</code>
''elm_layout_signal_callback_add()'' works very similarly to the functions
described in the previous section. The only difference is the type of the
object in the first parameter. For ''elm_layout_signal_callback_add()'' it is
a pointer to an Evas_Object, which is obtained through ''elm_layout_add()'' as
described in the [[/program_guide/containers/layout|Layout Container guide]].
\\
------
{{page>index}}

View File

@ -0,0 +1,999 @@
~~Title: Elementary Animations~~
{{page>index}}
----
===== Elementary Animations =====
Elementary transitions (''Elm_Transit'') allow you to apply various transition
effects, such as translation and rotation, to Evas objects. Elementary
transitions are mostly based on Ecore animators, but provide some transition
methods at a higher level of abstraction. Elementary transitions provide a
simpler way of animating objects than Ecore animators or Edje animations.
To use Elementary transitions, you must create an ''Elm_Transit'' object and
define the desired transitions using the methods of this object. After the
transitions are registered, they will be automatically managed: their callback
functions will be called for the set duration, and they will be deleted upon
completion.
Use Elementary transitions only when Edje animations are not sufficient. Edje
animations are better at handling transitions, have more flexibility, and can
be manipulated inside themes. The only drawback is that Edje animations have
their own definition language. If you want to code with the C language, use
Elementary transitions.
=== Table of Contents ===
* [[#Getting_Started|Getting Started]]
* [[#Adding_Objects_to_an_Animation|Adding Objects to an Animation]]
* [[#Animation_Duration|Animation Duration]]
* [[#Animation_Acceleration_Mode_("Tween_Mode")|Animation Acceleration Mode ("Tween Mode")]]
* [[#Animation_Repeat|Animation Repeat]]
* [[#Animation_Auto-reverse|Animation Auto-reverse]]
* [[#Transitions|Transitions]]
* [[#Built-in_Transitions|Built-in Transitions]]
* [[#Translation|Translation]]
* [[#Color_Transition|Color Transition]]
* [[#Rotation|Rotation]]
* [[#Wipe_Effect|Wipe Effect]]
* [[#Zoom_Effect|Zoom Effect]]
* [[#Resizing_Effect|Resizing Effect]]
* [[#Flip_Effect|Flip Effect]]
* [[#Resizable_Flip_Effect|Resizable Flip Effect]]
* [[#Fade_Effect|Fade Effect]]
* [[#Blend_Effect|Blend Effect]]
* [[#Combining_Transitions|Combining Transitions]]
* [[#Animation_Chain|Animation Chain]]
* [[#Animation_Timeline|Animation Timeline]]
* [[#Custom_Transition|Custom Transition]]
=== Related Info ===
* [[/tutorial/effects_tutorial|Effects Tutorial]]
* [[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Transit.html|Elementary Transit API]]
^ Elm Transit Examples ^^^^
|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_01_explained.html|Basic Transit Usage]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_02_explained.html|Chained Transitions]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_03_explained.html|Combined effects and options]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_04_c.html|Combined effects over two objects]]|
==== Getting Started ====
The first thing you need to do when creating an transition with
''Elm_Transit'' is to build your transit object using the
''elm_transit_add()'' function:
<code c>
Elm_Transit *transit = elm_transit_add();
</code>
You now have an ''Elm_Transit'' instance that will allow you to perform
transitions on one or more objects. The transit object holds the information
about the target objects and the transition effects that will be used. The
transit object also contains information about animation duration, number of
repetitions, auto-reverse, and so on. The transit object starts playing as
soon as the application enters the main loop.
==== Adding Objects to an Animation ====
You can add your Evas objects to your transition using the
''elm_transit_object_add()'' function:
<code c>
void elm_transit_object_add (Elm_Transit* transit,
Evas_Object* obj
)
</code>
* ''transit'' handles the transition.
* ''obj'' is the Evas object to animate.
<note>
The Evas object can be a low-level component, such as a rectangle, but also a
widget, such as a button, image, or calendar.
If you want to animate an Evas object handled by a container, such as a box,
you need to either unpack the object before the animation or animate the whole
container.
</note>
If you want to know which objects are currently in your transition, use the
''elm_transit_objects_get()'' function. You will get a list of all the objects
that are subject to the transition.
At any time, you can remove objects from the transition:
<code c>
void elm_transit_object_remove(Elm_Transit *transit,
Evas_Object *obj
)
</code>
* ''transit'' handles the transition.
* ''obj'' is the Evas object to remove from the transition.
<note>
After you have added at least one Evas object to your transition, if the list
of objects gets emptied somehow, be it because the transition has been
terminated or all objects have been deleted, the transition will be
automatically deleted. Otherwise, you will have to delete the transition by
yourself using the ''elm_transit_del()'' function. If you delete the
transit while the transition is running, the transition will stop.
</note>
=== Adding Images to an Animation ===
If you do not want to manage widgets for animating images, ''Elm_Transit''
provides a helper function for directly manipulating images:
<code c>
Elm_Transit* elm_transit_effect_image_animation_add(Elm_Transit *transit,
Eina_List *images
)
</code>
* ''transit'' handles the transition.
* ''images'' is a list of the image paths.
<note>
This list and its contents will be deleted after the effect ends by the
''elm_transit_effect_image_animation_context_free()'' function.
</note>
You can now define your image transitions exactly the same way as with any
Evas object.
The following example shows how to use ''Elm_Transit'' with images:
<code c>
char buf[PATH_MAX];
Eina_List *images = NULL;
Elm_Transit *transit = elm_transit_add();
snprintf(buf, sizeof(buf), "%s/images/btn_default.png", PACKAGE_DATA_DIR);
images = eina_list_append(images, eina_stringshare_add(buf));
snprintf(buf, sizeof(buf), "%s/images/btn_hover.png", PACKAGE_DATA_DIR);
images = eina_list_append(images, eina_stringshare_add(buf));
elm_transit_effect_image_animation_add(transit, images);
</code>
==== Animation Duration ====
With ''Elm_Transit'', setting the transition duration is mandatory. To set the
duration, use the ''elm_transit_duration_set()'' function:
<code c>
void elm_transit_duration_set(Elm_Transit *transit,
double duration
)
</code>
* ''transit'' handles the transition.
* ''duration'' is the duration in seconds.
<note>
The purpose of ''Elm_Transit'' is to abstract the low-level details
of object interpolation, so you cannot create an infinite transition by
specifying the duration. However, you can make your transition last forever
using the repeat function.
</note>
The following example shows how to make a complete revolution of the target
Evas object in 2 seconds:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);
</code>
To get the duration of the transition, use the ''elm_transit_duration_get()''
function.
==== Animation Acceleration Mode ("Tween Mode") ====
''Elm_Transit'' supports a number of built-in interpolation methods. By
default, all interpolations are linear. If you want to change the animation's
dynamics, use the ''elm_transit_tween_mode_set()'' function:
<code c>
void elm_transit_tween_mode_set(Elm_Transit * transit,
Elm_Transit_Tween_Mode tween_mode
)
</code>
* ''transit'' handles the transition.
* ''tween_mode'' is the tween mode of the transition.
''tween_mode'' can be one of the following:
* ''ELM_TRANSIT_TWEEN_MODE_LINEAR'' Constant speed.
* ''ELM_TRANSIT_TWEEN_MODE_SINUSOIDAL'' Starts slow, increase speed over time, then decrease again and stop slowly, v1 being a power factor.
* ''ELM_TRANSIT_TWEEN_MODE_DECELERATE'' Starts fast and decrease speed over time, v1 being a power factor.
* ''ELM_TRANSIT_TWEEN_MODE_ACCELERATE'' Starts slow and increase speed over time, v1 being a power factor.
* ''ELM_TRANSIT_TWEEN_MODE_DIVISOR_INTERP'' Start at gradient v1, interpolated via power of v2 curve.
* ''ELM_TRANSIT_TWEEN_MODE_BOUNCE'' Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1.
* ''ELM_TRANSIT_TWEEN_MODE_SPRING'' Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1.
* ''ELM_TRANSIT_TWEEN_MODE_BEZIER_CURVE'' Since 1.13: Follow the cubic-bezier curve calculated with the control points (x1, y1), (x2, y2)
To get the current tween mode, use the ''elm_transit_tween_mode_get()''
function.
==== Animation Repeat ====
To set a transition to repeat, use the ''elm_transit_repeat_times_set()''
function:
<code c>
void elm_transit_repeat_times_set(Elm_Transit * transit,
int repeat
)
</code>
* ''transit'' is the transition you want to repeat.
* ''repeat'' is the number of times the transition repeats.
<note>
If the ''repeat'' argument is set to 0, the transition will not loop at all.
If set to 1, the transition will run twice. If set to a negative value, the
transition will repeat forever.
</note>
To get the repeat value, use the ''elm_transit_repeat_times_get()'' function.
The default value is 0.
The following example shows how to make an Evas object spin for 3 complete
revolutions in 6 seconds:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_repeat_set(transit, 3.0);
elm_transit_go(transit);
</code>
==== Animation Auto-reverse ====
''Elm_Transit'' provides a helper function for automatically reversing the
transition once it finishes:
<code c>
void elm_transit_auto_reverse_set(Elm_Transit * transit,
Eina_Bool reverse
)
</code>
* ''transit'' is the transition you want to reverse.
* ''reverse'' is the reverse state. If the reverse state is set to ''EINA_TRUE'', this function will perform the same transition backwards as soon as the first transition is complete.
<note>
Reversing the transition doubles the duration of the transition. Moreover, if
the transition is set to repeat, the transition will run back and forth until
the repeat count is finished.
You can calculate the duration as follows if
both auto-reverse and repeat are set: 2 * duration * repeat.
</note>
The following example shows how to make an object perform half a turn and then
reverse the animation to its original position in 4 seconds:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_auto_reverse_set(transit, EINA_TRUE);
elm_transit_go(transit);
</code>
To determine whether the auto-reverse mode is enabled, use the
''elm_transit_auto_reverse_get()'' function.
==== Transitions ====
We distinguish two main transition types:
* Transitions that are applied to the properties of objects, such as position, size, angle, and color.
* Transitions from one object to another, where the first object is hidden to let the second one appear.
All transitions are based on the same principle: we set the starting and the
ending values for the properties we want to animate, we then set the lifespan
of the animation, and finally we inquire the preferred interpolation method
(such as linear, acceleration, or bounce).
You must declare the transitions after the parent window has been created,
since the transition effects make use of the geometric properties of the
parent window. If the parent window does not yet exist when calculating the
interpolation, the interpolation may end up being based on wrong information.
==== Built-in Transitions ====
''Elm_Transit'' provides several built-in transition definitions that are
useful for the most common cases, so you that will not have to code them from
scratch.
All these built-in effects are implemented as follows:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_effect_add(transit,
elm_transit_effect_translation_op,
elm_transit_effect_translation_context_new(),
elm_transit_effect_translation_context_free);</code>
* ''transit'': The ''Elm_Transit'' object that contains the target Evas objects and all the information needed to setup the transition.
* ''elm_transit_effect_translation_op'': The callback function that performs the transition (resizing interpolation in this example).
* ''elm_transit_effect_translation_context_new()'': The callback function that returns the context used in the transition for calculations. In this example, the context is the coordinates of the before and after objects.
* ''elm_transit_effect_translation_context_free'': The callback function that frees up the memory once the transition is complete.
All the definitions above can be rewritten as follows:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_effect_translation_add(transit, from_x, from_y, to_x, to_y);
</code>
=== Translation ===
To perform a translation on an Evas object, use the following method:
<code c>
Elm_Transit_Effect* elm_transit_effect_translation_add(Elm_Transit * transit,
Evas_Coord from_dx,
Evas_Coord from_dy,
Evas_Coord to_dx,
Evas_Coord to_dy
)
</code>
* ''transit'' is the transit object that contains (among other things) all the Evas objects subject to the translation.
* ''from_dx'': The starting X coordinate (source).
* ''from_dy'': The starting Y coordinate (source).
* ''to_dx'': The ending X coordinate (destination).
* ''to_dy'': The ending Y coordinate (destination).
The following example shows how to slide an Evas object (a rectangle) on a
45-degree diagonal, from bottom-left to top-right, at a constant speed, and in
1 second:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, rectangle);
elm_transit_effect_translation_add(transit, 0, 0, 280, 280);
elm_transit_duration_set(transit, 1);
elm_transit_go(transit);
</code>
=== Color Transition ===
Color transitions allow you to dynamically change the color of Evas objects.
The first argument is the transit object, while the other arguments will be
used to define the color transition using RGB colors. There is also an alpha
channel that controls the opacity of the color (the background of the object,
not the object itself).
<code c>
Elm_Transit_Effect * elm_transit_effect_color_add(Elm_Transit * transit,
unsigned int from_r,
unsigned int from_g,
unsigned int from_b,
unsigned int from_a,
unsigned int to_r,
unsigned int to_g,
unsigned int to_b,
unsigned int to_a
)
</code>
* ''transit'': The transit object that contains (among other things) all the Evas objects subject to the translation.
* ''from_r'': The start value for "Red".
* ''from_g'': The start value for "Green".
* ''from_b'': The start value for "Blue".
* ''from_a'': The start value for "Alpha".
* ''to_r'': The end value for "Red".
* ''to_g'': The end value for "Green".
* ''to_b'': The end value for "Blue".
* ''to_a'': The end value for "Alpha".
The following example shows how to transit a rectangle from red to blue in 3
seconds:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, rectangle);
elm_transit_effect_color_add(transit, // Target object
255, 0, 0, 255, // From color
0, 0, 255, 255); // To color
elm_transit_duration_set(transit, 3);
elm_transit_go(transit);
</code>
=== Rotation ===
<code c>
Elm_Transit_Effect* elm_transit_effect_rotation_add(Elm_Transit * transit,
float from_degree,
float to_degree
)
</code>
* ''transit'': The transit object that contains (among other things) all the Evas objects subject to the translation.
* ''from_degree'': The start degree of rotation.
* ''to_degree'': The end degree of rotation.
This function can be used to perform a rotation on any Evas object. It works
the same way as the other transit effects and takes two arguments for the
starting and ending angles. Note that if you apply a rotation on multiple
objects, they will individually mill around and not act as a group. If you
want several objects to revolve around a common point, you must encapsulate
the objects into a single parent object and apply the rotation to the parent
object. The following example shows how to achieve this:
<code c>
// Parent container
Evas_Object *parent = elm_box_add(my_window);
evas_object_show(parent);
elm_box_horizontal_set(parent, EINA_TRUE);
elm_box_homogeneous_set(parent, EINA_TRUE);
// Button 1
Evas_Object *btn1 = elm_button_add(parent);
elm_object_text_set(btn1, "Btn1");
elm_box_pack_start(parent, btn1);
evas_object_show(btn1);
// Button 2
Evas_Object *btn2 = elm_button_add(parent);
elm_object_text_set(btn2, "Btn2");
elm_box_pack_end(parent, btn2);
evas_object_show(btn2);
// Make the parent container do a 360 degrees spin
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, parent);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);
</code>
=== Wipe Effect ===
The wipe effect is designed to dynamically hide or show any element on the
scene.
<code c>
Elm_Transit_Effect* elm_transit_effect_wipe_add(Elm_Transit * transit,
Elm_Transit_Effect_Wipe_Type type,
Elm_Transit_Effect_Wipe_Dir dir
)
</code>
In addition to the ''Elm_Transit'' instance passed as the first argument, the
function takes the following arguments:
* ''type'': The wipe type ''Elm_Transit_Effect_Wipe_Type'' defines whether to show or hide the target elements. The value can be one of the following:
* ''ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE'': Hide the object during the animation.
* ''ELM_TRANSIT_EFFECT_WIPE_TYPE_SHOW'': Show the object during the animation.
* ''dir'': The wipe direction ''Elm_Transit_Effect_Wipe_Dir'' defines in which direction the target will progressively appear or disappear. The value can be one of the following:
* ''ELM_TRANSIT_EFFECT_WIPE_DIR_LEFT''
* ''ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT''
* ''ELM_TRANSIT_EFFECT_WIPE_DIR_UP''
* ''ELM_TRANSIT_EFFECT_WIPE_DIR_DOWN''
The following example shows how to make an object disappear progressively from
left to right:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_wipe_add(transit,
ELM_TRANSIT_EFFECT_TYPE_HIDE,
ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);
</code>
=== Zoom Effect ===
''Elm_Transit'' provides a zoom function.
<code c>
Elm_Transit_Effect* elm_transit_effect_zoom_add(Elm_Transit * transit,
float from_rate,
float to_rate
)
</code>
* ''transit'': The transit object that contains (among other things) all the Evas objects subject to the translation.
* ''from_rate'': The starting level of the zoom.
* ''to_rate'': The ending level of the zoom.
The ''from_rate'' argument defines the scale of the target objects at the
beginning of the animation. A value of 1 represents the initial scale of the
objects.
Setting the value of the ''to_rate'' argument to 2 will double the size of the
target objects (double the width and double the height). When using this
effect, the width and height of a target object will remain proportional to
one another. If you want to customize the zoom effect, use the
''elm_transit_effect_resizing_add()'' function.
The following example shows how to implement a zoom-out transition. At the end
of the 2-secondstransition, the animated object will be half its original
size.
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_zoom_add(transit, 1, 0.5);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);
</code>
=== Resizing Effect ===
The resizing effect allows you to design an interpolation of the width and
height attributes of one or more target elements.
<code c>
Elm_Transit_Effect* elm_transit_effect_resizing_add(Elm_Transit * transit,
Evas_Coord from_w,
Evas_Coord from_h,
Evas_Coord to_w,
Evas_Coord to_h)
)
</code>
* ''transit'': The transit object that contains (among other things) all the Evas objects subject to the translation.
* ''from_w'': The starting width.
* ''from_h'': The starting height.
* ''to_w'': The ending width.
* ''to_h'': The ending height.
The ''from_w'' and ''from_h'' arguments define the size at the beginning of
the animation. The ''to_w'' and ''to_h'' arguments define the size at the end.
<note>
If you are planning to use this method to hide an Evas object by setting one
of the length attributes to zero, consider using the
''elm_transit_effect_wipe_add()'' function instead.
</note>
The following example shows how to make a rectangle exchange its width and
height properties in a 2-second transition:
<code c>
Evas_Coord w, h;
evas_object_geometry_get(my_evas_object, NULL, NULL, &w, &h);
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_resize_add(transit, // Transition object
w, h, // Original sizing
h, w); // Target sizing
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);
</code>
=== Flip Effect ===
This transition combines the target Evas objects in pairs, so that one object
will show up while the other one disappears. This association relates the even
objects in the transit list of objects with the odd ones. The even objects are
shown at the beginning of the animation, and the odd objects shown when the
transition is complete. In other words, the effect applies to each pair of
objects in the order in which they are listed in the transit list of objects.
The flip effect itself is a pseudo-3D effect where the first object in the
pair is the front object and the second one is the back object. When the
transition launches, the front object rotates around a preferred axis in order
to let the back object take its place.
<code c>
Elm_Transit_Effect* elm_transit_effect_flip_add(Elm_Transit * transit,
Elm_Transit_Effect_Flip_Axis axis,
Eina_Bool cw
)
</code>
* ''transit'' is the transit object.
* ''axis'' is the prefered axis of rotation:
* ''ELM_TRANSIT_EFFECT_FLIP_AXIS_X''
* ''ELM_TRANSIT_EFFECT_FLIP_AXIS_Y''
* ''cw'' is the direction of the rotation:
* ''EINA_TRUE'' is clockwise.
* ''EINA_FALSE'' is counterclockwise.
The following example shows how to create a coin that flips indefinitely. Note
that we use images as Elementary widgets for demonstration purposes. You can
use the ''elm_transit_effect_image_animation_add()'' function if you do not
want to bother creating widgets.
<code c>
// Coin Heads
Evas_Object *coin_heads = elm_image_add(win);
if (!elm_image_file_set(coin_heads, IMG_DIR"/coin_heads.png", NULL))
printf("error: could not load image");
elm_win_resize_object_add(win, coin_heads);
// Coin Tails
Evas_Object *coin_tails = elm_image_add(win);
if (!elm_image_file_set(coin_tails, IMG_DIR"/coin_tails.png", NULL))
printf("error: could not load image");
elm_win_resize_object_add(win, coin_tails);
// Transition definition
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_auto_reverse_set(transit, EINA_TRUE);
elm_transit_repeat_times_set(transit, -1);
elm_transit_effect_flip_add(transit, ELM_TRANSIT_EFFECT_FLIP_AXIS_X, EINA_TRUE);
elm_transit_go(transit);
</code>
{{ :event_effect_elementary_transitions_coin_flip.png }}
=== Resizable Flip Effect ===
In the flip example above, we used two objects that have the same size.
However, you may sometimes want to flip from one object to another object with
different size attributes. The most common example would be using buttons with
dimensions that depend on their contents (such as labels). If you decide to
use the classic ''elm_transit_effect_flip_add()'' function, the size of the
object will change at the moment one object becomes completely hidden and the
other one begins to show up. If you wish to interpolate the size attributes as
well, use the ''elm_transit_effect_resizable_flip_add()'' function:
<code c>
Elm_Transit_Effect* elm_transit_effect_resizable_flip_add(Elm_Transit * transit,
Elm_Transit_Effect_Flip_Axis axis,
Eina_Bool cw
)
</code>
* ''transit'' is the transit object.
* ''axis'' is the preferred axis of rotation:
* ''ELM_TRANSIT_EFFECT_FLIP_AXIS_X''
* ''ELM_TRANSIT_EFFECT_FLIP_AXIS_Y''
* ''cw'' is the direction of the rotation:
* ''EINA_TRUE'' is clockwise.
* ''EINA_FALSE'' is counterclockwise.
This function works the exact same way as the standard flip effect function.
=== Fade Effect ===
This effect is used to transition from one Evas object to another one using a
fading effect: the first object will slowly disappear to let the second object
take its place.
<code c>
Elm_Transit_Effect* elm_transit_effect_fade_add(Elm_Transit *transit)
</code>
This effect is applied to each pair of objects in the order in which they are
listed in the transit list of objects. The first object in the pair will be
the before object and the second one will be the after object.
Building on the coin flip example, the following example shows how to fade out
one face of the coin while fading in the other face:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_effect_fade_add(transit);
elm_transit_go(transit);
</code>
If you simply want to hide an object with a fade transition, consider using a
transparent after object.
=== Blend Effect ===
Another transition involving at least two Evas objects is the blend effect.
This transition makes the before object blurry before the after object
appears.
<code c>
elm_transit_effect_blend_add(Elm_Transit *transit)
</code>
The argument is the transition target of the blend effect.
Building on the coin flip example, the following example shows how to blur out
one face of the coin while blurring in the other face:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_effect_blend_add(transit);
elm_transit_go(transit);
</code>
If you simply want to hide an object with a blur transition, consider using a
transparent after object.
==== Combining Transitions ====
To use multiple transitions at the same time on the same objects, simply
declare the transitions one after the other.
Building on the coin flip example, the following example shows how to roll the
coin on the ground using a rotation and a translation effect:
<code c>
Evas_Object *coin_heads = elm_image_add(parent);
if (!elm_image_file_set(coin_heads, IMG_DIR"/coin_heads.png", NULL))
printf("error: could not load image");
evas_object_resize(coin_heads, 100, 100);
evas_object_show(coin_heads);
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_duration_set(transit, 5.0);
elm_transit_effect_translation_add(transit, 0, 0, 3.1415 * 2 * 100, 0);
elm_transit_effect_rotation_add(transit, 0, 360);
elm_transit_go(transit);
</code>
==== Animation Chain ====
Now that we have listed all the effects that can be implemented using
''Elm_Transit'', we will see how to chain transitions into sequences. To
create complex, chained animations without worrying about synchronization
between the transitions, use the ''elm_transit_chain_transit_add()'' function.
This function takes as arguments two ''Elm_Transit'' objects and will
automatically take care of the chaining for you: the second transition will
start as soon as the first transition is finished.
The following example shows how to move a datetime widget on a square
trajectory:
<code c>
Evas_Object *dt = elm_datetime_add(parent);
evas_object_resize(dt, 350, 50);
evas_object_show(dt);
// The first transition
Elm_Transit *t1 = elm_transit_add();
elm_transit_object_add(t1, dt);
elm_transit_duration_set(t1, 2);
elm_transit_effect_translation_add(t1, 0, 0, 100, 0);
// The second transition
Elm_Transit *t2 = elm_transit_add();
elm_transit_object_add(t2, dt);
elm_transit_duration_set(t2, 2);
elm_transit_effect_translation_add(t2, 100, 0, 100, 100);
// The third transition
Elm_Transit *t3 = elm_transit_add();
elm_transit_object_add(t3, dt);
elm_transit_duration_set(t3, 2);
elm_transit_effect_translation_add(t3, 100, 100, 0, 100);
// The fourth transition
Elm_Transit *t4 = elm_transit_add();
elm_transit_object_add(t4, dt);
elm_transit_duration_set(t4, 2);
elm_transit_effect_translation_add(t4, 0, 100, 0, 0);
// Chaining the transitions
elm_transit_chain_transit_add(t1, t2);
elm_transit_chain_transit_add(t2, t3);
elm_transit_chain_transit_add(t3, t4);
// Starting the transitions
elm_transit_go(t1);
</code>
Note that we cannot use transition chaining to make a loop animation, since
the transit object is automatically destroyed as soon as the transition
completes. Therefore, you cannot do something like this:
<code c>
elm_transit_chain_transit_add(t4, t1);
</code>
To create a looped animation chain, you have to use low-level components
provided by the Ecore and Evas transition libraries, or you can use the
''elm_transit_del_cb_set()'' function to define a callback function for when a
transition gets deleted. This way, you could recreate your objects and
reiterate the transition chain as soon as the last transition ends.
<code c>
void elm_transit_del_cb_set(Elm_Transit * transit,
Elm_Transit_Del_Cb cb,
void * data
)
</code>
* ''transit'' is the transition object.
* ''cb'' is the callback function to run on transition delete.
* ''data'' is the data to pass to the callback function.
You can severe the chain relationship between two transits by using the
''elm_transit_chain_transit_del()'' function:
<code c>
void elm_transit_chain_transit_del(Elm_Transit * transit,
Elm_Transit * chain_transit
)
</code>
* ''transit'' is the first transition in the chain.
* ''chain_transit'' is the second transition in the chain.
To get the current chain transit list, use the
''elm_transit_chain_transits_get()'' function.
==== Animation Timeline ====
After you have defined all the properties that define your transition, start
the transition with the ''elm_transit_go()'' function:
<code c>
void elm_transit_go(Elm_Transit *transit)
</code>
You can maintain full control over the execution process even after the
transition has started. You can pause the transition by setting the paused
argument to ''EINA_TRUE'':
<code c>
elm_transit_paused_set(Elm_Transit * transit,
Eina_Bool paused
)
</code>
You can resume the transition by using the same method but setting the paused
argument to ''EINA_FALSE''. If you want to know whether the transition is
currently paused, use the ''elm_transit_paused_get()'' function.
You can remain informed about the present transition flow and get the current
frame by using the ''elm_transit_progress_value_get()'' function. This
function will return the timeline position of the animation, ranging between
0.0 (start) and 1.0 (end).
==== Custom Transition ====
''Elm_Transit'' provides a standard function for defining any effect of your
choosing that will be applied to some context data:
<code c>
elm_transit_effect_add(Elm_Transit * transit,
Elm_Transit_Effect_Transition_Cb transition_cb,
Elm_Transit_Effect * effect,
Elm_Transit_Effect_End_Cb end_cb
)
</code>
* ''transit'' is the transition target of the new effect.
* ''transition_cb'' is the transition callback function.
* ''effect'' is the new effect.
* ''end_cb'' is the callback function to call at the end of the effect.
As described earlier in this programming guide, this function embraces three
callbacks that will allow you to define every aspects of your transition from
its creation to its deletion. The following is an example of how to build a
custom resizing animation.
First, we define a structure capable of holding the context information about
resizing an Evas object:
<code c>
typedef struct
{
struct _size
{
Evas_Coord w, h;
}
from, to;
}
Custom_Effect;
</code>
We can now implement our custom resizing callback function. This function
takes the following arguments:
* ''data'' is the context data that holds the custom properties of our transition, which are used as parameters to calculate the interpolation.
* ''transit'' is the transit object that contains the list of our Evas objects to animate and all the information about duration, auto-reverse, looping, and so on.
* ''progress'' is the progress (position along the animation timeline) that ranges from 0.0 to 1.0 and allows us to calculate the desired interpolation for each frame.
<code c>
static void
_custom_op(void *data, Elm_Transit *transit, double progress)
{
if (!data) return;
Evas_Coord w, h;
Evas_Object *obj;
const Eina_List *elist;
Custom_Effect *custom_effect = data;
const Eina_List *objs = elm_transit_objects_get(transit);
if (progress &lt; 0.5)
{
h = custom_effect->from.h + (custom_effect->to.h * progress * 2);
w = custom_effect->from.w;
}
else
{
h = custom_effect->from.h + custom_effect->to.h;
w = custom_effect->from.w + (custom_effect->to.w * (progress - 0.5) * 2);
}
EINA_LIST_FOREACH(objs, elist, obj)
evas_object_resize(obj, w, h);
}
</code>
The callback function above resizes our Evas objects in two steps. During the
first half of the transition, only the height changes, while the width remains
the same. During the second half, it is the other way around until we get to
the desired size.
You must then define the context used by your animation:
<code c>
static void*
_custom_context_new(Evas_Coord from_w, Evas_Coord from_h, Evas_Coord to_w, Evas_Coord to_h)
{
Custom_Effect *custom_effect;
custom_effect = calloc(1, sizeof(Custom_Effect));
if (!custom_effect) return NULL;
custom_effect->from.w = from_w;
custom_effect->from.h = from_h;
custom_effect->to.w = to_w - from_w;
custom_effect->to.h = to_h - from_h;
return custom_effect;
}
</code>
You must define the function that will take care of deleting all the context
objects used by your custom transition and free up the allocated memory:
<code c>
static void
_custom_context_free(void *data, Elm_Transit *transit __UNUSED__)
{
free(data);
}
</code>
Finally, apply your custom transition to your ''Elm_Transit'' object:
<code c>
Elm_Transit *transit = elm_transit_add();
elm_transit_effect_add(transit,
_custom_op,
_custom_context_new(),
_custom_context_free);
</code>
If you want to delete an effect from your effects list, use the
''elm_transit_effect_del()'' function.
\\
^ Elm Transit Examples ^^^^^
|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_01_explained.html|Basic Transit Usage]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_02_explained.html|Chained Transitions]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_03_explained.html|Combined effects and options]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_04_c.html|Combined effects over two objects]]|
------
{{page>index}}

View File

@ -0,0 +1,69 @@
~~Title: Evas Events~~
{{page>index}}
----
===== Evas Events =====
Evas events happen on a canvas as a whole. This kind of events are too
low-level for writing applications and are most often used when writing the
graphical toolkit itself.
=== Table of Contents ===
* [[#Adding_Callbacks_to_Canvases:_evas_event_callback_add/del</a>|Adding Callbacks to Canvases: evas_event_callback_add/del]]
* [[#Types_of_Evas_Events|Types of Evas Events]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas__Canvas__Events.html|Canvas Events API]] ([[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas.html#gad64cde0da38a60e7cb7905b3ab216968|Evas API]])
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/Example_Evas_Events.html|Evas events example]]
==== Adding Callbacks to Canvases: evas_event_callback_add/del ====
The callbacks are added with ''evas_event_callback_add()''. Its prototype is
<code c>
void evas_event_callback_add(Evas* e,
Evas_Callback_Type type,
Evas_Event_Cb func,
const void* data
)
</code>
* ''e'' is the evas canvas on which the events happen. If needed, it can be
obtained from an Evas_Object through the ''evas_object_evas_get()'' function.
* ''type'' is the type of event that triggers the callback (the list is in the next section).
* ''func'' is the function that is called.
* ''data'' is a pointer to additional data that is given as an argument to the callback. It is optional and ''NULL'' is an acceptable value.
The type of the callback function is defined as follows.
<code c>
void (* Evas_Event_Cb) (void *data, Evas *e, void *event_info)
</code>
The callback function definition is similar to
<code c>
void some_evas_object_event_cb(void *data, Evas *e, void *event_info);
</code>
* ''data'' is the same as the data which was given as the parameter to ''evas_event_callback_add()''.
* ''e'' is the canvas on which the event occurred.
* ''event_info'' is data which depends on the object type and the event at play. The documentation must be read for each such event.
==== Types of Evas Events ====
The values are defined from the ''Evas_Callback_Type'' enum. Some of them are
not used for ''evas_event_callback_add()'' but are used in the previous
section.
* ''EVAS_CALLBACK_CANVAS_FOCUS_IN '': Image has been preloaded.
* ''EVAS_CALLBACK_CANVAS_FOCUS_OUT '': Canvas got focus as a whole.
* ''EVAS_CALLBACK_RENDER_FLUSH_PRE '': Canvas lost focus as a whole.
* ''EVAS_CALLBACK_RENDER_FLUSH_POST '': Called just before rendering is updated on the canvas target.
* ''EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN '': Called just after rendering is updated on the canvas target.
* ''EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT'': Canvas object got focus.
\\
--------
{{page>index}}

View File

@ -0,0 +1,577 @@
~~Title: Evas Map Effects~~
{{page>index}}
----
===== Evas Map Effects =====
Evas Map animations allow you to apply transformations to all types of objects
by way of UV mapping.
In UV mapping, you map points in the source object to 3D space positions in
the target object. This allows for rotation, perspective, scale, and other
transformation effects, depending on the map. In addition, each map point can
carry a multiplier color, which, if properly calculated, can be used to apply
3D shading effects on the target object.
Evas provides both raw and easy-to-use functions for UV mapping. The raw
functions allow you to create UV maps outside Evas and import them into your
application, for example by loading them from an external file. The
easy-to-use functions allow you to create UV maps directly in Evas by
calculating the map points based on high-level parameters, such as rotation
angle and ambient light.
=== Table of Contents ===
* [[#Map_Points|Map Points]]
* [[#Utility_Functions|Utility Functions]]
* [[#Zoom|Zoom]]
* [[#3D_Maps|3D Maps]]
* [[#3D_Rotation_and_Perspective|3D Rotation and Perspective]]
* [[#Color_and_Lighting|Color and Lighting]]
* [[#Mapping|Mapping]]
* [[#Lighting|Lighting]]
* [[#Alpha_Channel|Alpha Channel]]
* [[#Smoothing|Smoothing]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas__Object__Group__Map.html | Evas Map API]]
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/Example_Evas_Map_Overview.html|Evas Map Example]]
==== Map Points ====
A map consists of a set of points. (Currently, only four points are
supported.) Each point contains X and Y canvas coordinates that can be used to
alter the geometry of the mapped object, and a Z coordinate that indicates the
depth of the point. The Z coordinate does not normally affect the map, but
several utility functions use it to calculate the right position of the point
given the other parameters.
First, create an ''Evas_Map'' object using the ''evas_map_new()'' function.
This function creates the specified number of map points (currently only up to
four points). Each point is empty and ready to be modified with ''Evas_Map''
functions.
<code c>
Evas_Map *m = evas_map_new(4);
</code>
If you want to get the size (number of points) of an existing map, use the
''evas_map_count_get()'' function.
To set the coordinates for each point, use the ''evas_map_point_coord_set()''
function:
<code c>
evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z)
</code>
The following example shows a common way to define a map that matches the
geometry of a rectangle (a square in this case):
<code c>
evas_map_point_coord_set(m, 0, 100, 100, 0);
evas_map_point_coord_set(m, 1, 300, 100, 0);
evas_map_point_coord_set(m, 2, 300, 300, 0);
evas_map_point_coord_set(m, 3, 100, 300, 0);
</code>
{{ :event_effect_evas_map_1.png }}
The following examples all produce the same result as the above example, but
with simpler code:
* To create a rectangle map using the starting X and Y coordinates combined with width and height, use the ''evas_map_util_points_populate_from_geometry()'' function:
<code c>
evas_map_util_points_populate_from_geometry(Evas_Map *m, Evas_Coord x,
Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z)
</code>
The following example creates the same map as above:
<code c>
evas_map_util_points_populate_from_geometry(m, 100, 100, 200, 200, 0);
</code>
* To create a map based on the geometry of a given object, use the ''evas_map_util_points_populate_from_object()'' or ''evas_map_util_points_populate_from_object_full()'' function. The former sets the Z coordinate of all points to 0, whereas the latter allows you to define the same custom Z coordinate for all points:
<code c>
evas_map_util_points_populate_from_object(Evas_Map *m, const Evas_Object *obj)
</code>
<code c>
evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *obj, Evas_Coord z)
</code>
The following example creates the same map as above:
<code c>
Evas_Object *o;
evas_object_move(o, 100, 100);
evas_object_resize(o, 200, 200);
evas_map_util_points_populate_from_object(m, o);
// OR
evas_map_util_points_populate_from_object_full(m, o, 0);
</code>
You can apply several effects to an object by simply setting each point of the
map to the appropriate coordinates. The following example shows how to create
a simulated perspective:
{{ :event_effect_evas_map_2.png }}
<code c>
evas_map_point_coord_set(m, 0, 100, 100, 0);
evas_map_point_coord_set(m, 1, 250, 120, 0);
evas_map_point_coord_set(m, 2, 250, 280, 0);
evas_map_point_coord_set(m, 0, 100, 300, 0);
</code>
In the above example, the Z coordinate is unused: when setting points by hand,
the Z coordinate is irrelevant.
If you want to get the actual coordinates of a map, use the
''evas_map_point_coord_get()'' function:
<code c>
evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z)
</code>
After you have defined the map points, apply them to your map for
transformation:
<code c>
evas_object_map_set(o, m);
evas_object_map_enable_set(o, EINA_TRUE);
</code>
Finally, after you are done with the map, release the memory allocated to it
using the ''evas_map_free()'' function:
<code c>
evas_map_free(m);
</code>
The utility functions described in the next section allow you to perform the
above tasks with less coding work.
==== Utility Functions ====
Utility functions take an already configured map and allow you to easily
modify it to produce specific effects. For example, to rotate an object around
its center, you need the rotation angle and the coordinates of each corner of
the object to perform the math required to get the new set of coordinates that
needs to be set for the map. Evas provides a utility function that does the
math for you:
<code c>
void evas_map_util_rotate(Evas_Map * m,
double degrees,
Evas_Coord cx,
Evas_Coord cy
)
</code>
* ''m'' map to change.
* ''zoomx'' horizontal zoom to use.
* ''zoomy'' vertical zoom to use.
* ''cx'' zooming center horizontal position.
* ''cy'' zooming center vertical position.
This function rotates the map based on the angle and the center coordinates of
the rotation provided as arguments. A positive angle rotates the map
clockwise, while a negative angle rotates the map counterclockwise.
The following example shows how to rotate an object around its center point by
45 degrees clockwise. In the following figure, the center of rotation is the
red dot.
<code c>
evas_object_geometry_get(o, &x, &y, &w, &h);
m = evas_map_new(4);
evas_map_util_points_populate_from_object(m, o);
evas_map_util_rotate(m, 45, x + (w / 2), y + (h / 2));
evas_object_map_set(o, m);
evas_object_map_enable_set(o, EINA_TRUE);
evas_map_free(m);
</code>
{{ :event_effect_evas_map_3.png }}
You can rotate the object around any other point simply by setting the last
two arguments of the ''evas_map_util_rotate()'' function to the appropriate
values:
<code c>
evas_map_util_rotate(m, 45, x + w - 20, y + h - 20);
</code>
{{ :event_effect_evas_map_4.png }}
You can also set the center of the window as the center of the rotation using
the appropriate coordinates of the Evas canvas:
<code c>
evas_output_size_get(evas, &amp;w, &amp;h);
m = evas_map_new(4);
evas_map_util_points_populate_from_object(m, o);
evas_map_util_rotate(m, 45, w, h);
evas_object_map_set(o, m);
evas_object_map_enable_set(o, EINA_TRUE);
evas_map_free(m);
</code>
==== Zoom ====
The ''evas_map_util_zoom()'' function zooms the points of the map from a
center point, defined by ''cx'' and ''cy''. The ''zoomx'' and ''zoomy''
arguments specify how much to zoom in on the X and Y axes. A value of 1.0
means no zoom, 2.0 means double the size, 0.5 means half the size, and so on.
All the coordinates are global canvas coordinates.
<code c>
void evas_map_util_zoom(Evas_Map * m,
double zoomx,
double zoomy,
Evas_Coord cx,
Evas_Coord cy
)
</code>
* ''m'' map to change.
* ''zoomx'' horizontal zoom to use.
* ''zoomy'' vertical zoom to use.
* ''cx'' zooming center horizontal position.
* ''cy'' zooming center vertical position.
==== 3D Maps ====
Maps can also be used to achieve a 3D effect. In a 3D effect, the Z coordinate
of each point is meaningful: the higher the value, the further back the point
is located. Smaller values (usually negative) mean that the point is closer to
the user.
3D also introduces the concept of the back face of an object. An object is
said to be facing the user when all its points are placed in a clockwise
formation, as shown in the left map in the following figure. Rotating the map
around its Y axis swaps the order of the points into a counterclockwise
formation, making the object face away from the user, as shown in the right
map in the following figure. The back face is especially relevant in lighting
(see below).
{{ :event_effect_evas_map_5.png }}
To determine whether a map is facing the user, use the
''evas_map_util_clockwise_get()'' function. This function returns
''EINA_TRUE'' if the map is facing the user and ''EINA_FALSE'' if the map is
facing away from the user. This is normally done after all the other
operations are applied to the map.
<code c>
Eina_Bool evas_map_util_clockwise_get(Evas_Map *m)
</code>
==== 3D Rotation and Perspective ====
The ''evas_map_util_3d_rotate()'' function transforms a map to apply a 3D
rotation to the mapped object. You can apply the rotation around any point in
the canvas (including a Z coordinate). You can also apply the rotation around
any of the three axes.
<code c>
evas_map_util_3d_rotate(Evas_Map * m,
double dx,
double dy,
double dz,
Evas_Coord cx,
Evas_Coord cy,
Evas_Coord cz
)
</code>
* ''m'': map to change.
* ''dx'': amount of degrees from 0.0 to 360.0 to rotate around X axis.
* ''dy'': amount of degrees from 0.0 to 360.0 to rotate around Y axis.
* ''dz'': amount of degrees from 0.0 to 360.0 to rotate around Z axis.
* ''cx'': rotation's center horizontal position.
* ''cy'': rotation's center vertical position.
* ''cz'': rotation's center vertical position.
Starting from this simple setup, and setting the maps so that the blue square
rotates around the Y axis, we get the following:
{{ :event_effect_evas_map_6.png }}
A simple overlay over the image shows the original geometry of each object and
the axis around which they are being rotated. The Z axis is not shown, since
it is orthogonal to the screen. To show the Z axis, that is, to add 3D
perspective to the transformation, use the ''evas_map_util_3d_perspective()''
function on the map after its position has been set:
<code c>
void evas_map_util_3d_perspective(Evas_Map * m,
Evas_Coord px,
Evas_Coord py,
Evas_Coord z0,
Evas_Coord foc
)
</code>
* ''m'': map to change.
* ''px'': The perspective distance X coordinate
* ''py'': The perspective distance Y coordinate
* ''z0'': The "0" z plane value
* ''foc'': The focal distance
The result makes the vanishing point the center of each object:
{{ :event_effect_evas_map_7.png }}
==== Color and Lighting ====
Each point in a map can be set to a color, which will be multiplied with the
objects own color and linearly interpolated between adjacent points. To set
the color separately for each point, use the ''evas_map_point_color_set()''
function:
<code c>
void evas_map_point_color_set(Evas_Map * m,
int idx,
int r,
int g,
int b,
int a
)
</code>
* ''m'' map to change the color of.
* ''idx'' index of point to change. Must be smaller than map size.
* ''r'' red (0 - 255)
* ''g'' green (0 - 255)
* ''b'' blue (0 - 255)
* ''a'' alpha (0 - 255)
To set the same color for every point, use the
''evas_map_util_points_color_set()'' function:
<code c>
void evas_map_util_points_color_set(Evas_Map *m, int r, int g, int b, int a)
</code>
When using a 3D effect, colors can be used to improve its look by simulating a
light source. The ''evas_map_util_3d_lighting()'' function makes this task
easier by taking the coordinates of the light source and its color, along with
the color of the ambient light. Evas then sets the color of each point based
on its distance to the light source, the angle at which the object is facing
the light source, and the ambient light. Here, the orientation of each point
is important.
<code c>
evas_map_util_3d_lighting(Evas_Map * m,
Evas_Coord lx,
Evas_Coord ly,
Evas_Coord lz,
int lr,
int lg,
int lb,
int ar,
int ag,
int ab
)
</code>
* ''m'' map to change.
* ''lx'' X coordinate in space of light point
* ''ly'' Y coordinate in space of light point
* ''lz'' Z coordinate in space of light point
* ''lr'' light red value (0 - 255)
* ''lg'' light green value (0 - 255)
* ''lb'' light blue value (0 - 255)
* ''ar'' ambient color red value (0 - 255)
* ''ag'' ambient color green value (0 - 255)
* ''ab'' ambient color blue value (0 - 255)
If the map points are defined counterclockwise, the object faces away from the
user and is therefore obscured, since no light is reflecting back from it.
{{ :event_effect_evas_map_8.png }}
==== Mapping ====
Images need special handling when mapped. While Evas can easily handle objects, it is completely oblivious to the contents of images. This means that each point in a map needs to be mapped to a specific pixel in the source image. Failing to do this can result in unexpected behavior.
Let's get started with the following three images, each sized at 200 × 200 pixels:
{{ :event_effect_evas_map_9.png }}
The following three images illustrate the case where a map is set to an image
object without setting the right UV mapping for each map point. The objects
themselves are mapped properly to their new geometries, but the images are not
displayed correctly within the mapped objects.
{{ :event_effect_evas_map_10.png }}
To transform an image correctly, Evas needs to know how to handle the image
within the map. You can do this using the ''evas_map_point_image_uv_set()''
function, which allows you to map a given point in a map to a given pixel in a
source image:
<code c>
void evas_map_point_image_uv_set(Evas_Map *m,
int idx,
double u,
double v
)
</code>
* ''m'' map to change the point of.
* ''idx'' index of point to change. Must be smaller than map size.
* ''u'' the X coordinate within the image/texture source
* ''v'' the Y coordinate within the image/texture source
To match our example images to the maps above, all we need is the size of each
image, which we can get using the ''evas_object_image_size_get()'' function.
<code c>
// Tux 1: Some cropping and stretch up
evas_map_point_image_uv_set(m, 0, 0, 20);
evas_map_point_image_uv_set(m, 1, 200, 20);
evas_map_point_image_uv_set(m, 2, 200, 180);
evas_map_point_image_uv_set(m, 3, 0, 180);
evas_object_map_set(tux1, m);
evas_object_map_enable_set(tux1, EINA_TRUE);
// Inverted texture for shadow:
evas_map_point_image_uv_set(m, 0, 0, 180);
evas_map_point_image_uv_set(m, 1, 200, 180);
evas_map_point_image_uv_set(m, 2, 200, 20);
evas_map_point_image_uv_set(m, 3, 0, 20);
evas_object_map_set(tux1_shadow, m);
evas_object_map_enable_set(tux1_shadow, EINA_TRUE);
// Tux 2: Make it fit to the map:
evas_map_point_image_uv_set(m, 0, 0, 0);
evas_map_point_image_uv_set(m, 1, 200, 0);
evas_map_point_image_uv_set(m, 2, 200, 200);
evas_map_point_image_uv_set(m, 3, 0, 200);
evas_object_map_set(tux2, m);
evas_object_map_enable_set(tux2, EINA_TRUE);
// Tux 3: Zoom and fit relatively to image size
evas_object_image_size_get(evas_object_image_source_get(tux3), &w, &h);
evas_map_point_image_uv_set(m, 0, 0.1 * w, 0.1 * h);
evas_map_point_image_uv_set(m, 1, 0.9 * w, 0.1 * h);
evas_map_point_image_uv_set(m, 2, 0.9 * w, 0.9 * h);
evas_map_point_image_uv_set(m, 3, 0.1 * w, 0.9 * h);
evas_object_map_set(tux3, m);
evas_object_map_enable_set(tux3, EINA_TRUE);
</code>
{{ :event_effect_evas_map_11.png }}
You can also set a map to use only part of an image, or you can even map the
points in inverted order. Combined with the ''evas_object_image_source_set()''
function, you can achieve more interesting results still.
==== Lighting ====
''Evas_Map'' allows you to define an ambient light and a light source within
the scene. Both of these light sources have their own colors.
<code c>
void evas_map_util_3d_lighting(Evas_Map * m,
Evas_Coord lx,
Evas_Coord ly,
Evas_Coord lz,
int lr,
int lg,
int lb,
int ar,
int ag,
int ab
)
</code>
* ''m'' map to change.
* ''lx'' X coordinate in space of light point
* ''ly'' Y coordinate in space of light point
* ''lz'' Z coordinate in space of light point
* ''lr'' light red value (0 - 255)
* ''lg'' light green value (0 - 255)
* ''lb'' light blue value (0 - 255)
* ''ar'' ambient color red value (0 - 255)
* ''ag'' ambient color green value (0 - 255)
* ''ab'' ambient color blue value (0 - 255)
The above function is used to apply lighting calculations (from a single light
source) to a given map. The red, green, and blue values of each vertex will be
modified to reflect the lighting based on the light source coordinates, its
color, the ambient color, and the angle at which the map faces the light
source. The points of a surface should be defined in a clockwise formation if
the surface is facing the user, since faces have a logical side for lighting.
To get the reflections (gradient) in the shadow of our previous example, you
have to define a source of light close enough to the user and a very bright
ambient light, for example:
<code c>
evas_map_util_3d_lighting(m, // Evas_Map object
250/2, 150/2, -100, // Spot light coordinates
255, 255, 255, // Spot light color
200, 200, 200); // Ambient light color
</code>
==== Alpha Channel ====
You can also use an alpha channel on your map by enabling the alpha channel
feature:
<code c>
evas_map_alpha_set(Evas_Map *m, Eina_Bool enabled)
</code>
Next, set the alpha value separately for each map point:
<code c>
evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a)
</code>
Alternatively, you can set the same alpha value to all map points:
<code c>
evas_map_util_points_color_set(Evas_Map *m, int r, int g, int b, int a)
</code>
The following code sets the shadow transparency for the first image in the
above three-image example:
<code c>
// Set object transparency to 50%:
evas_map_util_points_color_set(m, 255, 255, 255, 127);
// Tux's head is almost invisible in the shadow:
evas_map_point_color_set(m, 3, 255, 255, 255, 15);
evas_map_point_color_set(m, 4, 255, 255, 255, 15);
</code>
==== Smoothing ====
To enable smoothing when rendering a map, use the ''evas_map_smooth_set()''
function:
<code c>
evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled)
</code>
The first argument is the ''Evas_Map'' object to apply smoothing to. The second argument sets whether to enable the smoothing:
* ''EINA_TRUE'': Enable smoothing.
* ''EINA_FALSE'': Disable smoothing.
If the object is of a type that has its own smoothing settings, the smoothing
settings must be disabled for both the object and the map. Map smoothing is
enabled by default. To check whether map smoothing is enabled, use the
''evas_map_smooth_get()'' function.
\\
[[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/Example_Evas_Map_Overview.html|Evas Map Example]]
-------
{{page>index}}

View File

@ -0,0 +1,87 @@
~~Title: Evas Object Events~~
{{page>index}}
----
===== Evas Object Events =====
Each of the evas objects on a given evas canvas can be manipulated
independently. They send events, to which callbacks can be attached through
''evas_object_event_callback_add()'' and removed with
''evas_object_event_callback_del()''. These events all relate to single
objects, not the whole canvas.
=== Table of Contents ===
* [[#Adding_and_Removing_Callbacks:_evas_object_event_callback_add/del|Adding and Removing Callbacks: evas_object_event_callback_add/del]]
* [[#Types_of_Evas_Object_Events|Types of Evas Object Events]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas__Object__Group__Events.html|Object Events API]]
==== Adding and Removing Callbacks: evas_object_event_callback_add/del ====
Callbacks are added with ''evas_event_callback_add()''. Its prototype is
<code c>
void evas_object_event_callback_add(Evas_Object* obj,
Evas_Callback_Type type,
Evas_Object_Event_Cb func,
const void* data
)
</code>
* ''obj'' is the object to attach the callback to.
* ''type'' is the type of event that triggers the callback (the list is in the next section).
* ''func'' is the function that is called.
* ''data'' is a pointer to additional data that is given as the argument to the callback. It is optional and ''NULL'' is an acceptable value.
The type of the callback function is defined as follows.
<code c>
void (* Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info)
</code>
The callback function definition is similar to
<code c>
void some_evas_object_event_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
</code>
* ''data'' is the same as the data which was given as the parameter to ''evas_object_smart_callback_add()''.
* ''e'' is the canvas on which the event occurred.
* ''obj'' is the object to which the event happened.
* ''event_info'' is data which depends on the object type and event at play. The documentation must be read for each event.
==== Types of Evas Object Events ====
The values are defined from the ''Evas_Callback_Type'' enum. Some of them are
not used for ''evas_object_event_callback_add()'', but are used in the next
section.
* ''EVAS_CALLBACK_MOUSE_IN'': the pointer got over an object (with no other object between the two). This takes place no matter how the pointer becomes directly above the object. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_In'' struct.
* ''EVAS_CALLBACK_MOUSE_OUT'': triggered similarly to ''EVAS_CALLBACK_MOUSE_IN'', but when the pointer goes outside an object's area. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_Out'' struct.
* ''EVAS_CALLBACK_MOUSE_DOWN'': a mouse button is pressed while the object is receiving events (either because the pointer is on top of the object or because the object had focus). ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_Down'' struct.
* ''EVAS_CALLBACK_MOUSE_UP'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_Up'' struct.
* ''EVAS_CALLBACK_MOUSE_MOVE'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_Move'' struct.
* ''EVAS_CALLBACK_MOUSE_WHEEL'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_Wheel'' struct.
* ''EVAS_CALLBACK_MULTI_DOWN'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Multi_Down'' struct.
* ''EVAS_CALLBACK_MULTI_UP'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Multi_Up'' struct.
* ''EVAS_CALLBACK_MULTI_MOVE'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Multi_Move'' struct.
* ''EVAS_CALLBACK_KEY_DOWN'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Key_Down'' struct.
* ''EVAS_CALLBACK_KEY_UP'': triggered similarly to ''EVAS_CALLBACK_MOUSE_DOWN''. ''event_info'' in the callback is a pointer to an ''Evas_Event_Key_Up'' struct.
* ''EVAS_CALLBACK_FOCUS_IN'': the object gained focus. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_In'' struct.
* ''EVAS_CALLBACK_FOCUS_OUT'': the object lost focus. ''event_info'' in the callback is a pointer to an ''Evas_Event_Mouse_In'' struct.
* ''EVAS_CALLBACK_SHOW'': the object is shown by a call to ''evas_object_show()''. ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_HIDE'': the object is hidden by a call to ''evas_object_hide()''. ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_MOVE'': the object's origin was moved (origin is the top-left corner at the creation time of the object). ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_RESIZE'': the object is resized. ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_RESTACK'': the object is re-stacked by ''evas_object_stack_below()'', ''evas_object_stack_above()'' or other events. ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_DEL'': the object is deleted.
* ''EVAS_CALLBACK_FREE'': for internal use only. Do not use (the object resources are about to be freed). ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_HOLD'': for internal use only. ''event_info'' in the callback is a pointer to an ''Evas_Event_Hold'' struct.
* ''EVAS_CALLBACK_CHANGED_SIZE_HINTS'': the size hints of the object changed.
* ''EVAS_CALLBACK_IMAGE_PRELOADED'': an image which was preloaded through ''evas_object_image_preload()'' is loaded. ''event_info'' in the callback is NULL.
* ''EVAS_CALLBACK_IMAGE_UNLOADED'': the image data is unloaded. ''event_info'' in the callback is NULL.

View File

@ -0,0 +1,162 @@
~~Title: Evas Smart Object Events~~
{{page>index}}
----
===== Evas Smart Object Events =====
Evas smart objects events are the most widely-used type of events in graphical
applications, since they are used for signals such as "clicked",
"clicked,double" (double-click), "pressed", etc. They are identified by
strings and each smart object is able to define its own events (although the
names follow conventions).
=== Table of Contents ===
* [[#Adding_a_Callback_on_an_Event:_evas_object_smart_callback_add()|Adding a Callback on an Event: evas_object_smart_callback_add()]]
* [[#Removing_a_Callback_on_an_Event:_evas_object_smart_callback_del()|Removing a Callback on an Event: evas_object_smart_callback_del()]]
* [[#Examples|Examples]]
* [[#Basic_Usage:_Button_with_a_Callback_on_the_"clicked"_Signal|Basic Usage: Button with a Callback on the "clicked" Signal]]
* [[#Usage_with_evas_object_smart_callback_del():_Clicking_on_the_Button_Removes_the_Callback|Usage with evas_object_smart_callback_del(): Clicking on the Button Removes the Callback]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas__Smart__Object__Group.html#ga18a8b179f94d21b2b09e19db11741061|Smart Object Functions API]]
==== Adding a Callback on an Event: evas_object_smart_callback_add() ====
Use the ''evas_object_smart_callback_add()'' function to add a callback for an
event to an object. Its prototype is
<code c>
void evas_object_smart_callback_add(Evas_Object* obj,
const char* event,
Evas_Smart_Cb func,
const void* data
)
</code>
* ''obj'' a smart object
* ''event'' the event's name string
* ''func'' the callback function
* ''data'' user data to be passed to the callback function
Evas smart objects' "smart callback" has the following signature:
<code c>
void (* Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info)
</code>
The callback function definition is similar to
<code c>
void some_evas_smart_cb(void *data, Evas_Object *obj, void *event_info);
</code>
* ''data'' is the same as the ''data'' which is given as the parameter to ''evas_object_smart_callback_add()''.
* ''obj'' is the object for which the event happened.
* ''event_info'' is data, which depends on the object type and event at play. The actual type is given in the documentation for the callback that is triggered
The following defines the ''_button_clicked()'' function and sets it as the
callback for the ''clicked'' event of an ''Evas_Object'' (a button here).
<code c>
static void
_button_clicked(void *data, Evas_Object *obj, void *event_info)
{
// Insert function body here
}
</code>
<code c>
static void
some_function(void)
{
// Code to build the window object
Evas_Object *button = elm_button_add(window);
evas_object_smart_callback_add(button, "clicked", _button_clicked, NULL);
}
</code>
If some of the arguments are not used by the callback function, the compiler
may raise the "unused parameter" warning. To avoid it, you can annotate the
argument with the ''__UNUSED__'' macro, which is a compiler-independent way to
let the compiler know that the parameter is willingly unused rather than by a
mistake.
<code c>
void cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
</code>
For a given object and event, callbacks are called in the order they have been
added. The ''evas_object_smart_callback_add()'' function does not execute any
special processing if it is called several times with the same callback
function and/or data. Callbacks are called as many times as they have been
added and in the order they have been added.
==== Removing a Callback on an Event: evas_object_smart_callback_del() ====
The ''evas_object_smart_callback_del()'' function enables deleting a callback
for a signal on an object. Its prototype is
<code c>
void* evas_object_smart_callback_del(Evas_Object* obj,
const char* event,
Evas_Smart_Cb func
)
</code>
It removes the first match for the given event and callback and returns the
''data'' pointer that was used in the corresponding call to
''evas_object_smart_callback_add()''.
==== Examples ====
=== Basic Usage: Button with a Callback on the "clicked" Signal ===
<code c>
static void
_button_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
fprintf(stdout, "Button clicked.\n");
fflush(stdout);
elm_exit();
}
static void
_add_button(Evas_Object *window)
{
Evas_Object *button;
button = elm_button_add(window);
elm_object_text_set(button, "Click Me To Exit!");
evas_object_smart_callback_add(button, "clicked", _button_clicked, NULL);
evas_object_show(button);
}
</code>
=== Usage with evas_object_smart_callback_del(): Clicking on the Button Removes the Callback ===
<code c>
static void
_button_clicked(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
fprintf(stdout, "Button clicked.\n");
fflush(stdout);
evas_object_smart_callback_del(obj, "clicked", _button_clicked);
}
static void
_add_button(Evas_Object *window)
{
Evas_Object *button;
button = elm_button_add(window);
elm_object_text_set(button, "Click Me!");
evas_object_smart_callback_add(button, "clicked", _button_clicked, NULL);
evas_object_show(button);
}
</code>
\\
----
{{page>index}}

View File

@ -0,0 +1,5 @@
++++Event and Effect Menu|
^ [[/program_guide/event_effect_pg|Event and Effect Programming Guide]] ^^^^^^
^ Events |[[/program_guide/event_effect/evas_smart_events|Evas smart events]]|[[/program_guide/event_effect/ecore_events|Ecore events]]|[[/program_guide/event_effect/edje_events|Edje events]]|[[/program_guide/event_effect/evas_object_events|Evas object events]]|[[/program_guide/event_effect/evas_events|Evas events]]|
^ Effects |[[/program_guide/event_effect/ecore_animators|Ecore Animators]]|[[/program_guide/event_effect/elementary_transitions|Elementary Transitions]]|[[/program_guide/event_effect/edje_animations|Edje Animations]]|[[/program_guide/event_effect/evas_map_animations|Evas Map Animations]]||
++++

View File

@ -0,0 +1,119 @@
~~Title: Event and Effect PG~~
{{page>index}}
===== Event and Effect =====
EFL and Elementary allow you to manage different kinds of events and create various types
of effects and animations in your application.
=== Table of Contents ===
* [[#Handling_Events|Handling Events]]
* [[/program_guide/event_effect/evas_smart_events|Evas smart events]]: the most comon king of GUI pregramming
* [[/program_guide/event_effect/ecore_events|Ecore events]]: for system events
* [[/program_guide/event_effect/edje_events|Edje events]]: signals and messages to or from themes
* [[/program_guide/event_effect/evas_object_events|Evas object events]]: drawing- or focus-related low-level events for specific objects on a canvas
* [[/program_guide/event_effect/evas_events|Evas events]]: drawing or focus-related low-level events for a whole canvas
* [[#Creating_Animations_and_Effects|Creating Animations and Effects]]
* [[/program_guide/event_effect/ecore_animators|Ecore Animators]]
* [[/program_guide/event_effect/elementary_transitions|Elementary Transitions]]
* [[/program_guide/event_effect/edje_animations|Edje Animations]]
* [[/program_guide/event_effect/evas_map_animations|Evas Map Animations]]
==== Handling Events ====
The EFLs rely on events and callbacks. In case of an event, (for example, a
key press, mouse click or a battery running low), the mainloop calls the
callback functions that are associated to that specific event. After the
callbacks have finished, the mainloop takes over and waits for new events,
upon which to trigger new callbacks.
It is important to do light work in the callbacks and to return to the
mainloop relatively quickly. If there is heavy work to do, it is best to use
an asynchronous mechanism like Ecore_con for network I/O or threads for
CPU-intensive tasks. Failure to return quickly to the mainloop blocks the
application's UI and it appears frozen.
=== EFL Event Types ===
There are several event types in the EFLs, and their use depends on the level
of the event. The event types from lower- to higher-level are:
* [[/program_guide/event_effect/evas_smart_events|Evas smart events]] are the most often used and take place on collections of evas objects (which are most typically handled). They are called "smart" because they have internal logic and can define their own events while other event types are fixed.
* [[/program_guide/event_effect/ecore_events|Ecore events]] are the lowest-level events and come directly from the system. Except for application-wide shortcuts, it is not advisable to use them.
* [[/program_guide/event_effect/evas_object_events|Evas object events]] events concern the objects that are on the canvas.
* [[/program_guide/event_effect/evas_events|Evas events]] are events on the graphical canvas as a whole. They are fairly low-level and mostly useful when drawing directly on the canvas.
Event types in the EFLs: Inner boxes are more specific than outer ones{{ :event_effect_scope.png |Event types in the EFLs: Inner boxes are more specific than outer ones}}
<note>
There are also [[/program_guide/event_effect/edje_events|Edje signals]], which
come from program sections in themes; they can be used from high-level
Elementary APIs or a low-level Edje API.
</note>
=== Basic Event Flow ===
A realistic scenario involving various types of events is an application
showing a button, which triggers the download of a file to be processed. There
are progress bars for the operations.
Create the window, create a box, set it vertical and add a button and two
progress bars. At first, only the button is fully visible.
When the user clicks on the button, an evas smart object event named "clicked"
is emitted. The callback then starts the download in Ecore_con, displays the
first progress bar and adds a callback to monitor the download progress. When
the download progress changes, the callback updates the progress bar.
After the download is finished, the second progress bar is displayed and the
file processing is offloaded to another thread through Ecore_thread. The
processing function regularly updates the progress bar (wrapped in
''ecore_main_loop_thread_safe_call_async()'' because GUI operations are not
thread-safe).
Events enable operations taking more than a few milliseconds' time to be
executed outside of the mainloop, therefore not blocking UI redraws.
Below is an illustration for the event flow that follows a click on the
screen.
{{ :event_effect_flow.png |Event flow for a user click}}
==== Creating Animations and Effects ====
This programming guide introduces the animation functionalities provided by
the EFL: Ecore animators, Elementary transitions, Edje animations, and Evas
Map animations.
The first option for creating animations with EFL is to use
[[/program_guide/event_effect/ecore_animators|Ecore
animators]]. To create an Ecore animation, you must first determine the
duration of the animation, and then define a callback function that performs
the animation with that duration.
You can also create animations using
[[/program_guide/event_effect/elementary_transitions|Elementary transitions]].
Elementary transitions allow you to apply various transition effects, such as
translation and rotation, to Evas objects. Elementary transitions are mostly
based on Ecore animators, but provide some transition methods at a higher
level of abstraction. Elementary transitions provide a simpler way of
animating objects than Ecore animators or Edje animations.
A third option for animating objects is to use
[[/program_guide/event_effect/edje_animations|Edje animations]], which are
based on a simple principle: transitioning from one state to another. To
animate an object with Edje, you have to first define the start and end states
of the animation, and then transition the object from the start state to the
end state.
Finally, [[/program_guide/event_effect/evas_map_animations|Evas Map
animations]] allow you to apply transformations to all types of objects by way
of UV mapping. In UV mapping, you map points in the source object to 3D space
positions in the target object. This allows for rotation, perspective, scale,
and other transformation effects, depending on the map. In addition, each map
point can carry a multiplier color, which, if properly calculated, can be used
to apply 3D shading effects on the target object.
\\
----
{{page>index}}

View File

@ -2,4 +2,5 @@
* [[program_guide/basic_application_structure_pg|Basic Application structure PG]]
* [[program_guide/containers_pg|Container PG]]
* [[program_guide/widgets_pg|Widgets PG]]
* [[program_guide/event_effect_pg|Event and Effect PG]]
++++