remove comp iconify hacks (and e_iconify api), expand comp object effect api

instead of adding specific handling which will work (sometimes) in one specific case, expand already-existing api to provide the needed functionality for iconify animations. now on emitting any signal to a comp object, optional glob-able effect providers can be hooked and prioritized to add effect animations

also use animating flags now when applying an object effect

a base effect is provided in elementary, but now each module which wants to hook iconify animations (or other events) can do so in the theme and have different animations with their module
This commit is contained in:
Mike Blumenkrantz 2014-01-29 13:25:38 -05:00
parent e5bbb98918
commit 9b36b9b78c
7 changed files with 191 additions and 112 deletions

View File

@ -101,7 +101,6 @@ src/bin/e_grab_dialog.h \
src/bin/e.h \
src/bin/e_hints.h \
src/bin/e_icon.h \
src/bin/e_iconify.h \
src/bin/e_ilist.h \
src/bin/e_import_config_dialog.h \
src/bin/e_import_dialog.h \
@ -267,7 +266,6 @@ src/bin/e_grabinput.c \
src/bin/e_grab_dialog.c \
src/bin/e_hints.c \
src/bin/e_icon.c \
src/bin/e_iconify.c \
src/bin/e_ilist.c \
src/bin/e_import_config_dialog.c \
src/bin/e_import_dialog.c \

View File

@ -71,8 +71,8 @@ typedef struct _E_Comp_Object
unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
unsigned int animating; // it's busy animating
Eina_Bool delete_pending : 1; // delete pendig
Eina_Bool animating : 1; // it's busy animating - defer hides/dels
Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
Eina_Bool visible : 1; // is visible
@ -95,6 +95,17 @@ typedef struct _E_Comp_Object
Eina_Bool force_move : 1;
} E_Comp_Object;
struct E_Comp_Object_Mover
{
EINA_INLIST;
E_Comp_Object_Mover_Cb func;
const char *sig;
void *data;
int pri;
};
static Eina_Inlist *_e_comp_object_movers = NULL;
static Evas_Smart *_e_comp_smart = NULL;
/* sekrit functionzzz */
@ -498,22 +509,12 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw)
if (cw->visible || cw->ec->re_manage)
e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
else if (cw->ec->iconic)
{
e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj);
e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e");
cw->ec->layer_block = 1;
evas_object_layer_set(cw->smart_obj, E_LAYER_CLIENT_PRIO);
}
e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e");
else
e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
if (cw->ec->iconic && cw->ec->re_manage)
{
e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj);
e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e");
cw->ec->layer_block = 1;
evas_object_layer_set(cw->smart_obj, E_LAYER_CLIENT_PRIO);
}
e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e");
if (!cw->zoomap_disabled)
e_zoomap_child_set(cw->zoomobj, NULL);
if (cw->frame_object)
@ -558,20 +559,12 @@ _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *
CRI("ACK!");
if (cw->animating)
{
cw->animating = 0;
cw->animating--;
cw->comp->animating--;
if (!e_object_unref(E_OBJECT(cw->ec))) return;
}
if (cw->defer_hide &&
((!strcmp(emission, "e,action,hide,done")) ||
(!strcmp(emission, "e,action,iconify,done"))))
if (cw->defer_hide && (!strcmp(emission, "e,action,hide,done")))
evas_object_hide(cw->smart_obj);
if ((!strcmp(emission, "e,action,iconify,done")) ||
(!strcmp(emission, "e,action,uniconify,done")))
{
cw->ec->layer_block = 0;
evas_object_layer_set(cw->smart_obj, cw->ec->layer);
}
}
/////////////////////////////////////////////
@ -1150,22 +1143,20 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj)
{
if ((!cw->ec->iconic) && (!cw->ec->override) && (!cw->ec->delete_requested))
e_hints_window_hidden_set(cw->ec);
cw->defer_hide = 1;
if ((!cw->animating) || (cw->ec->iconic))
{
if (!cw->comp->animating)
cw->comp->animating++;
cw->animating = 1;
e_object_ref(E_OBJECT(cw->ec));
if (cw->ec->iconic)
{
e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj);
e_comp_object_signal_emit(obj, "e,action,iconify", "e");
cw->ec->layer_block = 1;
evas_object_layer_set(cw->smart_obj, E_LAYER_CLIENT_PRIO);
}
e_comp_object_signal_emit(obj, "e,action,iconify", "e");
else
e_comp_object_signal_emit(obj, "e,state,hidden", "e");
{
e_comp_object_signal_emit(obj, "e,state,hidden", "e");
cw->comp->animating++;
cw->animating = 1;
e_object_ref(E_OBJECT(cw->ec));
}
cw->defer_hide = cw->animating;
if (!cw->animating)
e_comp_object_effect_set(obj, NULL);
}
}
if (cw->animating) return;
@ -1184,10 +1175,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw)
{
if (cw->ec->iconic && cw->animating)
{
e_iconify_provider_obj_message(cw->ec, EINA_FALSE, cw->shobj);
e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
cw->ec->layer_block = 1;
evas_object_layer_set(cw->smart_obj, E_LAYER_CLIENT_PRIO);
cw->defer_hide = 0;
}
return;
@ -1838,18 +1826,16 @@ _e_comp_smart_show(Evas_Object *obj)
e_comp_shape_queue(cw->comp);
if (cw->ec->input_only) return;
if (cw->ec->iconic)
{
e_iconify_provider_obj_message(cw->ec, EINA_FALSE, cw->shobj);
e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
cw->ec->layer_block = 1;
evas_object_layer_set(cw->smart_obj, E_LAYER_CLIENT_PRIO);
}
e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
else
e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
{
e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
cw->comp->animating++;
cw->animating = 1;
e_object_ref(E_OBJECT(cw->ec));
}
if (!cw->animating)
cw->comp->animating++;
cw->animating = 1;
e_object_ref(E_OBJECT(cw->ec));
e_comp_object_effect_set(obj, NULL);
}
static void
@ -2702,11 +2688,18 @@ reshadow:
EAPI void
e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
{
E_Comp_Object_Mover *prov;
API_ENTRY;
//INF("EMIT %p: %s %s", cw->ec, sig, src);
edje_object_signal_emit(cw->shobj, sig, src);
if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
if (cw->frame_icon) edje_object_signal_emit(cw->frame_icon, sig, src);
EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
{
if (!e_util_glob_match(sig, prov->sig)) continue;
if (prov->func(prov->data, obj, sig)) break;
}
}
EAPI void
@ -3256,16 +3249,24 @@ e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned
}
static void
_e_comp_object_effect_end_cb(void *data EINA_UNUSED, Evas_Object *obj, const char *emission, const char *source)
_e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
{
Edje_Signal_Cb end_cb;
void *end_data;
E_Comp_Object *cw = data;
edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
if (cw->animating)
{
cw->comp->animating--;
cw->animating--;
e_object_unref(E_OBJECT(cw->ec));
}
end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
end_data = evas_object_data_get(obj, "_e_comp.end_data");
end_cb(end_data, obj, emission, source);
edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
}
EAPI void
@ -3296,11 +3297,14 @@ e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *
e_comp_object_effect_clip(obj);
edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
cw->comp->animating++;
cw->animating++;
e_object_ref(E_OBJECT(cw->ec));
}
EAPI void
@ -3314,9 +3318,44 @@ e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb EINA_UNUSED)
cw->effect_clip = 0;
}
edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
if (cw->animating)
{
cw->animating--;
cw->comp->animating--;
e_object_unref(E_OBJECT(cw->ec));
}
}
static int
_e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
{
return a->pri - b->pri;
}
EAPI E_Comp_Object_Mover *
e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
{
E_Comp_Object_Mover *prov;
prov = E_NEW(E_Comp_Object_Mover, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
prov->func = provider;
prov->data = (void*)data;
prov->pri = pri;
prov->sig = sig;
_e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
(Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
return prov;
}
EAPI void
e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
{
EINA_SAFETY_ON_NULL_RETURN(prov);
_e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
free(prov);
}
////////////////////////////////////
static void

View File

@ -3,6 +3,9 @@ typedef struct E_Comp_Object_Frame E_Comp_Object_Frame;
typedef struct E_Event_Comp_Object E_Event_Comp_Object;
typedef void (*E_Comp_Object_Autoclose_Cb)(void *, Evas_Object *);
typedef Eina_Bool (*E_Comp_Object_Key_Cb)(void *, Ecore_Event_Key *);
typedef Eina_Bool (*E_Comp_Object_Mover_Cb) (void *data, Evas_Object *comp_object, const char *signal);
typedef struct E_Comp_Object_Mover E_Comp_Object_Mover;
typedef enum
{
@ -75,6 +78,8 @@ EAPI void e_comp_object_effect_clip(Evas_Object *obj);
EAPI void e_comp_object_effect_unclip(Evas_Object *obj);
EAPI void e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data);
EAPI void e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb EINA_UNUSED);
EAPI E_Comp_Object_Mover *e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data);
EAPI void e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov);
#endif
#endif

View File

@ -154,4 +154,3 @@
#include "e_comp_cfdata.h"
#include "e_comp_canvas.h"
#include "e_utils.h"
#include "e_iconify.h"

View File

@ -30,6 +30,7 @@ typedef struct _IBar_Icon IBar_Icon;
struct _Instance
{
E_Gadcon_Client *gcc;
E_Comp_Object_Mover *iconify_provider;
IBar *ibar;
E_Drop_Handler *drop_handler;
Config_Item *ci;
@ -215,36 +216,36 @@ _ibar_order_refresh(IBar *b, const char *path)
}
static void
_ibar_cb_iconify_provider(void *data, E_Client *ec, Eina_Bool iconify EINA_UNUSED, int *x, int *y, int *w, int *h)
_ibar_cb_iconify_end_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
E_Client *ec = data;
evas_object_layer_set(ec->frame, ec->layer);
ec->layer_block = 0;
if (ec->iconic)
evas_object_hide(ec->frame);
}
static Eina_Bool
_ibar_cb_iconify_provider(void *data, Evas_Object *obj, const char *signal EINA_UNUSED)
{
Instance *inst = data;
IBar_Icon *ic;
Evas_Coord ox, oy, ow, oh;
int ox, oy, ow, oh;
E_Client *ec;
EINA_INLIST_FOREACH(inst->ibar->icons, ic)
{
E_Exec_Instance *exe;
Eina_List *l;
EINA_LIST_FOREACH(ic->exes, l, exe)
{
Eina_List *ll;
E_Client *ec2;
EINA_LIST_FOREACH(exe->clients, ll, ec2)
{
if (ec == ec2)
{
evas_object_geometry_get(ic->o_holder, &ox, &oy, &ow, &oh);
*x = ox;
*y = oy;
*w = ow;
*h = oh;
return;
}
}
}
}
ec = e_comp_object_client_get(obj);
ic = eina_hash_find(inst->ibar->icon_hash, _desktop_name_get(ec->exe_inst ? ec->exe_inst->desktop : ec->desktop));
if (!ic) return EINA_FALSE;
ec->layer_block = 1;
evas_object_layer_set(ec->frame, E_LAYER_CLIENT_PRIO);
evas_object_geometry_get(ic->o_holder, &ox, &oy, &ow, &oh);
e_comp_object_effect_set(ec->frame, "iconify/ibar");
e_comp_object_effect_params_set(ec->frame, 1, (int[]){ec->x, ec->y, ec->w, ec->h, ox, oy, ow, oh}, 8);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){!!strcmp(signal, "e,action,iconify")}, 1);
e_comp_object_effect_start(ec->frame, _ibar_cb_iconify_end_cb, ec);
return EINA_TRUE;
}
static E_Gadcon_Client *
@ -282,7 +283,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
evas_object_event_callback_add(b->o_outerbox, EVAS_CALLBACK_RESIZE,
_ibar_cb_obj_moveresize, inst);
ibar_config->instances = eina_list_append(ibar_config->instances, inst);
e_iconify_provider_add(80, _ibar_cb_iconify_provider, inst);
inst->iconify_provider = e_comp_object_effect_mover_add(80, "e,action,*iconify", _ibar_cb_iconify_provider, inst);
return gcc;
}
@ -292,7 +293,7 @@ _gc_shutdown(E_Gadcon_Client *gcc)
Instance *inst;
inst = gcc->data;
e_iconify_provider_del(80, _ibar_cb_iconify_provider, inst);
e_comp_object_effect_mover_del(inst->iconify_provider);
ibar_config->instances = eina_list_remove(ibar_config->instances, inst);
e_drop_handler_del(inst->drop_handler);
_ibar_free(inst->ibar);

View File

@ -31,6 +31,7 @@ typedef struct _IBox_Icon IBox_Icon;
struct _Instance
{
E_Gadcon_Client *gcc;
E_Comp_Object_Mover *iconify_provider;
Evas_Object *o_ibox;
IBox *ibox;
E_Drop_Handler *drop_handler;
@ -117,32 +118,52 @@ static E_Config_DD *conf_item_edd = NULL;
Config *ibox_config = NULL;
static void
_ibox_cb_iconify_provider(void *data, E_Client *ec, Eina_Bool iconify EINA_UNUSED, int *x, int *y, int *w, int *h)
_ibox_cb_iconify_end_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
E_Client *ec = data;
evas_object_layer_set(ec->frame, ec->layer);
ec->layer_block = 0;
if (ec->iconic)
evas_object_hide(ec->frame);
}
static Eina_Bool
_ibox_cb_iconify_provider(void *data, Evas_Object *obj, const char *signal)
{
Instance *inst = data;
IBox_Icon *ic;
Evas_Coord ox, oy, ow, oh;
Eina_List *l;
EINA_LIST_FOREACH(inst->ibox->icons, l, ic)
E_Client *ec;
ec = e_comp_object_client_get(obj);
if (!strcmp(signal, "e,action,uniconify"))
{
if (ic->client == ec)
EINA_LIST_FOREACH(inst->ibox->icons, l, ic)
{
evas_object_geometry_get(ic->o_holder, &ox, &oy, &ow, &oh);
*x = ox;
*y = oy;
*w = ow;
*h = oh;
return;
if (ic->client == ec)
{
evas_object_geometry_get(ic->o_holder, &ox, &oy, &ow, &oh);
break;
}
}
}
// XXX: ibox doesn't know yet where a new icon might go... so assume right
// edge of ibox
evas_object_geometry_get(inst->ibox->o_box, &ox, &oy, &ow, &oh);
*x = ox + ow - 1;
*y = oy + (oh / 2);
*w = 1;
*h = 1;
else
{
// XXX: ibox doesn't know yet where a new icon might go... so assume right
// edge of ibox
evas_object_geometry_get(inst->ibox->o_box, &ox, &oy, &ow, &oh);
ox += ow - 1;
oy += (oh / 2);
}
ec->layer_block = 1;
evas_object_layer_set(ec->frame, E_LAYER_CLIENT_PRIO);
e_comp_object_effect_set(ec->frame, "iconify/ibox");
e_comp_object_effect_params_set(ec->frame, 1, (int[]){ec->x, ec->y, ec->w, ec->h, ox, oy, ow, oh}, 8);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){!!strcmp(signal, "e,action,iconify")}, 1);
e_comp_object_effect_start(ec->frame, _ibox_cb_iconify_end_cb, ec);
return EINA_TRUE;
}
static E_Gadcon_Client *
@ -187,7 +208,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
ibox_config->instances = eina_list_append(ibox_config->instances, inst);
// add highest priority iconify provider - tasks and ibar can do this
// but lower priority
e_iconify_provider_add(100, _ibox_cb_iconify_provider, inst);
inst->iconify_provider = e_comp_object_effect_mover_add(100, "e,action,*iconify", _ibox_cb_iconify_provider, inst);
return gcc;
}
@ -197,7 +218,7 @@ _gc_shutdown(E_Gadcon_Client *gcc)
Instance *inst;
inst = gcc->data;
e_iconify_provider_del(100, _ibox_cb_iconify_provider, inst);
e_comp_object_effect_mover_del(inst->iconify_provider);
inst->ci->gcc = NULL;
ibox_config->instances = eina_list_remove(ibox_config->instances, inst);
e_drop_handler_del(inst->drop_handler);

View File

@ -32,6 +32,7 @@ typedef struct _Tasks_Item Tasks_Item;
struct _Tasks
{
E_Gadcon_Client *gcc; // The gadcon client
E_Comp_Object_Mover *iconify_provider;
Evas_Object *o_items; // Table of items
Eina_List *items; // List of items
Eina_List *clients; // List of clients
@ -325,27 +326,42 @@ _gc_id_new(const E_Gadcon_Client_Class *client_class __UNUSED__)
}
/***************************************************************************/
static void
_tasks_cb_iconify_provider(void *data, E_Client *ec, Eina_Bool iconify EINA_UNUSED, int *x, int *y, int *w, int *h)
_tasks_cb_iconify_end_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
E_Client *ec = data;
evas_object_layer_set(ec->frame, ec->layer);
ec->layer_block = 0;
if (ec->iconic)
evas_object_hide(ec->frame);
}
static Eina_Bool
_tasks_cb_iconify_provider(void *data, Evas_Object *obj, const char *signal)
{
Tasks *tasks = data;
Tasks_Item *item;
Evas_Coord ox, oy, ow, oh;
Eina_List *l;
E_Client *ec;
ec = e_comp_object_client_get(obj);
EINA_LIST_FOREACH(tasks->items, l, item)
{
if (item->client == ec)
{
evas_object_geometry_get(item->o_item, &ox, &oy, &ow, &oh);
*x = ox;
*y = oy;
*w = ow;
*h = oh;
return;
ec->layer_block = 1;
evas_object_layer_set(ec->frame, E_LAYER_CLIENT_PRIO);
e_comp_object_effect_set(ec->frame, "iconify/tasks");
e_comp_object_effect_params_set(ec->frame, 1, (int[]){ec->x, ec->y, ec->w, ec->h, ox, oy, ow, oh}, 8);
e_comp_object_effect_params_set(ec->frame, 0, (int[]){!!strcmp(signal, "e,action,iconify")}, 1);
e_comp_object_effect_start(ec->frame, _tasks_cb_iconify_end_cb, ec);
return EINA_TRUE;
}
}
return EINA_FALSE;
}
static Tasks *
@ -369,7 +385,7 @@ _tasks_new(Evas *evas, E_Zone *zone, const char *id)
e_box_orientation_set(tasks->o_items, tasks->horizontal);
e_box_align_set(tasks->o_items, 0.5, 0.5);
tasks->zone = zone;
e_iconify_provider_add(90, _tasks_cb_iconify_provider, tasks);
tasks->iconify_provider = e_comp_object_effect_mover_add(90, "e,action,*iconify", _tasks_cb_iconify_provider, tasks);
return tasks;
}
@ -377,7 +393,7 @@ static void
_tasks_free(Tasks *tasks)
{
Tasks_Item *item;
e_iconify_provider_del(90, _tasks_cb_iconify_provider, tasks);
e_comp_object_effect_mover_del(tasks->iconify_provider);
EINA_LIST_FREE(tasks->items, item)
_tasks_item_free(item);
eina_list_free(tasks->clients);