enlightenment/src/bin/e_gadcon.c

5791 lines
182 KiB
C
Raw Normal View History

#include "e.h"
/*
* TODO: gadcon client ordering on drop
*/
#define E_LAYOUT_ITEM_DRAG_RESIST_LEVEL 10
static void _e_gadcon_event_populate(E_Gadcon *gc);
static Eina_Bool _e_gadcon_client_populate(E_Gadcon *gc, const E_Gadcon_Client_Class *cc, E_Config_Gadcon_Client *cf_gcc);
static void _e_gadcon_client_unpopulate(E_Gadcon_Client *gcc);
2012-06-20 05:43:15 -07:00
static void _e_gadcon_free(E_Gadcon *gc);
static void _e_gadcon_client_free(E_Gadcon_Client *gcc);
static void _e_gadcon_moveresize_handle(E_Gadcon_Client *gcc);
static Eina_Bool _e_gadcon_cb_client_scroll_timer(void *data);
static Eina_Bool _e_gadcon_cb_client_scroll_animator(void *data);
static void _e_gadcon_cb_client_frame_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_client_frame_moveresize(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_save(E_Gadcon_Client *gcc);
static void _e_gadcon_client_drag_begin(E_Gadcon_Client *gcc, int x, int y);
static void _e_gadcon_client_inject(E_Gadcon *gc, E_Gadcon_Client *gcc, int x, int y);
static void _e_gadcon_cb_min_size_request(void *data, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_size_request(void *data, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_moveresize(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_parent_resize_cb(E_Gadcon *gc, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
2012-06-20 05:43:15 -07:00
static void _e_gadcon_cb_client_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_client_mouse_in(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_client_mouse_out(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_client_move(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_cb_client_resize(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_move_start(E_Gadcon_Client *gcc);
static void _e_gadcon_client_move_stop(E_Gadcon_Client *gcc);
static void _e_gadcon_client_move_go(E_Gadcon_Client *gcc);
static void _e_gadcon_cb_signal_move_start(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_move_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_move_go(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_left_start(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_left_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_left_go(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_right_start(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_right_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_signal_resize_right_go(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _e_gadcon_cb_dnd_enter(void *data, const char *type, void *event);
static void _e_gadcon_cb_dnd_move(void *data, const char *type, void *event);
static void _e_gadcon_cb_dnd_leave(void *data, const char *type, void *event);
static void _e_gadcon_cb_dnd_drop(void *data, const char *type, void *event);
2012-06-20 05:43:15 -07:00
static int _e_gadcon_client_class_feature_check(const E_Gadcon_Client_Class *cc, const char *name, void *feature);
static void _e_gadcon_client_cb_menu_post(void *data, E_Menu *m);
static void _e_gadcon_client_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_cb_menu_style_plain(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_gadcon_client_cb_menu_style_inset(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_gadcon_client_cb_menu_autoscroll(void *data, E_Menu *m, E_Menu_Item *mi);
/*static void _e_gadcon_client_cb_menu_resizable(void *data, E_Menu *m, E_Menu_Item *mi);*/
2012-06-20 05:43:15 -07:00
static void _e_gadcon_client_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_gadcon_client_cb_menu_remove(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_gadcon_client_cb_menu_pre(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_gadcon_client_delfn(void *d, void *o);
2012-06-20 05:43:15 -07:00
static void _e_gadcon_client_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_client_event_free(void *d, void *e);
2012-06-20 05:43:15 -07:00
static Evas_Object *e_gadcon_layout_add(Evas *evas);
static void e_gadcon_layout_orientation_set(Evas_Object *obj, int horizontal);
static int e_gadcon_layout_orientation_get(Evas_Object *obj);
static void e_gadcon_layout_freeze(Evas_Object *obj);
static void e_gadcon_layout_thaw(Evas_Object *obj);
static void e_gadcon_layout_min_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
static void e_gadcon_layout_asked_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
static int e_gadcon_layout_pack(Evas_Object *obj, Evas_Object *child);
static void e_gadcon_layout_pack_size_set(Evas_Object *obj, int size);
static void e_gadcon_layout_pack_request_set(Evas_Object *obj, int pos, int size);
static void e_gadcon_layout_pack_options_set(Evas_Object *obj, E_Gadcon_Client *gcc);
static void e_gadcon_layout_pack_min_size_set(Evas_Object *obj, int w, int h);
static void e_gadcon_layout_pack_aspect_set(Evas_Object *obj, int w, int h);
static void e_gadcon_layout_pack_aspect_pad_set(Evas_Object *obj, int w, int h);
static void e_gadcon_layout_unpack(Evas_Object *obj);
static void _e_gadcon_provider_populate_request(E_Gadcon *gc, const E_Gadcon_Client_Class *cc);
2012-06-20 05:43:15 -07:00
static void _e_gadcon_provider_populate_unrequest(const E_Gadcon_Client_Class *cc);
static void _e_gadcon_provider_populate_job(void *data);
static void _e_gadcon_event_populate_free(void *data __UNUSED__, void *event);
static void _e_gadcon_custom_populate_job(void *data);
2012-06-20 05:43:15 -07:00
static int _e_gadcon_location_change(E_Gadcon_Client *gcc, E_Gadcon_Location *src, E_Gadcon_Location *dst);
typedef struct _E_Smart_Data E_Smart_Data;
typedef struct _E_Layout_Item_Container E_Layout_Item_Container;
2012-06-20 05:43:15 -07:00
static void _e_gadcon_client_current_position_sync(E_Gadcon_Client *gcc);
static void _e_gadcon_layout_smart_sync_clients(E_Gadcon *gc);
static void _e_gadcon_layout_smart_gadcon_position_shrinked_mode(E_Smart_Data *sd);
static void _e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd);
static Eina_List *_e_gadcon_layout_smart_gadcons_wrap(E_Smart_Data *sd);
static void _e_gadcon_layout_smart_gadcons_position(E_Smart_Data *sd, Eina_List **list);
static void _e_gadcon_layout_smart_gadcons_position_static(E_Smart_Data *sd, Eina_List **list);
static E_Layout_Item_Container *_e_gadcon_layout_smart_containers_position_adjust(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2);
static void _e_gadcon_layout_smart_position_items_inside_container(E_Smart_Data *sd, E_Layout_Item_Container *lc);
static void _e_gadcon_layout_smart_containers_merge(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2);
static void _e_gadcon_layout_smart_restore_gadcons_position_before_move(E_Smart_Data *sd, E_Layout_Item_Container **lc_moving, E_Layout_Item_Container *lc_back, Eina_List **con_list);
typedef enum _E_Gadcon_Layout_Item_State
{
E_LAYOUT_ITEM_STATE_NONE,
E_LAYOUT_ITEM_STATE_POS_INC,
E_LAYOUT_ITEM_STATE_POS_DEC,
E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC,
E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC,
E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC,
E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC,
} E_Gadcon_Layout_Item_State;
typedef enum _E_Gadcon_Layout_Item_Flags
{
2012-06-20 05:43:15 -07:00
E_GADCON_LAYOUT_ITEM_LOCK_NONE = 0x00000000,
E_GADCON_LAYOUT_ITEM_LOCK_POSITION = 0x00000001,
E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE = 0x00000002
} E_Gadcon_Layout_Item_Flags;
typedef enum _E_Layout_Item_Container_State
{
2012-06-20 05:43:15 -07:00
E_LAYOUT_ITEM_CONTAINER_STATE_NONE,
E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC,
E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC,
E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC,
E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC,
E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC,
E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC,
E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED
} E_Layout_Item_Container_State;
struct _E_Layout_Item_Container
{
2012-06-20 05:43:15 -07:00
int pos, size, prev_pos, prev_size;
2012-06-20 05:43:15 -07:00
struct
{
int min_seq, max_seq;
} state_info;
2012-06-20 05:43:15 -07:00
E_Smart_Data *sd;
Eina_List *items;
E_Layout_Item_Container_State state;
};
2012-06-20 05:43:15 -07:00
#define LC_FREE(__lc) \
if (__lc->items) \
eina_list_free(__lc->items); \
E_FREE(__lc)
#define E_LAYOUT_ITEM_CONTAINER_STATE_SET(__con_state, __bi_state) \
2012-06-20 05:43:15 -07:00
if (__bi_state == E_LAYOUT_ITEM_STATE_NONE) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_POS_INC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_POS_DEC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC; \
else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC) \
__con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC
#define LC_OVERLAP(__lc, __lc2) \
((((__lc2)->pos >= (__lc)->pos) && ((__lc2)->pos < ((__lc)->pos + (__lc)->size))) || \
(((__lc)->pos >= (__lc2)->pos) && ((__lc)->pos < ((__lc2)->pos + (__lc2)->size))))
#define E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(__lc, __bi, __increase) \
2012-06-20 05:43:15 -07:00
{ \
if (__increase) \
__lc->size += __bi->w; \
else \
__lc->size -= __bi->w; \
}
/********************/
EAPI int E_EVENT_GADCON_CLIENT_CLASS_ADD = -1;
EAPI int E_EVENT_GADCON_CLIENT_CLASS_DEL = -1;
EAPI int E_EVENT_GADCON_CLIENT_ADD = -1;
EAPI int E_EVENT_GADCON_CLIENT_DEL = -1;
EAPI int E_EVENT_GADCON_POPULATE = -1;
static Eina_Hash *providers = NULL;
static Eina_List *providers_list = NULL;
static Eina_List *gadcons = NULL;
static Eina_List *dummies = NULL;
static Ecore_Job *populate_job = NULL;
static Eina_List *custom_populate_requests = NULL;
static Ecore_Job *custom_populate_job = NULL;
2009-08-31 04:23:03 -07:00
static Eina_List *gadcon_locations = NULL;
static Ecore_Event_Handler *_module_init_end_handler = NULL;
static Eina_Bool _modules_loaded = EINA_FALSE;
static inline void
_eina_list_free(Eina_List *l)
{
eina_list_free(l);
}
static int
_e_gadcon_provider_list_sort_cb(E_Gadcon_Client_Class *a, E_Gadcon_Client_Class *b)
{
return strcasecmp(a->name, b->name);
}
static Eina_Bool
_module_init_end_cb(void *d __UNUSED__, int type __UNUSED__, void *ev __UNUSED__)
{
_modules_loaded = EINA_TRUE;
return ECORE_CALLBACK_RENEW;
}
/* externally accessible functions */
EINTERN int
e_gadcon_init(void)
{
E_EVENT_GADCON_CLIENT_CLASS_ADD = ecore_event_type_new();
E_EVENT_GADCON_CLIENT_CLASS_DEL = ecore_event_type_new();
E_EVENT_GADCON_CLIENT_ADD = ecore_event_type_new();
E_EVENT_GADCON_CLIENT_DEL = ecore_event_type_new();
E_EVENT_GADCON_POPULATE = ecore_event_type_new();
_module_init_end_handler = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _module_init_end_cb, NULL);
return 1;
}
EINTERN int
e_gadcon_shutdown(void)
{
if (populate_job)
{
ecore_job_del(populate_job);
populate_job = NULL;
}
custom_populate_requests = eina_list_free(custom_populate_requests);
if (custom_populate_job)
{
ecore_job_del(custom_populate_job);
custom_populate_job = NULL;
}
_modules_loaded = EINA_FALSE;
if (_module_init_end_handler)
ecore_event_handler_del(_module_init_end_handler);
_module_init_end_handler = NULL;
return 1;
}
/**
* Registers a new gadget class in e
*
* @param cc version of gadcon, name and callbacks to use
* for handling creation and destroying a gadget
*/
EAPI void
e_gadcon_provider_register(const E_Gadcon_Client_Class *cc)
{
E_Gadcon *gc;
Eina_List *l, *ll, *lll;
E_Config_Gadcon_Client *cf_gcc;
EINA_SAFETY_ON_NULL_RETURN(cc->name);
if (!providers) providers = eina_hash_string_superfast_new(NULL);
eina_hash_direct_add(providers, cc->name, cc);
EINA_LIST_FOREACH(gadcons, l, gc)
{
e_gadcon_layout_freeze(gc->o_container);
if (gc->awaiting_classes)
{
ll = eina_hash_find(gc->awaiting_classes, cc->name);
EINA_LIST_FOREACH(ll, lll, cf_gcc)
_e_gadcon_client_populate(gc, cc, cf_gcc);
}
e_gadcon_layout_thaw(gc->o_container);
}
providers_list = eina_list_sorted_insert(providers_list, (Eina_Compare_Cb)_e_gadcon_provider_list_sort_cb, cc);
{
E_Event_Gadcon_Client_Class_Add *ev;
ev = E_NEW(E_Event_Gadcon_Client_Class_Add, 1);
ev->cc = cc;
ecore_event_add(E_EVENT_GADCON_CLIENT_CLASS_ADD, ev, NULL, NULL);
}
}
/**
* unregisters a gadget class in e
*
* @param cc the gadget class that was used to register the gadget
*/
EAPI void
e_gadcon_provider_unregister(const E_Gadcon_Client_Class *cc)
{
Eina_List *l, *ll, *dlist = NULL;
E_Gadcon *gc;
E_Gadcon_Client *gcc;
_e_gadcon_provider_populate_unrequest(cc);
EINA_LIST_FOREACH(gadcons, l, gc)
{
2012-06-20 05:43:15 -07:00
EINA_LIST_FOREACH(gc->clients, ll, gcc)
{
if (gcc->client_class == cc)
dlist = eina_list_append(dlist, gcc);
}
gc->populated_classes = eina_list_remove(gc->populated_classes, cc);
}
EINA_LIST_FREE(dlist, gcc)
{
e_gadcon_client_queue(gcc->gadcon, gcc->cf);
gcc->hidden = 0;
e_gadcon_client_hide(gcc);
e_object_del(E_OBJECT(gcc));
}
eina_hash_del(providers, cc->name, cc);
providers_list = eina_list_remove(providers_list, cc);
{
E_Event_Gadcon_Client_Class_Add *ev;
ev = E_NEW(E_Event_Gadcon_Client_Class_Add, 1);
ev->cc = cc;
ecore_event_add(E_EVENT_GADCON_CLIENT_CLASS_DEL, ev, NULL, NULL);
}
}
EAPI void
e_gadcon_client_queue(E_Gadcon *gc, E_Config_Gadcon_Client *cf_gcc)
{
Eina_List *l;
if (!gc->awaiting_classes)
gc->awaiting_classes = eina_hash_string_superfast_new((Eina_Free_Cb)_eina_list_free);
l = eina_hash_find(gc->awaiting_classes, cf_gcc->name);
if (eina_list_data_find(l, cf_gcc)) return;
l = eina_list_append(l, cf_gcc);
eina_hash_set(gc->awaiting_classes, cf_gcc->name, l);
}
EAPI Eina_List *
e_gadcon_provider_list(void)
{
return providers_list;
}
EAPI void
e_gadcon_custom_new(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gadcons = eina_list_append(gadcons, gc);
if (!custom_populate_job)
{
custom_populate_job =
ecore_job_add(_e_gadcon_custom_populate_job, NULL);
}
if (!eina_list_data_find(custom_populate_requests, gc))
custom_populate_requests = eina_list_append(custom_populate_requests, gc);
gc->custom = EINA_TRUE;
}
EAPI void
e_gadcon_custom_del(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (eina_list_data_find(custom_populate_requests, gc))
custom_populate_requests = eina_list_remove(custom_populate_requests, gc);
gadcons = eina_list_remove(gadcons, gc);
}
EAPI void
e_gadcon_custom_populate_request(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (!gc->custom) return;
if (!custom_populate_job)
{
custom_populate_job =
ecore_job_add(_e_gadcon_custom_populate_job, NULL);
}
if (!eina_list_data_find(custom_populate_requests, gc))
custom_populate_requests = eina_list_append(custom_populate_requests, gc);
}
EAPI E_Gadcon *
e_gadcon_dummy_new(int id)
{
E_Gadcon *gc;
gc = E_OBJECT_ALLOC(E_Gadcon, E_GADCON_DUMMY_TYPE, _e_gadcon_free);
if (!gc) return NULL;
gc->id = id;
gc->layout_policy = E_GADCON_LAYOUT_POLICY_PANEL;
gc->location = NULL;
gc->dummy = 1;
gc->orient = E_GADCON_ORIENT_HORIZ;
dummies = eina_list_append(dummies, gc);
return gc;
}
EAPI void
e_gadcon_config_del(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->cfg_delete = 1;
}
EAPI void
e_gadcon_drop_handler_add(E_Gadcon *gc, E_Gadcon_DND_Cb enter, E_Gadcon_DND_Cb leave, E_Gadcon_DND_Cb move, E_Gadcon_DND_Cb drop, int x, int y, int w, int h)
{
const char *drop_types[] = { "enlightenment/gadcon_client" };
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->drop_handler) return;
gc->drop_handler =
e_drop_handler_add(E_OBJECT(gc), gc,
_e_gadcon_cb_dnd_enter, _e_gadcon_cb_dnd_move,
_e_gadcon_cb_dnd_leave, _e_gadcon_cb_dnd_drop,
drop_types, 1, x, y, w, h);
gc->dnd_enter_cb = enter;
gc->dnd_leave_cb = leave;
gc->dnd_move_cb = move;
gc->dnd_drop_cb = drop;
}
EAPI E_Gadcon *
e_gadcon_swallowed_new(const char *name, int id, Evas_Object *obj, const char *swallow_name)
{
E_Gadcon *gc;
E_Config_Gadcon *cf_gc;
Eina_List *l;
Evas_Coord x, y, w, h;
gc = E_OBJECT_ALLOC(E_Gadcon, E_GADCON_TYPE, _e_gadcon_free);
if (!gc) return NULL;
gc->name = eina_stringshare_add(name);
gc->id = id;
gc->layout_policy = E_GADCON_LAYOUT_POLICY_PANEL;
2009-08-31 04:23:03 -07:00
gc->location = NULL;
gc->edje.o_parent = obj;
gc->edje.swallow_name = eina_stringshare_add(swallow_name);
gc->orient = E_GADCON_ORIENT_HORIZ;
gc->evas = evas_object_evas_get(obj);
gc->o_container = e_gadcon_layout_add(gc->evas);
evas_object_geometry_get(gc->o_container, &x, &y, &w, &h);
e_gadcon_drop_handler_add(gc, NULL, NULL, NULL, NULL, x, y, w, h);
evas_object_event_callback_add(gc->o_container, EVAS_CALLBACK_MOVE,
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_moveresize, gc);
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
(Evas_Object_Event_Cb)_e_gadcon_parent_resize_cb, gc);
evas_object_event_callback_add(gc->o_container, EVAS_CALLBACK_RESIZE,
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_moveresize, gc);
evas_object_smart_callback_add(gc->o_container, "size_request",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_size_request, gc);
evas_object_smart_callback_add(gc->o_container, "min_size_request",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_min_size_request, gc);
evas_object_show(gc->o_container);
edje_object_part_swallow(gc->edje.o_parent, gc->edje.swallow_name,
2012-06-20 05:43:15 -07:00
gc->o_container);
gadcons = eina_list_append(gadcons, gc);
EINA_LIST_FOREACH(e_config->gadcons, l, cf_gc)
{
2012-06-20 05:43:15 -07:00
if ((!strcmp(cf_gc->name, gc->name)) && (cf_gc->id == gc->id))
{
gc->cf = cf_gc;
break;
}
}
if (!gc->cf)
{
2012-06-20 05:43:15 -07:00
gc->cf = E_NEW(E_Config_Gadcon, 1);
gc->cf->name = eina_stringshare_add(gc->name);
gc->cf->id = gc->id;
e_config->gadcons = eina_list_append(e_config->gadcons, gc->cf);
e_config_save_queue();
}
return gc;
}
EAPI void
e_gadcon_swallowed_min_size_set(E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->edje.o_parent)
{
evas_object_size_hint_min_set(gc->o_container, w, h);
2012-06-20 05:43:15 -07:00
edje_object_part_swallow(gc->edje.o_parent, gc->edje.swallow_name,
gc->o_container);
}
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_min_size_request_callback_set(E_Gadcon *gc, void (*func)(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->min_size_request.func = func;
gc->min_size_request.data = data;
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_size_request_callback_set(E_Gadcon *gc, void (*func)(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->resize_request.func = func;
gc->resize_request.data = data;
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_frame_request_callback_set(E_Gadcon *gc, Evas_Object *(*func)(void *data, E_Gadcon_Client * gcc, const char *style), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->frame_request.func = func;
gc->frame_request.data = data;
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_populate_callback_set(E_Gadcon *gc, void (*func)(void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->populate_class.func = func;
gc->populate_class.data = data;
}
EAPI void
e_gadcon_layout_policy_set(E_Gadcon *gc, E_Gadcon_Layout_Policy layout_policy)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->layout_policy == layout_policy) return;
gc->layout_policy = layout_policy;
/* FIXME: delete container obj, re-pack all clients */
}
EAPI Eina_Bool
e_gadcon_populate(E_Gadcon *gc)
{
Eina_List *l;
E_Config_Gadcon_Client *cf_gcc;
E_OBJECT_CHECK_RETURN(gc, EINA_FALSE);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, EINA_FALSE);
e_gadcon_layout_freeze(gc->o_container);
EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
{
2012-06-20 05:43:15 -07:00
E_Gadcon_Client_Class *cc;
2012-06-20 05:43:15 -07:00
if (!cf_gcc->name) continue;
cc = eina_hash_find(providers, cf_gcc->name);
if (cc)
{
if (!eina_list_data_find(gc->populated_classes, cc))
{
_e_gadcon_provider_populate_request(gc, cc);
cc = NULL;
}
}
2012-06-20 05:43:15 -07:00
if (cc)
_e_gadcon_client_populate(gc, cc, cf_gcc);
else
e_gadcon_client_queue(gc, cf_gcc);
}
e_gadcon_layout_thaw(gc->o_container);
if (gc->populated_classes && (!gc->populate_requests))
_e_gadcon_event_populate(gc);
return EINA_TRUE;
}
EAPI void
e_gadcon_unpopulate(E_Gadcon *gc)
{
E_Gadcon_Client *gcc;
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
Fix common misspellings Some misspellings were manually reverted since in E there are tons of .po with phrases in other languages. Other than that all the changes in the following files were reverted: * src/modules/illume/dicts/English_(US).dic * src/modules/illume-keyboard/dicts/English_(US).dic Following misspellings were fixed: acquited->acquitted adres->address adress->address alreayd->already aquire->acquire arbitarily->arbitrarily cant->can't Capetown->Cape carefull->careful causalities->casualties Celcius->Celsius certian->certain commandoes->commandos considerd->considered conveyer->conveyor dependant->dependent didnt->didn't discontentment->discontent doesnt->doesn't everytime->every exemple->example existance->existence existant->existent existince->existence Farenheit->Fahrenheit forbad->forbade funguses->fungi guage->gauge guerilla->guerrilla guerillas->guerrillas happend->happened hasnt->hasn't heros->heroes inbetween->between independant->independent inital->initial intrusted->entrusted irregardless->regardless isnt->isn't knifes->knives layed->laid loosing->losing marrage->marriage midwifes->midwives miniscule->minuscule monickers->monikers mroe->more noone->no one occured->occurred omre->more paralell->parallel payed->paid planed->planned quitted->quit quizes->quizzes seperated->separated seperate->separate shoudl->should similiar->similar simplier->simpler specifiying->specifying teh->the toke->took torpedos->torpedoes Tuscon->Tucson unecessary->unnecessary useage->usage usefull->useful useing->using waht->what wanna->want whith->with wich->which withing->within SVN revision: 52006
2010-09-08 16:59:07 -07:00
/* Be careful, e_object_del does remove gcc from gc->clients */
if (gc->o_container) e_gadcon_layout_freeze(gc->o_container);
while (gc->clients)
{
2012-06-20 05:43:15 -07:00
gcc = eina_list_data_get(gc->clients);
_e_gadcon_client_unpopulate(gcc);
/* FIXME: this seems to happen under some rare and as-yet
* undetermined circumstances in gadman
*/
if (gcc != eina_list_data_get(gc->clients)) continue;
CRI("DANGLING GADCON CLIENT %p! THIS IS A BUG!!!", gcc);
e_object_unref(E_OBJECT(gcc));
}
if (gc->awaiting_classes)
eina_hash_free(gc->awaiting_classes);
gc->awaiting_classes = NULL;
if (gc->o_container && (!stopping)) e_gadcon_layout_thaw(gc->o_container);
}
EAPI void
e_gadcon_repopulate(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->o_container) e_gadcon_layout_freeze(gc->o_container);
e_gadcon_unpopulate(gc);
e_gadcon_populate(gc);
if (gc->o_container) e_gadcon_layout_thaw(gc->o_container);
}
EAPI void
e_gadcon_populate_class(E_Gadcon *gc, const E_Gadcon_Client_Class *cc)
{
Eina_List *l;
E_Config_Gadcon_Client *cf_gcc;
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
e_gadcon_layout_freeze(gc->o_container);
EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
{
if (cf_gcc->name && (!strcmp(cf_gcc->name, cc->name)) &&
2012-06-20 05:43:15 -07:00
(cf_gcc->id) && (cf_gcc->style))
_e_gadcon_client_populate(gc, cc, cf_gcc);
}
e_gadcon_layout_thaw(gc->o_container);
}
EAPI void
e_gadcon_orient(E_Gadcon *gc, E_Gadcon_Orient orient)
{
Eina_List *l;
E_Gadcon_Client *gcc;
int horiz = 0;
E_OBJECT_CHECK(gc);
E_OBJECT_IF_NOT_TYPE(gc, E_GADCON_DUMMY_TYPE)
{
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
}
if (gc->orient == orient) return;
gc->orient = orient;
if (gc->dummy) return;
e_gadcon_layout_freeze(gc->o_container);
switch (gc->orient)
{
case E_GADCON_ORIENT_FLOAT:
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
2012-06-20 05:43:15 -07:00
horiz = 1;
break;
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
2012-06-20 05:43:15 -07:00
horiz = 0;
break;
default:
2012-06-20 05:43:15 -07:00
break;
}
e_gadcon_layout_orientation_set(gc->o_container, horiz);
EINA_LIST_FOREACH(gc->clients, l, gcc)
{
elm_box_horizontal_set(gcc->o_box, horiz);
2012-06-20 05:43:15 -07:00
if (gcc->client_class->func.orient)
gcc->client_class->func.orient(gcc, gc->orient);
}
e_gadcon_layout_thaw(gc->o_container);
}
EAPI void
e_gadcon_edit_begin(E_Gadcon *gc)
{
Eina_List *l;
E_Gadcon_Client *gcc;
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
e_gadcon_layout_freeze(gc->o_container);
e_gadcon_locked_set(gc, 1);
gc->editing = 1;
EINA_LIST_FOREACH(gc->clients, l, gcc)
e_gadcon_client_edit_begin(gcc);
e_gadcon_layout_thaw(gc->o_container);
}
EAPI void
e_gadcon_edit_end(E_Gadcon *gc)
{
Eina_List *l;
E_Gadcon_Client *gcc;
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
e_gadcon_layout_freeze(gc->o_container);
gc->editing = 0;
EINA_LIST_FOREACH(gc->clients, l, gcc)
e_gadcon_client_edit_end(gcc);
e_gadcon_layout_thaw(gc->o_container);
e_gadcon_locked_set(gc, 0);
}
EAPI void
e_gadcon_all_edit_begin(void)
{
Eina_List *l;
E_Gadcon *gc;
EINA_LIST_FOREACH(gadcons, l, gc)
e_gadcon_edit_begin(gc);
}
EAPI void
e_gadcon_all_edit_end(void)
{
Eina_List *l;
E_Gadcon *gc;
EINA_LIST_FOREACH(gadcons, l, gc)
e_gadcon_edit_end(gc);
}
EAPI void
e_gadcon_zone_set(E_Gadcon *gc, E_Zone *zone)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->zone = zone;
if (gc->cf) gc->cf->zone = zone->num;
}
EAPI E_Zone *
e_gadcon_zone_get(E_Gadcon *gc)
{
E_OBJECT_CHECK_RETURN(gc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
if (gc->zone) return gc->zone;
if (!gc->toolbar) return NULL;
return e_win_client_get(gc->toolbar->fwin)->zone;
}
EAPI void
e_gadcon_ecore_evas_set(E_Gadcon *gc, Ecore_Evas *ee)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->ecore_evas = ee;
}
EAPI int
e_gadcon_canvas_zone_geometry_get(E_Gadcon *gc, int *x, int *y, int *w, int *h)
{
E_OBJECT_CHECK_RETURN(gc, 0);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0);
if (!gc->ecore_evas) return 0;
ecore_evas_geometry_get(gc->ecore_evas, x, y, w, h);
compositor rewrite / charlie-foxtrot situation huge fustercluck commit because there wasn't really a way to separate out the changes. better to just rip it all out at once. * compositor and window management completely rewritten. this was the goal for E19, but it pretty much required everything existing to be scrapped since it wasn't optimized, streamlined, or sensible. now instead of having the compositor strapped to the window manager like an outboard motor, it's housed more like an automobile engine. ** various comp structs have been merged into other places (eg. E_Comp_Zone is now just part of E_Zone where applicable), leading to a large deduplication of attributes ** awful E_Comp_Win is totally dead, having been replaced with e_comp_object smart objects which work just like normal canvas objects ** protocol-specific window management and compositor functionality is now kept exclusively in backend files ** e_pixmap api provides generic client finding and rendering api ** screen/xinerama screens are now provided directly by compositor on startup and re-set on change ** e_comp_render_update finally replaced with eina_tiler ** wayland compositor no longer creates X windows ** compositor e_layout removed entirely * e_container is gone. this was made unnecessary in E18, but I kept it to avoid having too much code churn in one release. its sole purpose was to catch some events and handle window stacking, both of which are now just done by the compositor infra * e_manager is just for screensaver and keybind stuff now, possibly remove later? * e_border is gone along with a lot of its api. e_client has replaced it, and e_client has been rewritten completely; some parts may be similar, but the design now relies upon having a functional compositor ** window configuration/focus functions are all removed. all windows are now managed solely with evas_object_X functions on the "frame" member of a client, just as any other canvas object can be managed. *** do NOT set interceptors on a client's comp_object. seriously. * startup order rewritten: compositor now starts much earlier, other things just use attrs and members of the compositor * ecore_x_pointer_xy_get usage replaced with ecore_evas_pointer_xy_get * e_popup is totally gone, existing usage replaced by e_comp_object_util_add where applicable, otherwise just placed normally on the canvas * deskmirror is (more) broken for now * illume is totally fucked * Ecore_X_Window replaced with Ecore_Window in most cases * edge binding XWindows replaced with regular canvas objects * some E_Win functionality has changed such that delete callbacks are now correctly called in ALL cases. various dialogs have been updated to not crash as a result comp files and descriptions: e_comp.c - overall compositor functions, rendering/update loop, shape cutting e_comp_x.c - X window management and compositor functionality e_comp_wl.c - Wayland surface management and compositor functionality e_comp_canvas.c - general compositor canvas functions and utilities e_comp_object.c - E_Client->frame member for managing clients as Evas_Objects, utility functions for adding objects to the compositor rendering systems additional authors: ivan.briano@intel.com feature: new compositor removal: e_border, e_container, e_popup
2014-01-14 17:19:12 -08:00
// so much relies on this down here to have been broken... ie return comp-relative coords.
2009-01-21 20:42:16 -08:00
// if (gc->zone)
// {
// if (x) *x = *x - gc->zone->x;
// if (y) *y = *y - gc->zone->y;
// }
return 1;
}
2006-06-15 00:24:10 -07:00
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_util_menu_attach_func_set(E_Gadcon *gc, void (*func)(void *data, E_Gadcon_Client *gcc, E_Menu *menu), void *data)
2006-06-15 00:24:10 -07:00
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->menu_attach.func = func;
gc->menu_attach.data = data;
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_util_lock_func_set(E_Gadcon *gc, void (*func)(void *data, int lock), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->locked_set.func = func;
gc->locked_set.data = data;
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_util_urgent_show_func_set(E_Gadcon *gc, void (*func)(void *data), void *data)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->urgent_show.func = func;
gc->urgent_show.data = data;
}
EAPI void
e_gadcon_dnd_window_set(E_Gadcon *gc, Ecore_X_Window win)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->dnd_win = win;
}
2012-06-20 05:43:15 -07:00
EAPI Ecore_X_Window
e_gadcon_dnd_window_get(E_Gadcon *gc)
{
E_OBJECT_CHECK_RETURN(gc, 0);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0);
return gc->dnd_win;
}
EAPI void
e_gadcon_xdnd_window_set(E_Gadcon *gc, Ecore_X_Window win)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->xdnd_win = win;
}
2012-06-20 05:43:15 -07:00
EAPI Ecore_X_Window
e_gadcon_xdnd_window_get(E_Gadcon *gc)
{
E_OBJECT_CHECK_RETURN(gc, 0);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0);
return gc->xdnd_win;
}
EAPI void
e_gadcon_name_set(E_Gadcon *gc, const char *name)
{
if (!gc) return;
if (!name) return;
if (gc->name == name) return;
eina_stringshare_replace(&gc->name, name);
eina_stringshare_replace(&gc->cf->name, name);
}
EAPI void
e_gadcon_shelf_set(E_Gadcon *gc, E_Shelf *shelf)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->shelf = shelf;
}
2012-06-20 05:43:15 -07:00
EAPI E_Shelf *
e_gadcon_shelf_get(E_Gadcon *gc)
{
E_OBJECT_CHECK_RETURN(gc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
return gc->shelf;
}
2012-06-20 05:43:15 -07:00
EAPI void
e_gadcon_toolbar_set(E_Gadcon *gc, E_Toolbar *toolbar)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
gc->toolbar = toolbar;
}
EAPI E_Toolbar *
2012-06-20 05:43:15 -07:00
e_gadcon_toolbar_get(E_Gadcon *gc)
{
E_OBJECT_CHECK_RETURN(gc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
return gc->toolbar;
}
EAPI E_Config_Gadcon_Client *
e_gadcon_client_config_new(E_Gadcon *gc, const char *name)
{
E_Gadcon_Client_Class *cc;
E_Config_Gadcon_Client *cf_gcc;
E_OBJECT_CHECK_RETURN(gc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
if (!name) return NULL;
cc = eina_hash_find(providers, name);
if (!cc) return NULL;
2012-06-20 05:43:15 -07:00
if (!_e_gadcon_client_class_feature_check(cc, "id_new", cc->func.id_new))
return NULL;
cf_gcc = E_NEW(E_Config_Gadcon_Client, 1);
if (!cf_gcc) return NULL;
cf_gcc->id = eina_stringshare_add(cc->func.id_new(cc));
if (!cf_gcc->id)
{
free(cf_gcc);
return NULL;
}
cf_gcc->name = eina_stringshare_add(name);
if (gc->zone)
cf_gcc->geom.res = gc->zone->w;
else if (gc->o_container)
{
int w, h;
evas_object_geometry_get(gc->o_container, NULL, NULL, &w, &h);
switch (gc->orient)
{
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
cf_gcc->geom.res = h;
break;
default:
cf_gcc->geom.res = w;
}
}
else
cf_gcc->geom.res = 800;
cf_gcc->geom.size = 80;
cf_gcc->geom.pos = cf_gcc->geom.res - cf_gcc->geom.size;
cf_gcc->style = NULL;
cf_gcc->autoscroll = 0;
cf_gcc->resizable = 0;
gc->cf->clients = eina_list_append(gc->cf->clients, cf_gcc);
e_config_save_queue();
return cf_gcc;
}
EAPI void
e_gadcon_client_config_del(E_Config_Gadcon *cf_gc, E_Config_Gadcon_Client *cf_gcc)
{
E_Gadcon *gc;
Eina_List *l, *ll;
if (!cf_gcc) return;
EINA_LIST_FOREACH(gadcons, l, gc)
{
if (!gc->awaiting_classes) continue;
ll = eina_hash_find(gc->awaiting_classes, cf_gcc->name);
eina_hash_set(gc->awaiting_classes, cf_gcc->name, eina_list_remove(ll, cf_gcc));
}
eina_stringshare_del(cf_gcc->name);
eina_stringshare_del(cf_gcc->id);
eina_stringshare_del(cf_gcc->style);
if (cf_gc) cf_gc->clients = eina_list_remove(cf_gc->clients, cf_gcc);
free(cf_gcc);
}
EAPI E_Gadcon_Client *
e_gadcon_client_find(E_Gadcon *gc, E_Config_Gadcon_Client *cf_gcc)
{
E_Gadcon_Client *gcc;
Eina_List *l, *ll;
if (!cf_gcc) return NULL;
if (gc)
{
EINA_LIST_FOREACH(gc->clients, ll, gcc)
if (gcc->cf == cf_gcc) return gcc;
return NULL;
}
EINA_LIST_FOREACH(gadcons, l, gc)
EINA_LIST_FOREACH(gc->clients, ll, gcc)
if (gcc->cf == cf_gcc) return gcc;
return NULL;
}
static void
_e_gadcon_client_box_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc = data;
gcc->o_box = NULL;
}
static void
_e_gadcon_client_box_hints_changed(void *data EINA_UNUSED, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
evas_object_size_hint_min_set(obj, 0, 0);
}
static void
_e_gadcon_client_frame_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc = data;
gcc->o_frame = NULL;
}
EAPI void
e_gadcon_drag_finished_cb(E_Drag *drag, int dropped)
{
E_Gadcon_Client *gcc;
gcc = drag->data;
gcc->drag.drag = NULL;
if (!dropped)
{
/* free client config */
e_gadcon_client_config_del(NULL, gcc->cf);
gcc->cf = NULL;
/* delete the gadcon client */
/* TODO: Clean up module config too? */
e_object_del(E_OBJECT(gcc));
}
e_gadcon_client_drag_set(NULL);
gcc->gadcon->new_gcc = NULL;
e_object_unref(E_OBJECT(gcc));
}
/**
* Creates a new gadget
*
* @param gc gadcon pointer
* @param name to use for gadget
* @param id assigned to gadget
* @param style to for gadget
* @param base_obj the evas object that will show up in the shelf or gadget module
* @return returns pointer to created gadget, on failure returns null
*/
EAPI E_Gadcon_Client *
e_gadcon_client_new(E_Gadcon *gc, const char *name, const char *id __UNUSED__, const char *style, Evas_Object *base_obj)
{
E_Gadcon_Client *gcc;
E_OBJECT_CHECK_RETURN(gc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
2012-06-20 05:43:15 -07:00
gcc = E_OBJECT_ALLOC(E_Gadcon_Client, E_GADCON_CLIENT_TYPE,
_e_gadcon_client_free);
if (!gcc) return NULL;
e_object_delfn_add(E_OBJECT(gcc), _e_gadcon_client_delfn, NULL);
gcc->name = eina_stringshare_add(name);
gcc->gadcon = gc;
gcc->o_base = base_obj;
if (gc->clients)
gcc->id = E_GADCON_CLIENT(eina_list_last_data_get(gc->clients))->id + 1;
gc->clients = eina_list_append(gc->clients, gcc);
/* This must only be unique during runtime */
if (gcc->o_base)
evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_DEL,
2012-06-20 05:43:15 -07:00
_e_gadcon_client_del_hook, gcc);
if ((gc->frame_request.func) && (style))
{
2012-06-20 05:43:15 -07:00
gcc->o_frame = gc->frame_request.func(gc->frame_request.data, gcc, style);
gcc->style = eina_stringshare_add(style);
if (gcc->o_frame)
{
edje_object_size_min_calc(gcc->o_frame, &(gcc->pad.w), &(gcc->pad.h));
2015-01-20 16:20:04 -08:00
gcc->o_box = elm_box_add(e_win_evas_object_win_get(gcc->gadcon->o_container));
evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_DEL, _e_gadcon_client_box_del, gcc);
evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _e_gadcon_client_box_hints_changed, gcc);
2012-06-20 05:43:15 -07:00
switch (gcc->gadcon->orient)
{
case E_GADCON_ORIENT_FLOAT:
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
elm_box_horizontal_set(gcc->o_box, 1);
2012-06-20 05:43:15 -07:00
break;
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
elm_box_horizontal_set(gcc->o_box, 0);
2012-06-20 05:43:15 -07:00
break;
default:
break;
}
evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_MOVE,
_e_gadcon_cb_client_frame_moveresize, gcc);
evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_RESIZE,
_e_gadcon_cb_client_frame_moveresize, gcc);
evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_MOVE,
_e_gadcon_cb_client_frame_mouse_move, gcc);
if (gcc->o_base)
{
E_EXPAND(gcc->o_base);
elm_box_pack_end(gcc->o_box, gcc->o_base);
2012-06-20 05:43:15 -07:00
}
edje_object_part_swallow(gcc->o_frame, gc->edje.swallow_name, gcc->o_box);
evas_object_show(gcc->o_box);
evas_object_show(gcc->o_frame);
}
}
if (gcc->o_frame)
{
e_gadcon_layout_pack(gc->o_container, gcc->o_frame);
evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_DEL, _e_gadcon_client_frame_del, gcc);
}
else if (gcc->o_base)
e_gadcon_layout_pack(gc->o_container, gcc->o_base);
if (gcc->o_base) evas_object_show(gcc->o_base);
{
E_Event_Gadcon_Client_Add *ev;
ev = E_NEW(E_Event_Gadcon_Client_Add, 1);
ev->gcc = gcc;
e_object_ref(E_OBJECT(gcc));
ecore_event_add(E_EVENT_GADCON_CLIENT_ADD, ev, _e_gadcon_client_event_free, NULL);
}
return gcc;
}
EAPI void
e_gadcon_client_edit_begin(E_Gadcon_Client *gcc)
{
Evas_Coord x, y, w, h;
Evas_Object *base;
compositor rewrite / charlie-foxtrot situation huge fustercluck commit because there wasn't really a way to separate out the changes. better to just rip it all out at once. * compositor and window management completely rewritten. this was the goal for E19, but it pretty much required everything existing to be scrapped since it wasn't optimized, streamlined, or sensible. now instead of having the compositor strapped to the window manager like an outboard motor, it's housed more like an automobile engine. ** various comp structs have been merged into other places (eg. E_Comp_Zone is now just part of E_Zone where applicable), leading to a large deduplication of attributes ** awful E_Comp_Win is totally dead, having been replaced with e_comp_object smart objects which work just like normal canvas objects ** protocol-specific window management and compositor functionality is now kept exclusively in backend files ** e_pixmap api provides generic client finding and rendering api ** screen/xinerama screens are now provided directly by compositor on startup and re-set on change ** e_comp_render_update finally replaced with eina_tiler ** wayland compositor no longer creates X windows ** compositor e_layout removed entirely * e_container is gone. this was made unnecessary in E18, but I kept it to avoid having too much code churn in one release. its sole purpose was to catch some events and handle window stacking, both of which are now just done by the compositor infra * e_manager is just for screensaver and keybind stuff now, possibly remove later? * e_border is gone along with a lot of its api. e_client has replaced it, and e_client has been rewritten completely; some parts may be similar, but the design now relies upon having a functional compositor ** window configuration/focus functions are all removed. all windows are now managed solely with evas_object_X functions on the "frame" member of a client, just as any other canvas object can be managed. *** do NOT set interceptors on a client's comp_object. seriously. * startup order rewritten: compositor now starts much earlier, other things just use attrs and members of the compositor * ecore_x_pointer_xy_get usage replaced with ecore_evas_pointer_xy_get * e_popup is totally gone, existing usage replaced by e_comp_object_util_add where applicable, otherwise just placed normally on the canvas * deskmirror is (more) broken for now * illume is totally fucked * Ecore_X_Window replaced with Ecore_Window in most cases * edge binding XWindows replaced with regular canvas objects * some E_Win functionality has changed such that delete callbacks are now correctly called in ALL cases. various dialogs have been updated to not crash as a result comp files and descriptions: e_comp.c - overall compositor functions, rendering/update loop, shape cutting e_comp_x.c - X window management and compositor functionality e_comp_wl.c - Wayland surface management and compositor functionality e_comp_canvas.c - general compositor canvas functions and utilities e_comp_object.c - E_Client->frame member for managing clients as Evas_Objects, utility functions for adding objects to the compositor rendering systems additional authors: ivan.briano@intel.com feature: new compositor removal: e_border, e_container, e_popup
2014-01-14 17:19:12 -08:00
int layer;
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->o_control) return;
base = gcc->o_frame ?: gcc->o_base;
if (!base) return;
compositor rewrite / charlie-foxtrot situation huge fustercluck commit because there wasn't really a way to separate out the changes. better to just rip it all out at once. * compositor and window management completely rewritten. this was the goal for E19, but it pretty much required everything existing to be scrapped since it wasn't optimized, streamlined, or sensible. now instead of having the compositor strapped to the window manager like an outboard motor, it's housed more like an automobile engine. ** various comp structs have been merged into other places (eg. E_Comp_Zone is now just part of E_Zone where applicable), leading to a large deduplication of attributes ** awful E_Comp_Win is totally dead, having been replaced with e_comp_object smart objects which work just like normal canvas objects ** protocol-specific window management and compositor functionality is now kept exclusively in backend files ** e_pixmap api provides generic client finding and rendering api ** screen/xinerama screens are now provided directly by compositor on startup and re-set on change ** e_comp_render_update finally replaced with eina_tiler ** wayland compositor no longer creates X windows ** compositor e_layout removed entirely * e_container is gone. this was made unnecessary in E18, but I kept it to avoid having too much code churn in one release. its sole purpose was to catch some events and handle window stacking, both of which are now just done by the compositor infra * e_manager is just for screensaver and keybind stuff now, possibly remove later? * e_border is gone along with a lot of its api. e_client has replaced it, and e_client has been rewritten completely; some parts may be similar, but the design now relies upon having a functional compositor ** window configuration/focus functions are all removed. all windows are now managed solely with evas_object_X functions on the "frame" member of a client, just as any other canvas object can be managed. *** do NOT set interceptors on a client's comp_object. seriously. * startup order rewritten: compositor now starts much earlier, other things just use attrs and members of the compositor * ecore_x_pointer_xy_get usage replaced with ecore_evas_pointer_xy_get * e_popup is totally gone, existing usage replaced by e_comp_object_util_add where applicable, otherwise just placed normally on the canvas * deskmirror is (more) broken for now * illume is totally fucked * Ecore_X_Window replaced with Ecore_Window in most cases * edge binding XWindows replaced with regular canvas objects * some E_Win functionality has changed such that delete callbacks are now correctly called in ALL cases. various dialogs have been updated to not crash as a result comp files and descriptions: e_comp.c - overall compositor functions, rendering/update loop, shape cutting e_comp_x.c - X window management and compositor functionality e_comp_wl.c - Wayland surface management and compositor functionality e_comp_canvas.c - general compositor canvas functions and utilities e_comp_object.c - E_Client->frame member for managing clients as Evas_Objects, utility functions for adding objects to the compositor rendering systems additional authors: ivan.briano@intel.com feature: new compositor removal: e_border, e_container, e_popup
2014-01-14 17:19:12 -08:00
layer = evas_object_layer_get(base) + 1;
evas_object_geometry_get(base, &x, &y, &w, &h);
gcc->o_control = edje_object_add(gcc->gadcon->evas);
/* FIXME: should probably be in gadget theme or something */
evas_object_layer_set(gcc->o_control, layer);
e_gadcon_locked_set(gcc->gadcon, 1);
gcc->gadcon->editing = 1;
evas_object_move(gcc->o_control, x, y);
evas_object_resize(gcc->o_control, w, h);
2012-06-20 05:43:15 -07:00
e_theme_edje_object_set(gcc->o_control, "base/theme/gadman",
"e/gadman/control");
2012-06-20 05:43:15 -07:00
if ((gcc->autoscroll) /* || (gcc->resizable)*/)
{
if (elm_box_horizontal_get(gcc->o_box))
2012-06-20 05:43:15 -07:00
edje_object_signal_emit(gcc->o_control, "e,state,hsize,on", "e");
else
edje_object_signal_emit(gcc->o_control, "e,state,vsize,on", "e");
}
else
{
2012-06-20 05:43:15 -07:00
edje_object_signal_emit(gcc->o_control, "e,state,hsize,off", "e");
edje_object_signal_emit(gcc->o_control, "e,state,vsize,off", "e");
}
edje_object_signal_emit(gcc->o_control, "e,state,move,on", "e");
gcc->o_event = evas_object_rectangle_add(gcc->gadcon->evas);
evas_object_color_set(gcc->o_event, 0, 0, 0, 0);
evas_object_repeat_events_set(gcc->o_event, 1);
evas_object_layer_set(gcc->o_event, layer);
evas_object_move(gcc->o_event, x, y);
evas_object_resize(gcc->o_event, w, h);
edje_object_signal_callback_add(gcc->o_control, "e,action,move,start", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_move_start, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,move,stop", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_move_stop, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,move,go", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_move_go, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,start", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_start, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,stop", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_stop, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,go", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_go, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,start", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_start, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,stop", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_stop, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,go", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_go, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,start", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_start, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,stop", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_stop, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,go", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_left_go, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,start", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_start, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,stop", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_stop, gcc);
edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,go", "",
2012-06-20 05:43:15 -07:00
_e_gadcon_cb_signal_resize_right_go, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_DOWN,
_e_gadcon_cb_client_mouse_down, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_IN,
_e_gadcon_cb_client_mouse_in, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_OUT,
_e_gadcon_cb_client_mouse_out, gcc);
evas_object_event_callback_add(base, EVAS_CALLBACK_MOVE,
_e_gadcon_cb_client_move, gcc);
evas_object_event_callback_add(base, EVAS_CALLBACK_RESIZE,
_e_gadcon_cb_client_resize, gcc);
evas_object_show(gcc->o_event);
evas_object_show(gcc->o_control);
}
EAPI void
e_gadcon_client_edit_end(E_Gadcon_Client *gcc)
{
Eina_List *l = NULL;
E_Gadcon_Client *client = NULL;
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->o_frame)
{
2012-06-20 05:43:15 -07:00
evas_object_event_callback_del(gcc->o_frame, EVAS_CALLBACK_MOVE,
_e_gadcon_cb_client_move);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_del(gcc->o_frame, EVAS_CALLBACK_RESIZE,
_e_gadcon_cb_client_resize);
}
else if (gcc->o_base)
{
2012-06-20 05:43:15 -07:00
evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_MOVE,
_e_gadcon_cb_client_move);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_RESIZE,
_e_gadcon_cb_client_resize);
}
if (gcc->moving)
{
2012-06-20 05:43:15 -07:00
gcc->moving = 0;
if (gcc->cf) _e_gadcon_client_save(gcc);
}
if (gcc->o_event) evas_object_del(gcc->o_event);
gcc->o_event = NULL;
if (gcc->o_control) evas_object_del(gcc->o_control);
gcc->o_control = NULL;
e_gadcon_locked_set(gcc->gadcon, 0);
EINA_LIST_FOREACH(gcc->gadcon->clients, l, client)
{
2012-06-20 05:43:15 -07:00
if (!client) continue;
if (client->o_control) return;
}
gcc->gadcon->editing = 0;
}
EAPI void
e_gadcon_client_show(E_Gadcon_Client *gcc)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (!gcc->hidden) return;
if (gcc->o_box) evas_object_show(gcc->o_box);
if (gcc->o_frame) evas_object_show(gcc->o_frame);
if (gcc->o_base) evas_object_show(gcc->o_base);
if (gcc->o_control) evas_object_show(gcc->o_control);
if (gcc->o_event) evas_object_show(gcc->o_event);
if (gcc->o_frame)
{
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack(gcc->gadcon->o_container, gcc->o_frame);
e_gadcon_layout_pack_options_set(gcc->o_frame, gcc);
}
else if (gcc->o_base)
{
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack(gcc->gadcon->o_container, gcc->o_base);
e_gadcon_layout_pack_options_set(gcc->o_base, gcc);
}
gcc->hidden = 0;
}
EAPI void
e_gadcon_client_hide(E_Gadcon_Client *gcc)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->hidden) return;
if (gcc->o_box) evas_object_hide(gcc->o_box);
if (gcc->o_frame) evas_object_hide(gcc->o_frame);
if (gcc->o_base) evas_object_hide(gcc->o_base);
if (gcc->o_control) evas_object_hide(gcc->o_control);
if (gcc->o_event) evas_object_hide(gcc->o_event);
if (gcc->o_frame)
e_gadcon_layout_unpack(gcc->o_frame);
else if (gcc->o_base)
e_gadcon_layout_unpack(gcc->o_base);
gcc->hidden = 1;
}
EAPI void
e_gadcon_client_size_request(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h)
{
2006-02-05 01:29:47 -08:00
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
switch (gcc->gadcon->orient)
{
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_BOTTOM:
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_size_set(gcc->o_frame, w + gcc->pad.w);
else if (gcc->o_base)
e_gadcon_layout_pack_size_set(gcc->o_base, w);
break;
2006-02-05 01:29:47 -08:00
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_size_set(gcc->o_frame, h + gcc->pad.h);
else if (gcc->o_base)
e_gadcon_layout_pack_size_set(gcc->o_base, h);
break;
case E_GADCON_ORIENT_FLOAT:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
2006-02-05 01:29:47 -08:00
default:
2012-06-20 05:43:15 -07:00
break;
2006-02-05 01:29:47 -08:00
}
}
EAPI void
e_gadcon_client_min_size_set(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
gcc->min.w = w;
gcc->min.h = h;
/* if (!gcc->resizable)*/
2012-06-20 05:43:15 -07:00
{
if (gcc->o_frame)
e_gadcon_layout_pack_min_size_set(gcc->o_frame, w + gcc->pad.w,
h + gcc->pad.h);
else if (gcc->o_base)
e_gadcon_layout_pack_min_size_set(gcc->o_base, w, h);
}
_e_gadcon_moveresize_handle(gcc);
}
EAPI void
e_gadcon_client_aspect_set(E_Gadcon_Client *gcc, int w, int h)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
gcc->aspect.w = w;
gcc->aspect.h = h;
// if ((!gcc->autoscroll)/* && (!gcc->resizable)*/)
2012-06-20 05:43:15 -07:00
{
if (gcc->o_frame)
{
e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w,
gcc->pad.h);
e_gadcon_layout_pack_aspect_set(gcc->o_frame, w, h);
}
else if (gcc->o_base)
e_gadcon_layout_pack_aspect_set(gcc->o_base, w, h);
}
_e_gadcon_moveresize_handle(gcc);
}
EAPI void
e_gadcon_client_autoscroll_toggle_disabled_set(E_Gadcon_Client *gcc, Eina_Bool disable)
{
disable = !!disable;
if (gcc->autoscroll_disabled == disable) return;
gcc->autoscroll_disabled = disable;
if (disable) e_gadcon_client_autoscroll_set(gcc, 1);
}
EAPI void
e_gadcon_client_autoscroll_set(E_Gadcon_Client *gcc, int autoscroll)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->autoscroll_disabled && (!autoscroll))
{
e_util_dialog_show(_("Gadget error"), _("%s does not support disabling autoscrolling"), gcc->name);
return;
}
gcc->autoscroll = autoscroll;
gcc->autoscroll_set = 1;
2012-06-20 05:43:15 -07:00
/*
if (gcc->autoscroll)
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
{
e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w,
gcc->pad.h);
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack_aspect_set(gcc->o_frame, 0, 0);
e_gadcon_layout_pack_min_size_set(gcc->o_frame, 0, 0);
}
else if (gcc->o_base)
{
e_gadcon_layout_pack_aspect_set(gcc->o_base, 0, 0);
e_gadcon_layout_pack_min_size_set(gcc->o_base, 0, 0);
}
}
else
*/
2012-06-20 05:43:15 -07:00
{
if (gcc->o_frame)
{
e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w,
gcc->pad.h);
e_gadcon_layout_pack_aspect_set(gcc->o_frame, gcc->aspect.w,
gcc->aspect.h);
e_gadcon_layout_pack_min_size_set(gcc->o_frame, gcc->min.w,
gcc->min.h);
}
else if (gcc->o_base)
{
e_gadcon_layout_pack_min_size_set(gcc->o_base, gcc->min.w,
gcc->min.h);
e_gadcon_layout_pack_aspect_set(gcc->o_base, gcc->aspect.w,
gcc->aspect.h);
}
}
}
2012-06-20 05:43:15 -07:00
EAPI void
e_gadcon_client_resizable_set(E_Gadcon_Client *gcc __UNUSED__, int resizable __UNUSED__)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
/*
gcc->resizable = resizable;
if (gcc->resizable)
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
{
e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w,
gcc->pad.h);
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack_aspect_set(gcc->o_frame, 0, 0);
e_gadcon_layout_pack_min_size_set(gcc->o_frame, 0, 0);
}
else if (gcc->o_base)
{
e_gadcon_layout_pack_min_size_set(gcc->o_base, 0, 0);
e_gadcon_layout_pack_aspect_set(gcc->o_base, 0, 0);
}
}
else
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
{
e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w,
gcc->pad.h);
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack_aspect_set(gcc->o_frame, gcc->aspect.w,
gcc->aspect.h);
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack_min_size_set(gcc->o_frame, gcc->min.w,
gcc->min.h);
2012-06-20 05:43:15 -07:00
}
else if (gcc->o_base)
{
e_gadcon_layout_pack_min_size_set(gcc->o_base, gcc->min.w,
gcc->min.h);
2012-06-20 05:43:15 -07:00
e_gadcon_layout_pack_aspect_set(gcc->o_base, gcc->aspect.w,
gcc->aspect.h);
2012-06-20 05:43:15 -07:00
}
}
*/
}
EAPI int
e_gadcon_client_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h)
{
int gx = 0, gy = 0;
E_OBJECT_CHECK_RETURN(gcc, 0);
E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, 0);
2012-06-20 05:43:15 -07:00
if (!e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &gx, &gy, NULL, NULL))
return 0;
if (gcc->o_base) evas_object_geometry_get(gcc->o_base, x, y, w, h);
if (x) *x += gx;
if (y) *y += gy;
return 1;
}
EAPI int
e_gadcon_client_viewport_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h)
{
E_OBJECT_CHECK_RETURN(gcc, 0);
E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, 0);
if (gcc->o_box) evas_object_geometry_get(gcc->o_base, x, y, w, h);
2012-06-20 05:43:15 -07:00
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, x, y, w, h);
else
{
if (x) *x = 0;
if (y) *y = 0;
if (w) *w = 0;
if (h) *h = 0;
}
return 1;
}
EAPI E_Zone *
e_gadcon_client_zone_get(E_Gadcon_Client *gcc)
{
E_OBJECT_CHECK_RETURN(gcc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, NULL);
return e_gadcon_zone_get(gcc->gadcon);
}
static Eina_Bool
_e_gadcon_client_populate(E_Gadcon *gc, const E_Gadcon_Client_Class *cc, E_Config_Gadcon_Client *cf_gcc)
{
E_Gadcon_Client *gcc;
if (!eina_list_data_find(gc->populated_classes, cc))
{
_e_gadcon_provider_populate_request(gc, cc);
return EINA_TRUE;
}
if ((!cf_gcc->id) &&
(_e_gadcon_client_class_feature_check(cc, "id_new", cc->func.id_new)))
cf_gcc->id = eina_stringshare_add(cc->func.id_new(cc));
if (!cf_gcc->style)
gcc = cc->func.init(gc, cf_gcc->name, cf_gcc->id,
cc->default_style);
else
gcc = cc->func.init(gc, cf_gcc->name, cf_gcc->id,
cf_gcc->style);
if (!gcc) return EINA_FALSE;
gcc->cf = cf_gcc;
gcc->client_class = cc;
gcc->config.pos = cf_gcc->geom.pos;
gcc->config.size = cf_gcc->geom.size;
gcc->config.res = cf_gcc->geom.res;
gcc->state_info.seq = cf_gcc->state_info.seq;
gcc->state_info.flags = cf_gcc->state_info.flags;
gcc->config.pos_x = gcc->cf->geom.pos_x;
gcc->config.pos_y = gcc->cf->geom.pos_y;
gcc->config.size_w = gcc->cf->geom.size_w;
gcc->config.size_h = gcc->cf->geom.size_h;
gcc->cf->resizable = 0;
eina_stringshare_replace(&gcc->style, cf_gcc->style);
if (gcc->o_frame)
e_gadcon_layout_pack_options_set(gcc->o_frame, gcc);
else if (gcc->o_base)
e_gadcon_layout_pack_options_set(gcc->o_base, gcc);
if (!gcc->autoscroll_set)
e_gadcon_client_autoscroll_set(gcc, cf_gcc->autoscroll);
// e_gadcon_client_resizable_set(gcc, cf_gcc->resizable);
if (gcc->client_class->func.orient)
gcc->client_class->func.orient(gcc, gc->orient);
e_config_save_queue();
if (gc->editing) e_gadcon_client_edit_begin(gcc);
if (gc->instant_edit)
e_gadcon_client_util_menu_attach(gcc);
return EINA_TRUE;
}
static void
_e_gadcon_client_unpopulate(E_Gadcon_Client *gcc)
{
if (gcc->menu)
{
if (gcc->gadcon->shelf && (gcc->menu == gcc->gadcon->shelf->menu)) gcc->gadcon->shelf->menu = NULL;
e_menu_post_deactivate_callback_set(gcc->menu, NULL, NULL);
e_menu_deactivate(gcc->menu);
e_object_del(E_OBJECT(gcc->menu));
gcc->menu = NULL;
}
e_object_del(E_OBJECT(gcc));
}
2009-08-31 04:23:03 -07:00
static void
_e_gadcon_client_change_gadcon(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi)
2009-08-31 04:23:03 -07:00
{
E_Gadcon_Location *src, *dst;
2012-06-20 05:43:15 -07:00
E_Gadcon_Client *gcc;
2009-08-31 04:23:03 -07:00
gcc = data;
src = gcc->gadcon->location;
dst = e_object_data_get(E_OBJECT(mi));
_e_gadcon_location_change(gcc, src, dst);
}
static void
2012-06-20 05:43:15 -07:00
_e_gadcon_add_locations_menu_for_site(E_Menu *m, E_Gadcon_Client *gcc, E_Gadcon_Site site, int *count)
2009-08-31 04:23:03 -07:00
{
E_Menu_Item *mi;
const Eina_List *l;
2012-06-20 05:43:15 -07:00
E_Gadcon_Location *loc;
2009-08-31 04:23:03 -07:00
int k = *count;
EINA_LIST_FOREACH(gadcon_locations, l, loc)
{
2012-06-20 05:43:15 -07:00
if (loc->site == site)
{
if (loc == gcc->gadcon->location) continue;
if (k)
{
k = 0;
mi = e_menu_item_new(m);
e_menu_item_separator_set(mi, 1);
(*count) = 0;
}
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, loc->name);
e_object_data_set(E_OBJECT(mi), loc);
e_menu_item_callback_set(mi, _e_gadcon_client_change_gadcon, gcc);
2012-06-20 05:43:15 -07:00
if (loc->icon_name)
e_util_menu_item_theme_icon_set(mi, loc->icon_name);
(*count)++;
2012-06-20 05:43:15 -07:00
}
2009-08-31 04:23:03 -07:00
}
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_gadget_move_to_pre_cb(void *data, E_Menu *m)
2009-08-31 04:23:03 -07:00
{
E_Gadcon_Client *gcc;
int n = 0;
gcc = data;
e_menu_pre_activate_callback_set(m, NULL, NULL);
2009-08-31 04:23:03 -07:00
if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_SHELF))
_e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_SHELF, &n);
if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_DESKTOP))
_e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_DESKTOP, &n);
if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_TOOLBAR))
_e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_TOOLBAR, &n);
//if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_EFM_TOOLBAR))
//_e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_EFM_TOOLBAR, &n);
2009-08-31 04:23:03 -07:00
_e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_UNKNOWN, &n);
}
EAPI void
e_gadcon_client_add_location_menu(E_Gadcon_Client *gcc, E_Menu *menu)
{
E_Menu *mn;
E_Menu_Item *mi;
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->gadcon->location)
{
2012-06-20 05:43:15 -07:00
mn = e_menu_new();
mi = e_menu_item_new(menu);
e_menu_item_label_set(mi, _("Move to"));
e_util_menu_item_theme_icon_set(mi, "preferences-look");
e_menu_item_submenu_set(mi, mn);
e_menu_pre_activate_callback_set(mn, _e_gadcon_gadget_move_to_pre_cb, gcc);
e_object_unref(E_OBJECT(mn));
2009-08-31 04:23:03 -07:00
}
}
EAPI E_Menu *
e_gadcon_client_menu_set(E_Gadcon_Client *gcc, E_Menu *m)
{
E_Menu *ret;
E_OBJECT_CHECK_RETURN(gcc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, NULL);
ret = gcc->menu;
if (ret)
e_menu_post_deactivate_callback_set(ret, NULL, NULL);
gcc->menu = m;
if (gcc->gadcon->shelf) gcc->gadcon->shelf->menu = m;
if (m)
e_menu_post_deactivate_callback_set(m, _e_gadcon_client_cb_menu_post, gcc);
return ret;
}
EAPI E_Menu *
e_gadcon_client_util_menu_items_append(E_Gadcon_Client *gcc, E_Menu *menu_gadget, int flags __UNUSED__)
{
E_Menu *mo, *menu_main = NULL;
E_Menu_Item *mi;
char buf[256];
E_OBJECT_CHECK_RETURN(gcc, NULL);
E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, NULL);
if (e_config->menu_gadcon_client_toplevel)
menu_main = menu_gadget;
else
menu_main = e_menu_new();
e_menu_post_deactivate_callback_set(menu_main, _e_gadcon_client_cb_menu_post, gcc);
gcc->menu = menu_main;
2012-06-20 05:43:15 -07:00
if (gcc->gadcon->shelf)
{
if (e_menu_item_nth(menu_gadget, 0))
{
mi = e_menu_item_new(menu_gadget);
e_menu_item_separator_set(mi, 1);
}
/*
2012-06-20 05:43:15 -07:00
if (!gcc->o_control)
{
mi = e_menu_item_new(menu_gadget);
e_menu_item_label_set(mi, _("Move"));
e_util_menu_item_theme_icon_set(mi, "transform-scale");
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_edit, gcc);
2012-06-20 05:43:15 -07:00
}
mi = e_menu_item_new(menu_gadget);
e_menu_item_label_set(mi, _("Resizeable"));
e_util_menu_item_theme_icon_set(mi, "transform-scale");
e_menu_item_check_set(mi, 1);
if (gcc->resizable) e_menu_item_toggle_set(mi, 1);
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_resizable, gcc);
*/
if (!gcc->autoscroll_disabled)
{
mi = e_menu_item_new(menu_gadget);
e_menu_item_label_set(mi, _("Automatically scroll contents"));
e_util_menu_item_theme_icon_set(mi, "transform-move");
e_menu_item_check_set(mi, 1);
if (gcc->autoscroll) e_menu_item_toggle_set(mi, 1);
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_autoscroll, gcc);
}
2012-06-20 05:43:15 -07:00
if (gcc->gadcon->shelf)
{
mo = e_menu_new();
gcc->gadcon->shelf->menu = menu_main;
mi = e_menu_item_new(mo);
e_menu_item_label_set(mi, _("Plain"));
e_util_menu_item_theme_icon_set(mi, "enlightenment/plain");
e_menu_item_radio_group_set(mi, 1);
e_menu_item_radio_set(mi, 1);
if (!e_util_strcmp(gcc->style, E_GADCON_CLIENT_STYLE_PLAIN))
e_menu_item_toggle_set(mi, 1);
else if ((!gcc->style) &&
(!e_util_strcmp(gcc->client_class->default_style, E_GADCON_CLIENT_STYLE_PLAIN)))
e_menu_item_toggle_set(mi, 1);
e_menu_item_disabled_set(mi, mi->toggle);
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_style_plain, gcc);
mi = e_menu_item_new(mo);
e_menu_item_label_set(mi, _("Inset"));
e_util_menu_item_theme_icon_set(mi, "enlightenment/inset");
e_menu_item_radio_group_set(mi, 1);
e_menu_item_radio_set(mi, 1);
if (!e_util_strcmp(gcc->style, E_GADCON_CLIENT_STYLE_INSET))
e_menu_item_toggle_set(mi, 1);
else if ((!gcc->style) &&
(!e_util_strcmp(gcc->client_class->default_style, E_GADCON_CLIENT_STYLE_INSET)))
e_menu_item_toggle_set(mi, 1);
e_menu_item_disabled_set(mi, mi->toggle);
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_style_inset, gcc);
mi = e_menu_item_new(menu_gadget);
e_menu_item_label_set(mi, _("Look"));
e_util_menu_item_theme_icon_set(mi, "preferences-look");
e_menu_item_submenu_set(mi, mo);
e_object_unref(E_OBJECT(mo));
}
2012-06-20 05:43:15 -07:00
mi = e_menu_item_new(menu_gadget);
e_menu_item_separator_set(mi, 1);
2012-06-20 05:43:15 -07:00
e_gadcon_client_add_location_menu(gcc, menu_gadget);
2006-06-15 00:24:10 -07:00
2012-06-20 05:43:15 -07:00
mi = e_menu_item_new(menu_gadget);
e_menu_item_label_set(mi, _("Remove"));
e_util_menu_item_theme_icon_set(mi, "list-remove");
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_remove, gcc);
}
if ((!e_config->menu_gadcon_client_toplevel) && (!gcc->gadcon->toolbar))
{
2012-06-20 05:43:15 -07:00
mi = e_menu_item_new(menu_main);
if (gcc->client_class->func.label)
snprintf(buf, sizeof(buf), "%s",
gcc->client_class->func.label((E_Gadcon_Client_Class *)gcc->client_class));
else
snprintf(buf, sizeof(buf), "%s", gcc->name);
2012-06-20 05:43:15 -07:00
e_menu_item_label_set(mi, _(buf));
e_menu_item_realize_callback_set(mi, _e_gadcon_client_cb_menu_pre, gcc);
e_menu_item_submenu_set(mi, menu_gadget);
e_object_unref(E_OBJECT(menu_gadget));
}
2012-06-20 05:43:15 -07:00
2006-06-15 00:24:10 -07:00
if (gcc->gadcon->menu_attach.func)
{
if ((gcc->gadcon->shelf) || (gcc->gadcon->toolbar))
2012-06-20 05:43:15 -07:00
{
if (e_config->menu_gadcon_client_toplevel)
{
mi = e_menu_item_new(menu_main);
e_menu_item_separator_set(mi, 1);
}
gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data, gcc, menu_main);
}
else
gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data, gcc, menu_gadget);
2006-06-15 00:24:10 -07:00
}
2012-06-20 05:43:15 -07:00
return menu_main;
}
2012-06-20 05:43:15 -07:00
EAPI void
e_gadcon_client_util_menu_attach(E_Gadcon_Client *gcc)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->o_frame)
{
evas_object_event_callback_del_full(gcc->o_frame, EVAS_CALLBACK_MOUSE_DOWN,
_e_gadcon_client_cb_mouse_down, gcc);
evas_object_event_callback_del_full(gcc->o_frame, EVAS_CALLBACK_MOUSE_UP,
_e_gadcon_client_cb_mouse_up, gcc);
evas_object_event_callback_del_full(gcc->o_frame, EVAS_CALLBACK_MOUSE_MOVE,
_e_gadcon_client_cb_mouse_move, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_DOWN,
_e_gadcon_client_cb_mouse_down, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_UP,
_e_gadcon_client_cb_mouse_up, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_MOVE,
_e_gadcon_client_cb_mouse_move, gcc);
}
else if (gcc->o_base)
{
evas_object_event_callback_del_full(gcc->o_base, EVAS_CALLBACK_MOUSE_DOWN,
_e_gadcon_client_cb_mouse_down, gcc);
evas_object_event_callback_del_full(gcc->o_base, EVAS_CALLBACK_MOUSE_UP,
_e_gadcon_client_cb_mouse_up, gcc);
evas_object_event_callback_del_full(gcc->o_base, EVAS_CALLBACK_MOUSE_MOVE,
_e_gadcon_client_cb_mouse_move, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_DOWN,
_e_gadcon_client_cb_mouse_down, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_UP,
_e_gadcon_client_cb_mouse_up, gcc);
2012-06-20 05:43:15 -07:00
evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_MOVE,
_e_gadcon_client_cb_mouse_move, gcc);
}
}
EAPI void
e_gadcon_locked_set(E_Gadcon *gc, int lock)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->locked_set.func)
gc->locked_set.func(gc->locked_set.data, lock);
}
EAPI void
e_gadcon_urgent_show(E_Gadcon *gc)
{
E_OBJECT_CHECK(gc);
E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
if (gc->urgent_show.func)
gc->urgent_show.func(gc->urgent_show.data);
}
/*
* NOTE: x & y are relative to the o_box of the gadcon.
*/
EAPI void
e_gadcon_client_autoscroll_update(E_Gadcon_Client *gcc, Evas_Coord x, Evas_Coord y)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
if (gcc->autoscroll)
{
2012-06-20 05:43:15 -07:00
Evas_Coord w, h;
double d;
2010-11-08 06:05:08 -08:00
/* TODO: When using gadman there is no o_box! */
2012-06-20 05:43:15 -07:00
evas_object_geometry_get(gcc->o_box, NULL, NULL, &w, &h);
if (elm_box_horizontal_get(gcc->o_box))
2012-06-20 05:43:15 -07:00
{
if (w > 1) d = (double)x / (double)(w - 1);
else d = 0;
}
else
{
if (h > 1) d = (double)y / (double)(h - 1);
else d = 0;
}
if (d < 0.0) d = 0.0;
else if (d > 1.0)
d = 1.0;
if (!gcc->scroll_timer)
gcc->scroll_timer =
ecore_timer_add(0.01, _e_gadcon_cb_client_scroll_timer, gcc);
if (!gcc->scroll_animator)
gcc->scroll_animator =
ecore_animator_add(_e_gadcon_cb_client_scroll_animator, gcc);
gcc->scroll_wanted = d;
}
}
EAPI void
e_gadcon_client_autoscroll_cb_set(E_Gadcon_Client *gcc, void (*func)(void *data), void *data)
{
E_OBJECT_CHECK(gcc);
E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
gcc->scroll_cb.func = func;
gcc->scroll_cb.data = data;
}
EAPI Eina_Bool
e_gadcon_site_is_shelf(E_Gadcon_Site site)
{
2012-06-20 05:43:15 -07:00
return site == E_GADCON_SITE_SHELF;
}
EAPI Eina_Bool
e_gadcon_site_is_desktop(E_Gadcon_Site site)
{
2012-06-20 05:43:15 -07:00
return site == E_GADCON_SITE_DESKTOP;
}
EAPI Eina_Bool
e_gadcon_site_is_efm_toolbar(E_Gadcon_Site site)
{
2012-06-20 05:43:15 -07:00
return site == E_GADCON_SITE_EFM_TOOLBAR;
}
EAPI Eina_Bool
e_gadcon_site_is_any_toolbar(E_Gadcon_Site site)
{
switch (site)
{
2012-06-20 05:43:15 -07:00
// there should be all toolbar sities identifiers
case E_GADCON_SITE_TOOLBAR:
case E_GADCON_SITE_EFM_TOOLBAR:
return EINA_TRUE;
2012-06-20 05:43:15 -07:00
default:
2012-06-20 05:43:15 -07:00
return EINA_FALSE;
}
return EINA_FALSE;
}
EAPI Eina_Bool
e_gadcon_site_is_not_toolbar(E_Gadcon_Site site)
{
switch (site)
{
2012-06-20 05:43:15 -07:00
// there should be all toolbar sities identifiers
case E_GADCON_SITE_TOOLBAR:
case E_GADCON_SITE_EFM_TOOLBAR:
return EINA_FALSE;
2012-06-20 05:43:15 -07:00
default:
2012-06-20 05:43:15 -07:00
return EINA_TRUE;
}
return EINA_TRUE;
}
EAPI void
e_gadcon_client_drag_set(E_Gadcon_Client *gcc)
{
Eina_List *l;
E_Gadcon *gc;
EINA_LIST_FOREACH(gadcons, l, gc)
gc->drag_gcc = gcc;
}
/* local subsystem functions */
static void
_e_gadcon_free(E_Gadcon *gc)
{
if (gc->dummy)
dummies = eina_list_remove(dummies, gc);
else
{
e_gadcon_unpopulate(gc);
gadcons = eina_list_remove(gadcons, gc);
}
eina_list_free(gc->populated_classes);
if (custom_populate_requests)
custom_populate_requests = eina_list_remove(custom_populate_requests, gc);
if (gc->o_container) evas_object_del(gc->o_container);
eina_stringshare_del(gc->name);
eina_stringshare_del(gc->edje.swallow_name);
if (gc->edje.o_parent)
evas_object_event_callback_del_full(gc->edje.o_parent, EVAS_CALLBACK_RESIZE,
(Evas_Object_Event_Cb)_e_gadcon_parent_resize_cb, gc);
if (gc->config_dialog) e_object_del(E_OBJECT(gc->config_dialog));
if (gc->drop_handler) e_drop_handler_del(gc->drop_handler);
if (gc->cfg_delete)
{
eina_stringshare_del(gc->cf->name);
e_config->gadcons = eina_list_remove(e_config->gadcons, gc->cf);
free(gc->cf);
e_config_save_queue();
}
free(gc);
}
static void
_e_gadcon_client_event_free(void *d __UNUSED__, void *e)
{
E_Event_Gadcon_Client_Del *ev = e;
e_object_unref(E_OBJECT(ev->gcc));
free(ev);
}
static void
_e_gadcon_event_populate(E_Gadcon *gc)
{
E_Event_Gadcon_Populate *ev;
ev = E_NEW(E_Event_Gadcon_Populate, 1);
e_object_ref(E_OBJECT(gc));
ev->gc = gc;
ecore_event_add(E_EVENT_GADCON_POPULATE, ev, _e_gadcon_event_populate_free, NULL);
}
static void
_e_gadcon_client_delfn(void *d __UNUSED__, void *o)
{
E_Gadcon_Client *gcc = o;
E_Event_Gadcon_Client_Add *ev;
if (gcc->instant_edit_timer)
{
2012-06-20 05:43:15 -07:00
ecore_timer_del(gcc->instant_edit_timer);
gcc->instant_edit_timer = NULL;
}
if (gcc->o_base)
evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_DEL,
2012-06-20 05:43:15 -07:00
_e_gadcon_client_del_hook);
if (gcc->menu)
{
if (gcc->gadcon->shelf && (gcc->menu == gcc->gadcon->shelf->menu)) gcc->gadcon->shelf->menu = NULL;
e_menu_post_deactivate_callback_set(gcc->menu, NULL, NULL);
e_menu_deactivate(gcc->menu);
2012-06-20 05:43:15 -07:00
e_object_del(E_OBJECT(gcc->menu));
gcc->menu = NULL;
}
e_gadcon_client_edit_end(gcc);
gcc->client_class->func.shutdown(gcc);
if ((gcc->client_class->func.id_del) && (gcc->cf))
gcc->client_class->func.id_del((E_Gadcon_Client_Class *)gcc->client_class,
gcc->cf->id);
if (gcc->drag.drag)
e_object_del(E_OBJECT(gcc->drag.drag));
gcc->gadcon->clients = eina_list_remove(gcc->gadcon->clients, gcc);
E_FREE_FUNC(gcc->scroll_timer, ecore_timer_del);
E_FREE_FUNC(gcc->scroll_animator, ecore_animator_del);
E_FREE_FUNC(gcc->o_box, evas_object_del);
E_FREE_FUNC(gcc->o_frame, evas_object_del);
e_object_ref(E_OBJECT(gcc));
ev = E_NEW(E_Event_Gadcon_Client_Del, 1);
ev->gcc = gcc;
ecore_event_add(E_EVENT_GADCON_CLIENT_DEL, ev, _e_gadcon_client_event_free, NULL);
}
static void
_e_gadcon_client_free(E_Gadcon_Client *gcc)
{
if (gcc->o_box) evas_object_del(gcc->o_box);
if (gcc->o_frame) evas_object_del(gcc->o_frame);
eina_stringshare_del(gcc->name);
eina_stringshare_del(gcc->style);
if (gcc->menu)
{
e_menu_deactivate(gcc->menu);
e_object_del(E_OBJECT(gcc->menu));
}
free(gcc);
}
static void
_e_gadcon_moveresize_handle(E_Gadcon_Client *gcc)
{
int w, h, mw, mh;
if (!gcc->o_base) return;
evas_object_geometry_get(gcc->o_box, NULL, NULL, &w, &h);
if (gcc->gadcon->edje.o_parent)
evas_object_geometry_get(gcc->gadcon->edje.o_parent, NULL, NULL, &mw, &mh);
else
mw = w, mh = h;
w = MIN(w, mw);
h = MIN(h, mh);
2012-06-20 05:43:15 -07:00
/*
if (gcc->resizable)
{
if (elm_box_horizontal_get(gcc->o_box))
2012-06-20 05:43:15 -07:00
{
if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
w = (h * gcc->aspect.w) / gcc->aspect.h;
}
else
{
if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
h = (w * gcc->aspect.h) / gcc->aspect.w;
}
}
*/
if (gcc->autoscroll)
{
if (elm_box_horizontal_get(gcc->o_box))
2012-06-20 05:43:15 -07:00
{
if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
{
w = (h * gcc->aspect.w) / gcc->aspect.h; // ZZZZ
// w = gcc->min.w;
}
else
{
w = gcc->min.w;
}
2012-06-20 05:43:15 -07:00
}
else
{
if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
{
h = (w * gcc->aspect.h) / gcc->aspect.w; // ZZZZ
// h = gcc->min.h;
}
else
{
h = gcc->min.h;
}
2012-06-20 05:43:15 -07:00
}
}
evas_object_size_hint_min_set(gcc->o_base, w, h);
evas_object_size_hint_max_set(gcc->o_base, mw, mh);
}
static void
_e_gadcon_parent_resize_cb(E_Gadcon *gc, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Eina_List *l;
E_Gadcon_Client *gcc;
EINA_LIST_FOREACH(gc->clients, l, gcc)
_e_gadcon_moveresize_handle(gcc);
}
static Eina_Bool
_e_gadcon_cb_client_scroll_timer(void *data)
{
E_Gadcon_Client *gcc;
double d, v;
gcc = data;
d = gcc->scroll_wanted - gcc->scroll_pos;
if (d < 0) d = -d;
if (d < 0.001)
{
2012-06-20 05:43:15 -07:00
gcc->scroll_pos = gcc->scroll_wanted;
gcc->scroll_timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
v = 0.05;
gcc->scroll_pos = (gcc->scroll_pos * (1.0 - v)) + (gcc->scroll_wanted * v);
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_e_gadcon_cb_client_scroll_animator(void *data)
{
E_Gadcon_Client *gcc;
gcc = data;
if (elm_box_horizontal_get(gcc->o_box))
elm_box_align_set(gcc->o_box, 1.0 - gcc->scroll_pos, 0.5);
else
elm_box_align_set(gcc->o_box, 0.5, 1.0 - gcc->scroll_pos);
if (!gcc->scroll_timer)
{
2012-06-20 05:43:15 -07:00
gcc->scroll_animator = NULL;
return ECORE_CALLBACK_CANCEL;
}
if (gcc->scroll_cb.func)
gcc->scroll_cb.func(gcc->scroll_cb.data);
return ECORE_CALLBACK_RENEW;
}
static void
_e_gadcon_cb_client_frame_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
{
Evas_Event_Mouse_Move *ev;
E_Gadcon_Client *gcc;
Evas_Coord x, y;
ev = event_info;
gcc = data;
evas_object_geometry_get(gcc->o_box, &x, &y, NULL, NULL);
2012-06-20 05:43:15 -07:00
e_gadcon_client_autoscroll_update(gcc, ev->cur.output.x - x,
ev->cur.output.y - y);
}
static void
_e_gadcon_cb_client_frame_moveresize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
_e_gadcon_moveresize_handle(gcc);
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_client_save(E_Gadcon_Client *gcc)
{
gcc->cf->geom.pos = gcc->config.pos;
gcc->cf->geom.size = gcc->config.size;
gcc->cf->geom.res = gcc->config.res;
gcc->cf->geom.pos_x = gcc->config.pos_x;
gcc->cf->geom.pos_y = gcc->config.pos_y;
gcc->cf->geom.size_w = gcc->config.size_w;
gcc->cf->geom.size_h = gcc->config.size_h;
gcc->cf->state_info.seq = gcc->state_info.seq;
gcc->cf->state_info.flags = gcc->state_info.flags;
gcc->cf->autoscroll = gcc->autoscroll;
eina_stringshare_replace(&gcc->cf->style, gcc->style);
/* gcc->cf->resizable = gcc->resizable;*/
gcc->cf->resizable = 0;
e_config_save_queue();
}
static void
_e_gadcon_client_drag_begin(E_Gadcon_Client *gcc, int x, int y)
{
E_Drag *drag;
Evas_Object *o = NULL;
Evas_Coord w = 0, h = 0;
E_Zone *zone;
const char *drag_types[] = { "enlightenment/gadcon_client" };
zone = e_gadcon_zone_get(gcc->gadcon);
if (gcc->gadcon->drag_gcc) return;
compositor rewrite / charlie-foxtrot situation huge fustercluck commit because there wasn't really a way to separate out the changes. better to just rip it all out at once. * compositor and window management completely rewritten. this was the goal for E19, but it pretty much required everything existing to be scrapped since it wasn't optimized, streamlined, or sensible. now instead of having the compositor strapped to the window manager like an outboard motor, it's housed more like an automobile engine. ** various comp structs have been merged into other places (eg. E_Comp_Zone is now just part of E_Zone where applicable), leading to a large deduplication of attributes ** awful E_Comp_Win is totally dead, having been replaced with e_comp_object smart objects which work just like normal canvas objects ** protocol-specific window management and compositor functionality is now kept exclusively in backend files ** e_pixmap api provides generic client finding and rendering api ** screen/xinerama screens are now provided directly by compositor on startup and re-set on change ** e_comp_render_update finally replaced with eina_tiler ** wayland compositor no longer creates X windows ** compositor e_layout removed entirely * e_container is gone. this was made unnecessary in E18, but I kept it to avoid having too much code churn in one release. its sole purpose was to catch some events and handle window stacking, both of which are now just done by the compositor infra * e_manager is just for screensaver and keybind stuff now, possibly remove later? * e_border is gone along with a lot of its api. e_client has replaced it, and e_client has been rewritten completely; some parts may be similar, but the design now relies upon having a functional compositor ** window configuration/focus functions are all removed. all windows are now managed solely with evas_object_X functions on the "frame" member of a client, just as any other canvas object can be managed. *** do NOT set interceptors on a client's comp_object. seriously. * startup order rewritten: compositor now starts much earlier, other things just use attrs and members of the compositor * ecore_x_pointer_xy_get usage replaced with ecore_evas_pointer_xy_get * e_popup is totally gone, existing usage replaced by e_comp_object_util_add where applicable, otherwise just placed normally on the canvas * deskmirror is (more) broken for now * illume is totally fucked * Ecore_X_Window replaced with Ecore_Window in most cases * edge binding XWindows replaced with regular canvas objects * some E_Win functionality has changed such that delete callbacks are now correctly called in ALL cases. various dialogs have been updated to not crash as a result comp files and descriptions: e_comp.c - overall compositor functions, rendering/update loop, shape cutting e_comp_x.c - X window management and compositor functionality e_comp_wl.c - Wayland surface management and compositor functionality e_comp_canvas.c - general compositor canvas functions and utilities e_comp_object.c - E_Client->frame member for managing clients as Evas_Objects, utility functions for adding objects to the compositor rendering systems additional authors: ivan.briano@intel.com feature: new compositor removal: e_border, e_container, e_popup
2014-01-14 17:19:12 -08:00
if (!zone) return;
if (!e_util_strcmp(gcc->client_class->name, "systray"))
return;
e_gadcon_client_drag_set(gcc);
e_object_ref(E_OBJECT(gcc));
/* Remove this config from the current gadcon */
2012-06-20 05:43:15 -07:00
gcc->gadcon->cf->clients =
eina_list_remove(gcc->gadcon->cf->clients, gcc->cf);
gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
gcc->state_info.resist = 0;
if (!e_drop_inside(gcc->gadcon->drop_handler, x, y))
e_gadcon_client_hide(gcc);
2015-03-13 14:44:24 -07:00
ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
2012-06-20 05:43:15 -07:00
gcc->drag.drag = drag = e_drag_new(x, y,
drag_types, 1, gcc, -1, NULL,
e_gadcon_drag_finished_cb);
if (!drag) return;
o = gcc->client_class->func.icon((E_Gadcon_Client_Class *)gcc->client_class,
e_drag_evas_get(drag));
if (o)
evas_object_geometry_get(o, NULL, NULL, &w, &h);
else
{
/* FIXME: fallback icon for drag */
o = evas_object_rectangle_add(e_drag_evas_get(drag));
evas_object_color_set(o, 255, 255, 255, 100);
}
if (w < 10)
w = h = 50;
e_drag_object_set(drag, o);
e_drag_resize(drag, w, h);
e_drag_start(drag, x + w / 2, y + h / 2);
e_drag_hide(drag);
}
static void
_e_gadcon_client_inject(E_Gadcon *gc, E_Gadcon_Client *gcc, int x, int y)
{
Eina_List *l;
E_Gadcon_Client *gcc2;
Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
int i;
/* Check if the gadcon client is in place */
if (!gcc->hidden)
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
evas_object_geometry_get(gcc->o_frame, &cx, &cy, &cw, &ch);
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, &cx, &cy, &cw, &ch);
else return; /* make clang happy */
2012-06-20 05:43:15 -07:00
if (E_INSIDE(x, y, cx, cy, cw, ch)) return;
}
/* If x, y is not inside any gadcon client, seq will be 0 and it's position
* will later be used for placement. */
gcc->state_info.seq = 0;
for (i = 0; i < 2; i++)
{
/* two passes:
* - find sequence position to inject
* - update other gadget sequences
*/
EINA_LIST_FOREACH(gc->clients, l, gcc2)
2012-06-20 05:43:15 -07:00
{
if (gcc == gcc2) continue;
if (i == 1)
2012-06-20 05:43:15 -07:00
{
/* on second pass, increment all sequence numbers which are
* >= the injected gadget's sequence to get ordering right
*/
if (gcc2->state_info.seq >= gcc->state_info.seq)
gcc2->state_info.seq++;
continue;
2012-06-20 05:43:15 -07:00
}
if (gcc2->hidden) continue;
if (gcc2->o_frame)
evas_object_geometry_get(gcc2->o_frame, &cx, &cy, &cw, &ch);
else if (gcc2->o_base)
evas_object_geometry_get(gcc2->o_base, &cx, &cy, &cw, &ch);
else return; /* make clang happy */
if (e_gadcon_layout_orientation_get(gc->o_container))
2012-06-20 05:43:15 -07:00
{
/* inside left half of gadget */
if (E_INSIDE(x, y, cx, cy, cw / 2, ch))
{
/* place before */
gcc->state_info.seq = gcc2->state_info.seq;
break;
}
/* inside right half of gadget */
else if (E_INSIDE(x, y, cx + cw / 2, cy, cw / 2, ch))
{
/* place after */
gcc->state_info.seq = gcc2->state_info.seq + 1;
break;
}
2012-06-20 05:43:15 -07:00
}
else
{
/* top half of gadget */
if (E_INSIDE(x, y, cx, cy, cw, ch / 2))
{
/* place before */
gcc->state_info.seq = gcc2->state_info.seq;
break;
}
/* bottom half of gadget */
else if (E_INSIDE(x, y, cx, cy + ch / 2, cw, ch / 2))
{
/* place after */
gcc->state_info.seq = gcc2->state_info.seq + 1;
break;
}
2012-06-20 05:43:15 -07:00
}
}
}
}
static void
_e_gadcon_cb_min_size_request(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon *gc;
gc = data;
if (gc->min_size_request.func)
{
2012-06-20 05:43:15 -07:00
Evas_Coord w = 0, h = 0;
2012-06-20 05:43:15 -07:00
e_gadcon_layout_min_size_get(gc->o_container, &w, &h);
gc->min_size_request.func(gc->min_size_request.data, gc, w, h);
}
}
static void
_e_gadcon_cb_size_request(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon *gc;
gc = data;
if (gc->resize_request.func)
{
2012-06-20 05:43:15 -07:00
Evas_Coord w = 0, h = 0;
2012-06-20 05:43:15 -07:00
e_gadcon_layout_asked_size_get(gc->o_container, &w, &h);
gc->resize_request.func(gc->resize_request.data, gc, w, h);
}
}
static void
_e_gadcon_cb_moveresize(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon *gc;
Evas_Coord x, y, w, h;
gc = data;
evas_object_geometry_get(gc->o_container, &x, &y, &w, &h);
2012-06-20 05:43:15 -07:00
if (gc->drop_handler)
e_drop_handler_geometry_set(gc->drop_handler, x, y, w, h);
}
static void
_e_gadcon_cb_client_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
{
Evas_Event_Mouse_Down *ev;
E_Gadcon_Client *gcc;
gcc = data;
ev = event_info;
if (ev->button == 3)
{
2012-06-20 05:43:15 -07:00
E_Zone *zone;
E_Menu *mn;
E_Menu_Item *mi;
int cx, cy;
2015-03-13 14:47:36 -07:00
zone = e_zone_current_get();
2012-06-20 05:43:15 -07:00
e_gadcon_locked_set(gcc->gadcon, 1);
mn = e_menu_new();
e_menu_post_deactivate_callback_set(mn, _e_gadcon_client_cb_menu_post,
gcc);
gcc->menu = mn;
2012-06-20 05:43:15 -07:00
mi = e_menu_item_new(mn);
e_menu_item_label_set(mi, _("Stop moving"));
e_util_menu_item_theme_icon_set(mi, "enlightenment/edit");
e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_edit, gcc);
2012-06-20 05:43:15 -07:00
if (gcc->gadcon->menu_attach.func)
{
mi = e_menu_item_new(mn);
e_menu_item_separator_set(mi, 1);
2012-06-20 05:43:15 -07:00
gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data,
gcc, mn);
if (gcc->gadcon->shelf) e_shelf_locked_set(gcc->gadcon->shelf, 0);
2012-06-20 05:43:15 -07:00
}
2012-06-20 05:43:15 -07:00
if (gcc->gadcon->toolbar)
2015-03-13 14:44:24 -07:00
ecore_evas_pointer_xy_get(e_comp->ee, &cx, &cy);
2012-06-20 05:43:15 -07:00
else
{
e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, NULL, NULL);
cx = cx + ev->output.x;
cy = cy + ev->output.y;
}
e_menu_activate_mouse(mn, zone, cx, cy, 1, 1,
E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
}
}
static void
_e_gadcon_cb_client_mouse_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
edje_object_signal_emit(gcc->o_control, "e,state,focused", "e");
}
static void
_e_gadcon_cb_client_mouse_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
edje_object_signal_emit(gcc->o_control, "e,state,unfocused", "e");
}
static void
_e_gadcon_cb_client_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
Evas_Coord x, y;
gcc = data;
evas_object_geometry_get(obj, &x, &y, NULL, NULL);
if (gcc->o_control) evas_object_move(gcc->o_control, x, y);
if (gcc->o_event) evas_object_move(gcc->o_event, x, y);
}
static void
_e_gadcon_cb_client_resize(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
Evas_Coord w, h;
gcc = data;
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
if (gcc->o_control) evas_object_resize(gcc->o_control, w, h);
if (gcc->o_event) evas_object_resize(gcc->o_event, w, h);
}
static void
_e_gadcon_client_move_start(E_Gadcon_Client *gcc)
{
2013-12-04 20:05:50 -08:00
int x, y, gy, gx;
2012-06-20 05:43:15 -07:00
evas_object_raise(gcc->o_event);
evas_object_stack_below(gcc->o_control, gcc->o_event);
gcc->moving = 1;
evas_object_geometry_get(gcc->gadcon->o_container, &gx, &gy, NULL, NULL);
if (gcc->gadcon->toolbar)
evas_pointer_canvas_xy_get(gcc->gadcon->evas, &gcc->dx, &gcc->dy);
else
{
ecore_evas_pointer_xy_get(e_comp->ee, &gcc->dx, &gcc->dy);
2013-12-04 20:05:50 -08:00
gcc->dx -= gx;
gcc->dy -= gy;
}
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
evas_object_geometry_get(gcc->o_frame, &x, &y, NULL, NULL);
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, &x, &y, NULL, NULL);
2009-12-06 11:42:41 -08:00
else
return;
/* using drag pos to calc offset between pointer and gcc pos */
gcc->drag.x = x - (gcc->dx + gx);
gcc->drag.y = y - (gcc->dy + gy);
gcc->state_info.resist = 0;
}
static void
_e_gadcon_client_move_stop(E_Gadcon_Client *gcc)
{
gcc->moving = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
gcc->state_info.resist = 0;
_e_gadcon_layout_smart_sync_clients(gcc->gadcon);
}
static void
_e_gadcon_client_move_go(E_Gadcon_Client *gcc)
{
Evas_Coord x, y, w, h;
int cx, cy;
int gx, gy, gw, gh;
int changes = 0;
2012-06-20 05:43:15 -07:00
if (!gcc->moving) return;
/* we need to get output not canvas because things like systray
can reparent another window so we get no position here */
/* maybe we should better grab mouse while move resize is active...*/
//evas_pointer_canvas_xy_get(gcc->gadcon->evas, &cx, &cy);
if (gcc->gadcon->toolbar)
evas_pointer_canvas_xy_get(gcc->gadcon->evas, &cx, &cy);
else
ecore_evas_pointer_xy_get(e_comp->ee, &cx, &cy);
2012-06-20 05:43:15 -07:00
evas_object_geometry_get(gcc->gadcon->o_container, &gx, &gy, &gw, &gh);
cx -= gx;
cy -= gy;
2012-06-20 05:43:15 -07:00
x = cx - gcc->dx;
2012-06-20 05:43:15 -07:00
y = cy - gcc->dy;
gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION | E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
_e_gadcon_client_current_position_sync(gcc);
2013-12-04 20:06:57 -08:00
if ((cy + e_config->drag_resist < 0 || cy - e_config->drag_resist >= gh) ||
(cx + e_config->drag_resist < 0 || cx - e_config->drag_resist > gw))
{
_e_gadcon_client_drag_begin(gcc, cx, cy);
return;
}
if (gcc->o_frame)
evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
2009-12-06 11:42:41 -08:00
else
2012-06-20 05:43:15 -07:00
return; /* make clang happy */
if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
2012-06-20 05:43:15 -07:00
{
/* DRAG RIGHT */
if (x > 0 && (cx + gcc->drag.x > gcc->config.pos))
2012-06-20 05:43:15 -07:00
{
if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_INC)
gcc->state_info.resist = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_INC;
changes = 1;
}
/* DRAG LEFT */
else if (x < 0 && (cx + gcc->drag.x < gcc->config.pos))
2012-06-20 05:43:15 -07:00
{
if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_DEC)
gcc->state_info.resist = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_DEC;
changes = 1;
}
if (changes)
{
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, cx + gcc->drag.x, w);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, cx + gcc->drag.x, w);
gcc->config.size = w;
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = w;
}
}
else
{
/* DRAG DOWN */
2012-06-20 05:43:15 -07:00
if (y > 0 && (cy + gcc->drag.y > gcc->config.pos))
{
if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_INC)
gcc->state_info.resist = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_INC;
changes = 1;
}
/* DRAG UP */
2012-06-20 05:43:15 -07:00
else if (y < 0 && (cy + gcc->drag.y < gcc->config.pos))
{
if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_DEC)
gcc->state_info.resist = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_DEC;
changes = 1;
}
if (changes)
{
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, cy + gcc->drag.y, h);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, cy + gcc->drag.y, h);
gcc->config.size = h;
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = h;
}
}
gcc->dx += x;
gcc->dy += y;
}
static void
_e_gadcon_cb_signal_move_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadcon_client_move_start(data);
}
static void
_e_gadcon_cb_signal_move_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadcon_client_move_stop(data);
}
static void
_e_gadcon_cb_signal_move_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadcon_client_move_go(data);
}
static void
_e_gadcon_client_resize_start(E_Gadcon_Client *gcc)
{
evas_object_raise(gcc->o_event);
evas_object_stack_below(gcc->o_control, gcc->o_event);
gcc->resizing = 1;
evas_pointer_canvas_xy_get(gcc->gadcon->evas, &gcc->dx, &gcc->dy);
}
static void
_e_gadconclient_resize_stop(E_Gadcon_Client *gcc)
{
gcc->resizing = 0;
gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
_e_gadcon_layout_smart_sync_clients(gcc->gadcon);
_e_gadcon_client_save(gcc);
}
static void
_e_gadcon_cb_signal_resize_left_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadcon_client_resize_start(data);
}
static void
_e_gadcon_cb_signal_resize_left_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadconclient_resize_stop(data);
}
static void
_e_gadcon_cb_signal_resize_left_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Gadcon_Client *gcc;
Evas_Coord x, y, w, h;
gcc = data;
if (!gcc->resizing) return;
evas_pointer_canvas_xy_get(gcc->gadcon->evas, &x, &y);
x = x - gcc->dx;
y = y - gcc->dy;
2012-06-20 05:43:15 -07:00
gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION |
E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
if (gcc->o_frame)
evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
2012-06-20 05:43:15 -07:00
else return; /* make clang happy */
_e_gadcon_client_current_position_sync(gcc);
if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
{
2012-06-20 05:43:15 -07:00
if (x > 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC;
else if (x < 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC;
}
else
{
2012-06-20 05:43:15 -07:00
if (y > 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC;
else if (y < 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC;
}
if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos + x, w - x);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos + x, w - x);
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = w;
}
else
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos + y, h - y);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos + y, h - y);
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = h;
}
gcc->dx += x;
gcc->dy += y;
}
static void
_e_gadcon_cb_signal_resize_right_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadcon_client_resize_start(data);
}
static void
_e_gadcon_cb_signal_resize_right_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
_e_gadconclient_resize_stop(data);
}
static void
_e_gadcon_cb_signal_resize_right_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Gadcon_Client *gcc;
Evas_Coord x, y, w, h;
gcc = data;
if (!gcc->resizing) return;
evas_pointer_canvas_xy_get(gcc->gadcon->evas, &x, &y);
x = x - gcc->dx;
y = y - gcc->dy;
2012-06-20 05:43:15 -07:00
gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION |
E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
if (gcc->o_frame)
evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
else if (gcc->o_base)
evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
2012-06-20 05:43:15 -07:00
else return; /* make clang happy */
_e_gadcon_client_current_position_sync(gcc);
if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
{
2012-06-20 05:43:15 -07:00
if (x > 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
else if (x < 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC;
}
else
{
2012-06-20 05:43:15 -07:00
if (y > 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
else if (y < 0)
gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
}
if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos, w + x);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos, w + x);
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = w;
}
else
{
2012-06-20 05:43:15 -07:00
if (gcc->o_frame)
e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos, h + y);
else if (gcc->o_base)
e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos, h + y);
evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
gcc->config.res = h;
}
gcc->dx += x;
gcc->dy += y;
}
static void
_e_gadcon_cb_dnd_enter(void *data, const char *type __UNUSED__, void *event)
{
E_Event_Dnd_Enter *ev;
E_Gadcon *gc;
E_Gadcon_Client *gcc;
ev = event;
gc = data;
2012-09-17 05:24:17 -07:00
//INF("DND ENTER");
gcc = gc->drag_gcc;
if (!gcc) return; // dnd from efm or something
if ((!gcc->hidden) && (gcc->gadcon == gc))
{
if (gc->dnd_enter_cb) gc->dnd_enter_cb(gc, gc->drag_gcc);
e_drag_hide(gc->drag_gcc->drag.drag);
return;
}
if (gcc->gadcon != gc)
e_gadcon_client_hide(gc->drag_gcc);
else if (e_gadcon_site_is_desktop(gcc->gadcon->location->site))
{
e_gadcon_client_show(gc->drag_gcc);
e_drag_hide(gc->drag_gcc->drag.drag);
if (gc->dnd_enter_cb) gc->dnd_enter_cb(gc, gc->drag_gcc);
return;
}
e_gadcon_layout_freeze(gc->o_container);
if (gc->new_gcc)
{
e_object_del(E_OBJECT(gc->new_gcc));
gc->new_gcc = NULL;
}
2012-10-01 01:54:36 -07:00
while (ev->data)
{
2012-06-20 05:43:15 -07:00
/* Create a new gadcon to show where the gadcon will end up */
E_Gadcon_Client_Class *cc;
2012-06-20 05:43:15 -07:00
gcc = ev->data;
cc = eina_hash_find(providers, gcc->name);
2012-10-01 01:54:36 -07:00
if (!cc) break;
if (!gcc->style)
gc->new_gcc = cc->func.init(gc, gcc->name, gcc->cf->id,
cc->default_style);
2012-10-01 01:54:36 -07:00
else
gc->new_gcc = cc->func.init(gc, gcc->name, gcc->cf->id,
gcc->style);
2012-10-01 01:54:36 -07:00
if (!gc->new_gcc) break;
gc->new_gcc->cf = gcc->cf;
gc->new_gcc->client_class = cc;
gc->new_gcc->config.pos = gcc->config.pos;
gc->new_gcc->config.size = gcc->config.size;
gc->new_gcc->config.res = gcc->config.res;
gc->new_gcc->state_info.seq = gcc->state_info.seq;
gc->new_gcc->state_info.flags = gcc->state_info.flags;
gc->new_gcc->config.pos_x = gcc->config.pos_x;
gc->new_gcc->config.pos_y = gcc->config.pos_y;
gc->new_gcc->config.size_w = gcc->config.size_w;
gc->new_gcc->config.size_h = gcc->config.size_h;
if (gc->new_gcc->client_class->func.orient)
2012-06-20 05:43:15 -07:00
{
2012-10-01 01:54:36 -07:00
if (gc->orient == E_GADCON_ORIENT_FLOAT)
{
gc->new_gcc->client_class->func.orient(gc->new_gcc, gcc->gadcon->orient);
gc->new_gcc->cf->orient = gcc->gadcon->orient;
}
2012-06-20 05:43:15 -07:00
else
{
2012-10-01 01:54:36 -07:00
gc->new_gcc->client_class->func.orient(gc->new_gcc, gc->orient);
gc->new_gcc->cf->orient = gc->orient;
}
}
if (gc->new_gcc->o_frame)
e_gadcon_layout_pack_options_set(gc->new_gcc->o_frame, gc->new_gcc);
else if (gc->new_gcc->o_base)
{
e_gadcon_layout_pack_options_set(gc->new_gcc->o_base, gc->new_gcc);
if (!gc->o_container)
{
int w, h, gw, gh;
w = gc->zone->w;
h = gc->zone->h;
if ((!gc->new_gcc->config.pos_x) && (!gc->new_gcc->config.pos_y))
{
2012-10-01 01:54:36 -07:00
gc->new_gcc->config.pos_x = (double)ev->x / (double)w;
gc->new_gcc->config.pos_y = (double)ev->y / (double)h;
}
2012-10-01 01:54:36 -07:00
if ((!gc->new_gcc->config.size_w) && (!gc->new_gcc->config.size_h))
{
evas_object_geometry_get(gcc->o_frame ? : gcc->o_base, NULL, NULL, &gw, &gh);
2012-10-01 01:54:36 -07:00
gc->new_gcc->config.size_w = (double)gw / (double)w;
gc->new_gcc->config.size_h = (double)gh / (double)h;
}
2012-10-01 01:54:36 -07:00
else
{
gw = gc->new_gcc->config.size_w * w;
gh = gc->new_gcc->config.size_h * h;
}
evas_object_resize(gc->new_gcc->o_base, gw, gh);
evas_object_move(gc->new_gcc->o_base, ev->x, ev->y);
2012-06-20 05:43:15 -07:00
}
}
2012-10-01 01:54:36 -07:00
e_drag_hide(gc->drag_gcc->drag.drag);
2012-10-01 01:54:36 -07:00
e_gadcon_client_edit_begin(gc->new_gcc);
e_gadcon_client_autoscroll_set(gc->new_gcc, gcc->autoscroll);
/* e_gadcon_client_resizable_set(gc->new_gcc, gcc->resizable);*/
gc->new_gcc->state_info.resist = 1;
if (gc->instant_edit)
e_gadcon_client_util_menu_attach(gc->new_gcc);
break;
}
e_gadcon_layout_thaw(gc->o_container);
if (gc->dnd_enter_cb) gc->dnd_enter_cb(gc, gc->drag_gcc);
}
static void
_e_gadcon_cb_dnd_move(void *data, const char *type __UNUSED__, void *event)
{
E_Event_Dnd_Move *ev;
E_Gadcon *gc;
E_Gadcon_Client *gcc = NULL;
int dx = 0, dy = 0;
2012-09-12 08:02:12 -07:00
Evas_Object *o;
ev = event;
gc = data;
2012-10-01 07:07:37 -07:00
//INF("DND (%d,%d)", ev->x, ev->y);
gcc = gc->new_gcc ? : gc->drag_gcc;
2012-09-12 08:02:12 -07:00
if (!gcc) return;
if (gcc->state_info.resist > 0)
{
2012-09-12 08:02:12 -07:00
gcc->state_info.resist--;
return;
}
e_gadcon_layout_freeze(gc->o_container);
2012-06-20 05:43:15 -07:00
2012-09-12 08:02:12 -07:00
if (e_gadcon_layout_orientation_get(gc->o_container))
gcc->config.pos = ev->x - gcc->config.size / 2;
else
gcc->config.pos = ev->y - gcc->config.size / 2;
if (!gcc->gadcon->o_container)
{
int w, h;
w = gc->zone->w;
h = gc->zone->h;
gcc->config.pos_x = (double)ev->x / (double)w;
gcc->config.pos_y = (double)ev->y / (double)h;
if (gcc->o_frame) evas_object_move(gcc->o_frame, ev->x, ev->y);
else if (gcc->o_base)
evas_object_move(gcc->o_base, ev->x, ev->y);
}
2012-09-12 08:02:12 -07:00
_e_gadcon_client_inject(gc, gcc, ev->x + dx, ev->y + dy);
o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
if (o)
e_gadcon_layout_pack_request_set(o, gcc->config.pos,
gcc->config.size);
2012-09-12 08:02:12 -07:00
e_gadcon_layout_thaw(gc->o_container);
if (gc->dnd_move_cb) gc->dnd_move_cb(gc, gcc);
}
static void
_e_gadcon_cb_dnd_leave(void *data, const char *type __UNUSED__, void *event __UNUSED__)
{
E_Gadcon *gc;
gc = data;
2012-09-17 05:24:17 -07:00
//INF("DND LEAVE");
/* If we exit the starting container hide the gadcon visual */
if (gc->drag_gcc->gadcon == gc) e_gadcon_client_hide(gc->drag_gcc);
/* Delete temporary object */
if (!gc->new_gcc)
{
if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, gc->drag_gcc);
return;
}
2012-09-17 05:24:17 -07:00
//INF("DELETING new_gcc");
e_object_del(E_OBJECT(gc->new_gcc));
gc->new_gcc = NULL;
e_drag_show(gc->drag_gcc->drag.drag);
if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, gc->drag_gcc);
}
static void
_e_gadcon_cb_dnd_drop(void *data, const char *type __UNUSED__, void *event __UNUSED__)
{
E_Gadcon *gc;
E_Gadcon_Client *gcc = NULL;
gc = data;
2012-09-17 05:24:17 -07:00
//INF("DND DROP");
gc->cf->clients = eina_list_append(gc->cf->clients, gc->drag_gcc->cf);
if (!gc->new_gcc)
{
/* using drag_gcc, so do things a bit differently
* this only happens with gadman dnd, broken on shelves
*/
_e_gadcon_client_save(gc->drag_gcc);
e_gadcon_client_show(gc->drag_gcc);
if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
return;
}
gcc = gc->new_gcc;
if (!gc->o_container)
{
/* FIXME: gadman sucks and should probably use a regular gadcon layout, but it doesn't
* so we need to repop here
*/
gcc->cf = gc->drag_gcc->cf;
_e_gadcon_client_save(gc->new_gcc);
e_object_del(E_OBJECT(gc->new_gcc));
gc->new_gcc = NULL;
/* this little hack prevents the dead gcc from overwriting our config */
gc->drag_gcc->moving = 0;
e_gadcon_custom_populate_request(gc);
e_config_save_queue();
if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
goto cleanup;
}
if (gc->editing) e_gadcon_client_edit_begin(gc->new_gcc);
gc->new_gcc = NULL;
e_config_save_queue();
if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
cleanup:
/* still has refcount from drag */
e_object_del(E_OBJECT(gc->drag_gcc));
gc->drag_gcc = NULL;
}
static int
_e_gadcon_client_class_feature_check(const E_Gadcon_Client_Class *cc, const char *name, void *feature)
{
if (!feature)
{
e_util_dialog_show(_("Insufficent gadcon support"),
_("Module %s needs to support %s"),
2012-06-20 05:43:15 -07:00
cc->name, name);
return 0;
}
return 1;
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_client_cb_menu_post(void *data, E_Menu *m)
{
E_Gadcon_Client *gcc;
if (!(gcc = data)) return;
if (gcc->gadcon) e_gadcon_locked_set(gcc->gadcon, 0);
if (gcc->menu != m)
{
e_object_del(E_OBJECT(m));
return;
}
if (gcc->gadcon && gcc->gadcon->shelf && (gcc->menu == gcc->gadcon->shelf->menu)) gcc->gadcon->shelf->menu = NULL;
e_object_del(E_OBJECT(gcc->menu));
gcc->menu = NULL;
}
static Eina_Bool
_e_gadcon_client_cb_instant_edit_timer(void *data)
{
E_Gadcon_Client *gcc;
gcc = data;
e_gadcon_client_edit_begin(gcc);
_e_gadcon_client_move_start(gcc);
gcc->instant_edit_timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
static void
_e_gadcon_client_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
{
Evas_Event_Mouse_Down *ev;
E_Gadcon_Client *gcc;
ev = event_info;
gcc = data;
if (gcc->menu) return;
if (ev->button == 3)
{
2012-06-20 05:43:15 -07:00
E_Menu *m;
2009-01-21 20:42:16 -08:00
E_Zone *zone;
2012-06-20 05:43:15 -07:00
int cx, cy, cw, ch;
2012-06-20 05:43:15 -07:00
e_gadcon_locked_set(gcc->gadcon, 1);
m = e_menu_new();
2012-06-20 05:43:15 -07:00
m = e_gadcon_client_util_menu_items_append(gcc, m, 0);
e_menu_post_deactivate_callback_set(m, _e_gadcon_client_cb_menu_post,
gcc);
gcc->menu = m;
if (gcc->gadcon->shelf) gcc->gadcon->shelf->menu = m;
2012-06-20 05:43:15 -07:00
e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, &cw, &ch);
2009-01-21 20:42:16 -08:00
zone = gcc->gadcon->zone;
2015-03-13 14:47:36 -07:00
if (!zone) zone = e_zone_current_get();
2012-06-20 05:43:15 -07:00
e_menu_activate_mouse(m, zone,
cx + ev->output.x,
2009-01-21 20:42:16 -08:00
cy + ev->output.y, 1, 1,
2012-06-20 05:43:15 -07:00
E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
}
else if (ev->button == 2)
{
if (gcc->instant_edit_timer)
ecore_timer_del(gcc->instant_edit_timer);
gcc->instant_edit_timer = NULL;
e_gadcon_client_edit_begin(gcc);
_e_gadcon_client_move_start(gcc);
}
else if (ev->button == 1)
{
2012-06-20 05:43:15 -07:00
if ((!gcc->o_control) && (gcc->gadcon->instant_edit))
{
if (gcc->instant_edit_timer)
ecore_timer_del(gcc->instant_edit_timer);
2012-06-20 05:43:15 -07:00
gcc->instant_edit_timer =
ecore_timer_add(1.0, _e_gadcon_client_cb_instant_edit_timer,
gcc);
}
}
}
static void
_e_gadcon_client_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
{
Evas_Event_Mouse_Up *ev;
E_Gadcon_Client *gcc;
ev = event_info;
gcc = data;
if ((ev->button == 1) && (gcc->gadcon->instant_edit))
{
2012-06-20 05:43:15 -07:00
if (gcc->instant_edit_timer)
{
ecore_timer_del(gcc->instant_edit_timer);
gcc->instant_edit_timer = NULL;
}
if (gcc->o_control)
{
_e_gadcon_client_move_stop(gcc);
e_gadcon_client_edit_end(gcc);
}
}
else if (ev->button == 2)
{
if (gcc->o_control)
{
_e_gadcon_client_move_stop(gcc);
e_gadcon_client_edit_end(gcc);
}
}
}
static void
_e_gadcon_client_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
if ((gcc->gadcon->instant_edit))
{
2012-06-20 05:43:15 -07:00
if (gcc->o_control) _e_gadcon_client_move_go(gcc);
}
}
static void
_e_gadcon_client_cb_menu_style_plain(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon_Client *gcc;
E_Gadcon *gc;
gcc = data;
gc = gcc->gadcon;
eina_stringshare_replace(&gcc->style, E_GADCON_CLIENT_STYLE_PLAIN);
_e_gadcon_client_save(gcc);
e_gadcon_unpopulate(gc);
e_gadcon_populate(gc);
}
static void
_e_gadcon_client_cb_menu_style_inset(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon_Client *gcc;
E_Gadcon *gc;
gcc = data;
gc = gcc->gadcon;
eina_stringshare_replace(&gcc->style, E_GADCON_CLIENT_STYLE_INSET);
_e_gadcon_client_save(gcc);
e_gadcon_unpopulate(gc);
e_gadcon_populate(gc);
}
static void
_e_gadcon_client_cb_menu_autoscroll(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
e_gadcon_layout_freeze(gcc->gadcon->o_container);
if (gcc->autoscroll) gcc->autoscroll = 0;
2012-06-20 05:43:15 -07:00
else gcc->autoscroll = 1;
e_gadcon_client_autoscroll_set(gcc, gcc->autoscroll);
_e_gadcon_client_save(gcc);
e_gadcon_layout_thaw(gcc->gadcon->o_container);
}
2012-06-20 05:43:15 -07:00
/*
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_client_cb_menu_resizable(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
e_gadcon_layout_freeze(gcc->gadcon->o_container);
if (gcc->resizable) gcc->resizable = 0;
else gcc->resizable = 1;
e_gadcon_client_resizable_set(gcc, gcc->resizable);
_e_gadcon_client_save(gcc);
e_gadcon_layout_thaw(gcc->gadcon->o_container);
2012-06-20 05:43:15 -07:00
}
*/
static void
_e_gadcon_client_cb_menu_edit(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
if (gcc->o_control)
e_gadcon_client_edit_end(gcc);
else
e_gadcon_client_edit_begin(gcc);
}
static void
_e_gadcon_client_cb_menu_remove(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{
E_Gadcon *gc;
E_Gadcon_Client *gcc;
gcc = data;
gc = gcc->gadcon;
e_gadcon_client_config_del(gc->cf, gcc->cf);
gcc->cf = NULL;
e_object_del(E_OBJECT(gcc));
if (!gc->custom)
{
e_gadcon_unpopulate(gc);
e_gadcon_populate(gc);
}
e_config_save_queue();
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_client_cb_menu_pre(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi)
{
E_Gadcon_Client *gcc;
if (!(gcc = data)) return;
2012-06-20 05:43:15 -07:00
if (gcc->client_class->func.icon)
{
// e menu ASSUMES... EXPECTS the icon to be an.... e_icon!
// if it's not, spankies for whoever wrote the icon callback!
mi->icon_object =
gcc->client_class->func.icon((E_Gadcon_Client_Class *)gcc->client_class,
mi->menu->evas);
}
else
2012-06-20 05:43:15 -07:00
e_util_menu_item_theme_icon_set(mi, "preferences-gadget"); // FIXME: Needs icon in theme
}
static void
_e_gadcon_client_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
E_Gadcon_Client *gcc;
gcc = data;
gcc->o_base = NULL;
e_object_del(E_OBJECT(gcc));
}
2006-02-05 01:29:47 -08:00
/* a smart object JUST for gadcon */
2012-06-20 05:43:15 -07:00
typedef struct _E_Gadcon_Layout_Item E_Gadcon_Layout_Item;
struct _E_Smart_Data
2012-06-20 05:43:15 -07:00
{
Evas_Coord x, y, w, h;
Evas_Object *obj, *clip;
unsigned char horizontal : 1;
unsigned char doing_config : 1;
unsigned char redo_config : 1;
2012-06-20 05:43:15 -07:00
Eina_List *items;
int frozen;
Evas_Coord minw, minh, req;
};
struct _E_Gadcon_Layout_Item
{
2012-06-20 05:43:15 -07:00
E_Smart_Data *sd;
struct
{
int pos, size, size2, res, prev_pos, prev_size;
} ask;
int hookp;
struct
{
int w, h;
} min, aspect, aspect_pad;
E_Gadcon_Client *gcc;
2012-06-20 05:43:15 -07:00
Evas_Coord x, y, w, h;
Evas_Object *obj;
unsigned char can_move : 1;
};
/* local subsystem functions */
static E_Gadcon_Layout_Item *_e_gadcon_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
2012-06-20 05:43:15 -07:00
static void _e_gadcon_layout_smart_disown(Evas_Object *obj);
static void _e_gadcon_layout_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_gadcon_layout_smart_reconfigure(E_Smart_Data *sd);
static void _e_gadcon_layout_smart_init(void);
static void _e_gadcon_layout_smart_add(Evas_Object *obj);
static void _e_gadcon_layout_smart_del(Evas_Object *obj);
static void _e_gadcon_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
static void _e_gadcon_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
static void _e_gadcon_layout_smart_show(Evas_Object *obj);
static void _e_gadcon_layout_smart_hide(Evas_Object *obj);
static void _e_gadcon_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
static void _e_gadcon_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
static void _e_gadcon_layout_smart_clip_unset(Evas_Object *obj);
static void _e_gadcon_layout_smart_min_cur_size_calc(E_Smart_Data *sd, int *min, int *mino, int *cur);
static void _e_gadcon_layout_smart_gadcons_width_adjust(E_Smart_Data *sd, int min, int cur);
static int _e_gadcon_layout_smart_sort_by_sequence_number_cb(const void *d1, const void *d2);
static int _e_gadcon_layout_smart_sort_by_position_cb(const void *d1, const void *d2);
/* local subsystem globals */
static Evas_Smart *_e_smart = NULL;
/* externally accessible functions */
static Evas_Object *
e_gadcon_layout_add(Evas *evas)
2012-06-20 05:43:15 -07:00
{
_e_gadcon_layout_smart_init();
return evas_object_smart_add(evas, _e_smart);
}
static void
e_gadcon_layout_orientation_set(Evas_Object *obj, int horizontal)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
2012-06-20 05:43:15 -07:00
if (((sd->horizontal) && (horizontal)) ||
((!sd->horizontal) && (!horizontal))) return;
sd->horizontal = horizontal;
_e_gadcon_layout_smart_reconfigure(sd);
}
static int
e_gadcon_layout_orientation_get(Evas_Object *obj)
{
E_Smart_Data *sd;
2006-07-28 04:31:50 -07:00
if (!obj) return 0;
sd = evas_object_smart_data_get(obj);
if (!sd) return 0;
return sd->horizontal;
}
static void
e_gadcon_layout_freeze(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->frozen++;
}
static void
e_gadcon_layout_thaw(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->frozen--;
_e_gadcon_layout_smart_reconfigure(sd);
}
2006-02-05 01:29:47 -08:00
static void
e_gadcon_layout_min_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
{
E_Smart_Data *sd;
2012-06-20 05:43:15 -07:00
/*
Eina_List *l;
Evas_Object *obj;
2006-02-05 01:29:47 -08:00
Evas_Coord tw = 0, th = 0;
*/
if (!obj) return;
2006-02-05 01:29:47 -08:00
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->horizontal)
{
2012-06-20 05:43:15 -07:00
if (w) *w = sd->minw;
if (h) *h = sd->minh;
}
else
{
2012-06-20 05:43:15 -07:00
if (w) *w = sd->minh;
if (h) *h = sd->minw;
}
2012-06-20 05:43:15 -07:00
/*
EINA_LIST_FOREACH(sd->items, l, obj)
2006-02-05 01:29:47 -08:00
{
2012-06-20 05:43:15 -07:00
E_Gadcon_Layout_Item *bi;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (sd->horizontal)
{
tw += bi->min.w;
if (bi->min.h > th) th = bi->min.h;
}
else
{
th += bi->min.h;
if (bi->min.w > tw) tw = bi->min.w;
}
2006-02-05 01:29:47 -08:00
}
if (w) *w = tw;
if (h) *h = th;
*/
2006-02-05 01:29:47 -08:00
}
static void
e_gadcon_layout_asked_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
{
E_Smart_Data *sd;
Evas_Coord tw = 0, th = 0;
if (!obj) return;
2006-02-05 01:29:47 -08:00
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->horizontal)
tw = sd->req;
else
th = sd->req;
2012-06-20 05:43:15 -07:00
/*
Evas_Object *obj;
EINA_LIST_FOREACH(sd->items, l, obj)
2006-02-05 01:29:47 -08:00
{
2012-06-20 05:43:15 -07:00
E_Gadcon_Layout_Item *bi;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (sd->horizontal)
{
tw += bi->ask.size;
}
else
{
th += bi->ask.size;
}
2006-02-05 01:29:47 -08:00
}
*/
2006-02-05 01:29:47 -08:00
if (w) *w = tw;
if (h) *h = th;
}
static int
e_gadcon_layout_pack(Evas_Object *obj, Evas_Object *child)
{
E_Smart_Data *sd;
if (!obj) return 0;
sd = evas_object_smart_data_get(obj);
if (!sd) return 0;
_e_gadcon_layout_smart_adopt(sd, child);
sd->items = eina_list_prepend(sd->items, child);
_e_gadcon_layout_smart_reconfigure(sd);
return 0;
}
static void
e_gadcon_layout_pack_size_set(Evas_Object *obj, int size)
{
/*
* FIXME:
* simplify this function until the is redone
* _e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd)
*/
E_Gadcon_Layout_Item *bi;
int pos;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) return;
pos = bi->ask.pos + (bi->ask.size / 2);
if (pos < (bi->ask.res / 3))
2012-06-20 05:43:15 -07:00
{
/* hooked to start */
2012-06-20 05:43:15 -07:00
bi->ask.size = size;
2006-02-05 01:29:47 -08:00
}
else if (pos > ((2 * bi->ask.res) / 3))
2012-06-20 05:43:15 -07:00
{
/* hooked to end */
2012-06-20 05:43:15 -07:00
bi->ask.pos = (bi->ask.pos + bi->ask.size) - size;
bi->ask.size = size;
2006-02-05 01:29:47 -08:00
}
else
2012-06-20 05:43:15 -07:00
{
/* hooked to middle */
2012-06-20 05:43:15 -07:00
if ((bi->ask.pos <= (bi->ask.res / 2)) &&
((bi->ask.pos + bi->ask.size) > (bi->ask.res / 2)))
{
/* straddles middle */
2012-06-20 05:43:15 -07:00
if (bi->ask.res > 2)
bi->ask.pos = (bi->ask.res / 2) +
(((bi->ask.pos + (bi->ask.size / 2) -
(bi->ask.res / 2)) *
(bi->ask.res / 2)) /
(bi->ask.res / 2)) - (bi->ask.size / 2);
else
bi->x = bi->ask.res / 2;
bi->ask.size = size;
}
else
{
if (pos < (bi->ask.res / 2))
{
bi->ask.pos = (bi->ask.pos + bi->ask.size) - size;
bi->ask.size = size;
}
else
bi->ask.size = size;
}
2006-02-05 01:29:47 -08:00
bi->ask.size = size;
}
_e_gadcon_layout_smart_reconfigure(bi->sd);
}
2006-02-05 01:29:47 -08:00
/* called when a users moves/resizes the gadcon client explicitly */
static void
2006-02-05 01:29:47 -08:00
e_gadcon_layout_pack_request_set(Evas_Object *obj, int pos, int size)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) return;
bi->ask.res = bi->sd->w;
if (pos < 0) pos = 0;
if ((bi->ask.res - pos) < size) pos = bi->ask.res - size;
bi->ask.size = size;
2006-02-05 01:29:47 -08:00
bi->ask.pos = pos;
_e_gadcon_layout_smart_reconfigure(bi->sd);
}
2006-02-05 01:29:47 -08:00
/* called when restoring config from saved config */
static void
e_gadcon_layout_pack_options_set(Evas_Object *obj, E_Gadcon_Client *gcc)
{
int ok, seq;
Eina_List *l;
Evas_Object *item;
E_Gadcon_Layout_Item *bi, *bi2;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) return;
bi->ask.res = gcc->config.res;
bi->ask.size = gcc->config.size;
bi->ask.pos = gcc->config.pos;
bi->gcc = gcc;
ok = 0;
if (!gcc->state_info.seq) ok = 1;
seq = 1;
EINA_LIST_FOREACH(bi->sd->items, l, item)
{
2012-06-20 05:43:15 -07:00
bi2 = evas_object_data_get(item, "e_gadcon_layout_data");
if (bi == bi2) continue;
if (bi->gcc->id == bi2->gcc->id) continue;
2012-06-20 05:43:15 -07:00
if (bi->gcc->state_info.seq == bi2->gcc->state_info.seq)
ok = 1;
2012-06-20 05:43:15 -07:00
if (bi2->gcc->state_info.seq > seq)
seq = bi2->gcc->state_info.seq;
}
if (ok)
2012-06-20 05:43:15 -07:00
{
gcc->state_info.seq = seq + 1;
gcc->state_info.want_save = 1;
gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_NONE;
}
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_reconfigure(bi->sd);
}
static void
e_gadcon_layout_pack_min_size_set(Evas_Object *obj, int w, int h)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi)
{
evas_object_size_hint_min_set(obj, w, h);
evas_object_size_hint_min_set(obj, w, h);
return;
}
if (bi->sd->horizontal)
{
2012-06-20 05:43:15 -07:00
bi->min.w = w;
bi->min.h = h;
}
else
{
2012-06-20 05:43:15 -07:00
bi->min.w = h;
bi->min.h = w;
}
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_reconfigure(bi->sd);
}
static void
e_gadcon_layout_pack_aspect_set(Evas_Object *obj, int w, int h)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi)
{
evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, w, h);
return;
}
if (bi->sd->horizontal)
{
2012-06-20 05:43:15 -07:00
bi->aspect.w = w;
bi->aspect.h = h;
}
else
{
2012-06-20 05:43:15 -07:00
bi->aspect.w = h;
bi->aspect.h = w;
}
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_reconfigure(bi->sd);
}
static void
e_gadcon_layout_pack_aspect_pad_set(Evas_Object *obj, int w, int h)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) return;
if (bi->sd->horizontal)
{
2012-06-20 05:43:15 -07:00
bi->aspect_pad.w = w;
bi->aspect_pad.h = h;
}
else
{
2012-06-20 05:43:15 -07:00
bi->aspect_pad.w = h;
bi->aspect_pad.h = w;
}
}
static void
e_gadcon_layout_unpack(Evas_Object *obj)
{
E_Gadcon_Layout_Item *bi;
E_Smart_Data *sd;
if (!obj) return;
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) return;
sd = bi->sd;
if (!sd) return;
sd->items = eina_list_remove(sd->items, obj);
_e_gadcon_layout_smart_disown(obj);
if (!stopping)
_e_gadcon_layout_smart_reconfigure(sd);
}
/* local subsystem functions */
static E_Gadcon_Layout_Item *
_e_gadcon_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return NULL;
bi = E_NEW(E_Gadcon_Layout_Item, 1);
if (!bi) return NULL;
bi->sd = sd;
bi->obj = obj;
/* defaults */
evas_object_clip_set(obj, sd->clip);
evas_object_smart_member_add(obj, bi->sd->obj);
evas_object_data_set(obj, "e_gadcon_layout_data", bi);
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_item_del_hook, NULL);
if ((!evas_object_visible_get(sd->clip)) &&
(evas_object_visible_get(sd->obj)))
evas_object_show(sd->clip);
return bi;
}
static void
_e_gadcon_layout_smart_disown(Evas_Object *obj)
{
E_Gadcon_Layout_Item *bi;
if (!obj) return;
bi = evas_object_data_del(obj, "e_gadcon_layout_data");
if (!bi) return;
if (!bi->sd->items)
{
2012-06-20 05:43:15 -07:00
if (evas_object_visible_get(bi->sd->clip))
evas_object_hide(bi->sd->clip);
}
evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_item_del_hook);
evas_object_smart_member_del(obj);
evas_object_clip_unset(obj);
free(bi);
}
static void
_e_gadcon_layout_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
if (!obj) return;
e_gadcon_layout_unpack(obj);
}
static void
_e_gadcon_layout_smart_reconfigure(E_Smart_Data *sd)
{
Evas_Coord xx, yy;
Eina_List *l;
Evas_Object *obj;
int min, mino, cur;
Eina_List *list = NULL;
E_Gadcon_Layout_Item *bi;
E_Layout_Item_Container *lc;
int i, set_prev_pos = 0;
static int recurse = 0;
if (sd->frozen) return;
if (sd->doing_config)
{
2012-06-20 05:43:15 -07:00
sd->redo_config = 1;
return;
}
recurse++;
min = mino = cur = 0;
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_min_cur_size_calc(sd, &min, &mino, &cur);
if ((sd->minw != min) || (sd->minh != mino))
{
2012-06-20 05:43:15 -07:00
sd->minw = min;
sd->minh = mino;
evas_object_smart_callback_call(sd->obj, "min_size_request", NULL);
}
if (sd->req != cur)
{
2012-06-20 05:43:15 -07:00
if (cur >= sd->minw)
{
sd->req = cur;
evas_object_smart_callback_call(sd->obj, "size_request", NULL);
}
else
{
sd->req = sd->minw;
}
}
if (recurse == 1) _e_gadcon_layout_smart_gadcons_width_adjust(sd, min, cur);
if (sd->w <= sd->req)
2012-06-20 05:43:15 -07:00
{
_e_gadcon_layout_smart_gadcon_position_shrinked_mode(sd);
set_prev_pos = 0;
}
else
2012-06-20 05:43:15 -07:00
{
_e_gadcon_layout_smart_gadcons_asked_position_set(sd);
2012-06-20 05:43:15 -07:00
list = _e_gadcon_layout_smart_gadcons_wrap(sd);
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_gadcons_position(sd, &list);
2012-06-20 05:43:15 -07:00
EINA_LIST_FREE(list, lc)
LC_FREE(lc);
2012-06-20 05:43:15 -07:00
set_prev_pos = 1;
}
sd->items = eina_list_sort(sd->items, eina_list_count(sd->items),
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_sort_by_position_cb);
i = 1;
EINA_LIST_FOREACH(sd->items, l, obj)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (bi->gcc->gadcon->editing) bi->gcc->state_info.seq = i;
2012-06-20 05:43:15 -07:00
if (set_prev_pos)
{
bi->ask.prev_pos = bi->x;
bi->ask.prev_size = bi->w;
}
2012-06-20 05:43:15 -07:00
if ((bi->x == bi->ask.pos) &&
(bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION))
bi->gcc->state_info.flags |= E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
2012-06-20 05:43:15 -07:00
if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
(bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE))
{
if (bi->x != bi->ask.pos)
bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
}
i++;
}
EINA_LIST_FOREACH(sd->items, l, obj)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(obj, "e_gadcon_layout_data");
if (!bi) continue;
bi->h = sd->h;
xx = sd->x + bi->x;
yy = sd->y; // + ((sd->h - bi->h) / 2);
if (sd->horizontal)
{
evas_object_move(obj, xx, yy);
evas_object_resize(obj, bi->w, bi->h);
}
else
{
evas_object_move(obj, yy, xx);
evas_object_resize(obj, bi->h, bi->w);
}
if ((recurse == 1) && bi->gcc->state_info.want_save)
{
_e_gadcon_client_save(bi->gcc);
bi->gcc->state_info.want_save = 0;
}
}
sd->doing_config = 0;
if (sd->redo_config)
{
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_reconfigure(sd);
sd->redo_config = 0;
}
if ((sd->minw != min) || (sd->minh != mino))
{
2012-06-20 05:43:15 -07:00
sd->minw = min;
sd->minh = mino;
evas_object_smart_callback_call(sd->obj, "min_size_request", NULL);
}
if (sd->req != cur)
{
2012-06-20 05:43:15 -07:00
if (cur >= sd->minw)
{
sd->req = cur;
evas_object_smart_callback_call(sd->obj, "size_request", NULL);
}
}
recurse--;
}
static void
_e_gadcon_layout_smart_init(void)
{
if (_e_smart) return;
2012-06-20 05:43:15 -07:00
{
static const Evas_Smart_Class sc =
{
"e_gadcon_layout",
EVAS_SMART_CLASS_VERSION,
_e_gadcon_layout_smart_add,
_e_gadcon_layout_smart_del,
_e_gadcon_layout_smart_move,
_e_gadcon_layout_smart_resize,
_e_gadcon_layout_smart_show,
_e_gadcon_layout_smart_hide,
_e_gadcon_layout_smart_color_set,
_e_gadcon_layout_smart_clip_set,
_e_gadcon_layout_smart_clip_unset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
_e_smart = evas_smart_class_new(&sc);
}
}
static void
_e_gadcon_layout_smart_add(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = calloc(1, sizeof(E_Smart_Data));
if (!sd) return;
sd->obj = obj;
sd->x = 0;
sd->y = 0;
sd->w = 0;
sd->h = 0;
sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
sd->horizontal = 1;
evas_object_smart_member_add(sd->clip, obj);
evas_object_move(sd->clip, -100005, -100005);
evas_object_resize(sd->clip, 200010, 200010);
evas_object_color_set(sd->clip, 255, 255, 255, 255);
evas_object_smart_data_set(obj, sd);
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_layout_smart_del(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
while (sd->items)
{
2012-06-20 05:43:15 -07:00
Evas_Object *child;
2012-06-20 05:43:15 -07:00
child = eina_list_data_get(sd->items);
e_gadcon_layout_unpack(child);
}
evas_object_del(sd->clip);
free(sd);
evas_object_smart_data_set(obj, NULL);
}
static void
_e_gadcon_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if ((x == sd->x) && (y == sd->y)) return;
2012-06-20 05:43:15 -07:00
{
Eina_List *l;
Evas_Object *item;
Evas_Coord dx, dy;
if (sd->horizontal)
{
dx = x - sd->x;
dy = y - sd->y;
}
else
{
dx = x - sd->y;
dy = y - sd->x;
}
EINA_LIST_FOREACH(sd->items, l, item)
{
Evas_Coord ox, oy;
evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
evas_object_move(item, ox + dx, oy + dy);
}
}
if (sd->horizontal)
{
2012-06-20 05:43:15 -07:00
sd->x = x;
sd->y = y;
}
else
{
sd->x = y;
sd->y = x;
}
}
static void
_e_gadcon_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if ((w == sd->w) && (h == sd->h)) return;
if (sd->horizontal)
2012-06-20 05:43:15 -07:00
{
sd->w = w;
sd->h = h;
}
else
{
2012-06-20 05:43:15 -07:00
sd->w = h;
sd->h = w;
}
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_reconfigure(sd);
}
static void
_e_gadcon_layout_smart_show(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->items) evas_object_show(sd->clip);
}
static void
_e_gadcon_layout_smart_hide(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_hide(sd->clip);
}
static void
_e_gadcon_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
2012-06-20 05:43:15 -07:00
if (!sd) return;
evas_object_color_set(sd->clip, r, g, b, a);
}
static void
_e_gadcon_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_clip_set(sd->clip, clip);
}
static void
_e_gadcon_layout_smart_clip_unset(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_clip_unset(sd->clip);
2012-06-20 05:43:15 -07:00
}
/*
* @min - the minimum width required by all the gadcons
* @cur - the current width required by all the gadcons
* @mino - the smalest width/height among all the objects
*/
static void
_e_gadcon_layout_smart_min_cur_size_calc(E_Smart_Data *sd, int *min, int *mino, int *cur)
{
2012-06-20 05:43:15 -07:00
E_Gadcon_Layout_Item *bi;
Eina_List *l;
Evas_Object *item;
EINA_LIST_FOREACH(sd->items, l, item)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(item, "e_gadcon_layout_data");
bi->ask.size2 = bi->ask.size;
if ((bi->aspect.w > 0) && (bi->aspect.h > 0))
{
bi->ask.size2 =
(((sd->h - bi->aspect_pad.h) * bi->aspect.w) / bi->aspect.h) + bi->aspect_pad.w;
if (bi->ask.size2 > bi->min.w)
{
*min += bi->ask.size2;
*cur += bi->ask.size2;
}
else
{
*min += bi->min.w;
*cur += bi->min.w;
}
}
else
{
bi->ask.size2 = bi->ask.size = bi->min.w;
2012-06-20 05:43:15 -07:00
*min += bi->min.w;
if (bi->min.h > *mino) *mino = bi->min.h;
if (bi->ask.size < bi->min.w)
*cur += bi->min.w;
else
*cur += bi->ask.size;
}
}
}
2012-06-20 05:43:15 -07:00
static int
_e_gadcon_layout_smart_width_smart_sort_reverse_cb(const void *d1, const void *d2)
{
const E_Gadcon_Layout_Item *bi, *bi2;
bi = evas_object_data_get(d1, "e_gadcon_layout_data");
2012-06-20 05:43:15 -07:00
bi2 = evas_object_data_get(d2, "e_gadcon_layout_data");
if (bi->ask.size2 > bi->min.w)
{
2012-06-20 05:43:15 -07:00
if (bi2->ask.size2 > bi2->min.w)
{
if (bi->ask.size2 < bi2->ask.size2)
return 1;
else
return -1;
}
else
{
if (bi->ask.size2 == bi2->ask.size2)
return -1;
else
{
if (bi->ask.size2 < bi2->ask.size2)
return 1;
else
return -1;
}
}
}
else
{
2012-06-20 05:43:15 -07:00
if (bi2->ask.size2 > bi2->min.w)
{
if (bi->ask.size2 == bi2->ask.size2)
return 1;
else
{
if (bi->ask.size2 < bi2->ask.size2)
return 1;
else
return -1;
}
}
else
{
if (bi->ask.size2 < bi2->ask.size2)
return 1;
else if (bi->ask.size2 > bi2->ask.size2)
return -1;
}
}
return 0;
}
2012-06-20 05:43:15 -07:00
static void
_e_gadcon_layout_smart_gadcons_width_adjust(E_Smart_Data *sd, int min, int cur)
2012-06-20 05:43:15 -07:00
{
E_Gadcon_Layout_Item *bi = NULL;
Eina_List *l, *l2;
Evas_Object *item;
int needed = 0;
int need = 0;
int max_size, autosize = 0;
if (sd->w < cur)
{
2012-06-20 05:43:15 -07:00
if (sd->w < min) max_size = min;
else max_size = cur;
need = max_size - sd->w;
}
else
return;
2012-06-20 05:43:15 -07:00
sd->items = eina_list_sort(sd->items, eina_list_count(sd->items),
_e_gadcon_layout_smart_width_smart_sort_reverse_cb);
EINA_LIST_FOREACH(sd->items, l, item)
2012-06-20 05:43:15 -07:00
{
bi = evas_object_data_get(item, "e_gadcon_layout_data");
if (bi->gcc->autoscroll) autosize += bi->ask.size2;
2012-06-20 05:43:15 -07:00
}
if (autosize < 1) autosize = 1;
while (need > 0)
2012-06-20 05:43:15 -07:00
{
needed = need;
EINA_LIST_REVERSE_FOREACH(sd->items, l2, item)
2012-06-20 05:43:15 -07:00
{
if (need <= 0) break;
bi = evas_object_data_get(item, "e_gadcon_layout_data");
if (bi->gcc->autoscroll)
{
2012-06-20 05:43:15 -07:00
int reduce_by;
reduce_by = (need * bi->ask.size2) / autosize;
if (reduce_by < 1) reduce_by = 1;
if (bi->ask.size2 - reduce_by > 8)
{
bi->ask.size2 -= reduce_by;
2012-06-20 05:43:15 -07:00
need -= reduce_by;
}
else
{
need -= bi->ask.size2 - 8;
bi->ask.size2 = 8;
}
2012-06-20 05:43:15 -07:00
}
}
/* If the 'needed' size change didn't get modified (no gadget has autoscroll)
then we must break or we end up in an infinite loop */
if (need == needed) break;
}
}
2012-06-20 05:43:15 -07:00
static int
_e_gadcon_layout_smart_sort_by_sequence_number_cb(const void *d1, const void *d2)
{
const E_Gadcon_Layout_Item *bi, *bi2;
bi = evas_object_data_get(d1, "e_gadcon_layout_data");
bi2 = evas_object_data_get(d2, "e_gadcon_layout_data");
if ((!bi->gcc->state_info.seq) && (!bi2->gcc->state_info.seq)) return 0;
2012-06-20 05:43:15 -07:00
else if (!bi->gcc->state_info.seq)
return 1;
else if (!bi2->gcc->state_info.seq)
return -1;
return bi->gcc->state_info.seq - bi2->gcc->state_info.seq;
2012-06-20 05:43:15 -07:00
}
static int
_e_gadcon_layout_smart_sort_by_position_cb(const void *d1, const void *d2)
{
const E_Gadcon_Layout_Item *bi, *bi2;
bi = evas_object_data_get(d1, "e_gadcon_layout_data");
bi2 = evas_object_data_get(d2, "e_gadcon_layout_data");
2012-06-20 05:43:15 -07:00
return bi->x - bi2->x;
}
static int
_e_gadcon_layout_smart_containers_sort_cb(const void *d1, const void *d2)
{
const E_Layout_Item_Container *lc, *lc2;
lc = d1;
lc2 = d2;
if (lc->pos < lc2->pos) return -1;
2012-06-20 05:43:15 -07:00
else if (lc->pos > lc2->pos)
return 1;
return 0;
}
static int
_e_gadcon_layout_smart_seq_sort_cb(const void *d1, const void *d2)
{
const E_Gadcon_Layout_Item *bi, *bi2;
bi = d1;
bi2 = d2;
2012-06-20 05:43:15 -07:00
return bi->gcc->state_info.seq - bi2->gcc->state_info.seq;
}
static void
_e_gadcon_layout_smart_sync_clients(E_Gadcon *gc)
{
E_Gadcon_Client *gcc;
Eina_List *l;
EINA_LIST_FOREACH(gc->clients, l, gcc)
{
2012-06-20 05:43:15 -07:00
_e_gadcon_client_save(gcc);
}
}
static void
_e_gadcon_client_current_position_sync(E_Gadcon_Client *gcc)
{
E_Gadcon_Layout_Item *bi;
Evas_Object *o;
o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
if (o)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(o, "e_gadcon_layout_data");
if (!bi) return;
}
2012-06-20 05:43:15 -07:00
else return; /* make clang happy */
gcc->state_info.prev_pos = gcc->config.pos;
gcc->state_info.prev_size = gcc->config.size;
gcc->config.pos = bi->x;
}
static void
_e_gadcon_layout_smart_gadcon_position_shrinked_mode(E_Smart_Data *sd)
2012-06-20 05:43:15 -07:00
{
Eina_List *l;
Evas_Object *item;
2012-06-20 05:43:15 -07:00
E_Gadcon_Layout_Item *bi, *bi2;
void *tp;
int pos = 0;
sd->items = eina_list_sort(sd->items, eina_list_count(sd->items),
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_sort_by_sequence_number_cb);
EINA_LIST_FOREACH(sd->items, l, item)
2012-06-20 05:43:15 -07:00
{
bi = evas_object_data_get(item, "e_gadcon_layout_data");
if (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_INC)
{
if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
{
bi->gcc->state_info.resist++;
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
}
else
{
bi->gcc->state_info.resist = 0;
if (eina_list_next(l))
{
tp = eina_list_data_get(eina_list_next(l));
l->next->data = eina_list_data_get(l);
l->data = tp;
bi2 = evas_object_data_get(tp, "e_gadcon_layout_data");
if (bi2->x + bi2->w / 2 > bi->ask.pos + bi->w)
{
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
return;
}
bi->gcc->config.pos = bi->ask.pos = bi2->ask.pos;
bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
bi->gcc->state_info.want_save = 1;
bi2->gcc->state_info.want_save = 1;
break;
}
else
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
}
}
else if (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_DEC)
{
if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
{
bi->gcc->state_info.resist++;
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
}
else
{
bi->gcc->state_info.resist = 0;
if (eina_list_prev(l))
{
tp = eina_list_data_get(eina_list_prev(l));
l->prev->data = eina_list_data_get(l);
l->data = tp;
bi2 = evas_object_data_get(tp, "e_gadcon_layout_data");
if (bi->ask.pos > bi2->x + bi2->w / 2)
{
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
return;
}
bi->gcc->config.pos = bi->ask.pos = bi2->ask.pos;
bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
bi->gcc->state_info.want_save = 1;
bi2->gcc->state_info.want_save = 1;
break;
}
else
bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
}
}
else if ((bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC) ||
(bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC) ||
(bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC) ||
(bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC))
{
if (bi->w < bi->min.w)
bi->gcc->config.size = bi->w = bi->min.w;
else
bi->gcc->config.size = bi->w;
bi->gcc->config.pos = bi->gcc->state_info.prev_pos;
}
}
EINA_LIST_FOREACH(sd->items, l, item)
2012-06-20 05:43:15 -07:00
{
bi = evas_object_data_get(item, "e_gadcon_layout_data");
2012-06-20 05:43:15 -07:00
bi->x = pos;
bi->w = bi->ask.size2;
bi->gcc->config.size = bi->w;
pos = bi->x + bi->w;
}
}
static void
_e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd)
{
E_Gadcon_Layout_Item *bi;
Eina_List *l;
Evas_Object *item;
#if 0
EINA_LIST_FOREACH(sd->items, l, item)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(item, "e_gadcon_layout_data");
if (!bi) continue;
bi->x = bi->ask.pos;
bi->w = bi->ask.size2;
}
#else
int pos;
EINA_LIST_FOREACH(sd->items, l, item)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(item, "e_gadcon_layout_data");
if (!bi) continue;
pos = bi->ask.pos + (bi->ask.size / 2);
if (pos < (bi->ask.res / 3))
{
/* hooked to start */
bi->x = bi->ask.pos;
bi->w = bi->ask.size2;
bi->hookp = 0;
}
else if (pos > ((2 * bi->ask.res) / 3))
{
/* hooked to end */
bi->x = (bi->ask.pos - bi->ask.res) + sd->w;
bi->w = bi->ask.size2;
bi->hookp = bi->ask.res;
}
else
{
/* hooked to middle */
if ((bi->ask.pos <= (bi->ask.res / 2)) &&
((bi->ask.pos + bi->ask.size2) > (bi->ask.res / 2)))
{
/* straddles middle */
if (bi->ask.res > 2)
bi->x = (sd->w / 2) +
(((bi->ask.pos + (bi->ask.size2 / 2) -
(bi->ask.res / 2)) *
(bi->ask.res / 2)) /
(bi->ask.res / 2)) - (bi->ask.size2 / 2);
else
bi->x = sd->w / 2;
bi->w = bi->ask.size2;
}
else
{
/* either side of middle */
bi->x = (bi->ask.pos - (bi->ask.res / 2)) + (sd->w / 2);
bi->w = bi->ask.size2;
}
bi->hookp = bi->ask.res / 2;
}
}
#endif
}
2012-06-20 05:43:15 -07:00
/*
* The function returns a list of E_Gadcon_Layout_Item_Container
*/
static Eina_List *
_e_gadcon_layout_smart_gadcons_wrap(E_Smart_Data *sd)
{
Eina_List *l, *list = NULL;
Evas_Object *item;
E_Layout_Item_Container *lc;
E_Gadcon_Layout_Item *bi;
EINA_LIST_FOREACH(sd->items, l, item)
{
2012-06-20 05:43:15 -07:00
bi = evas_object_data_get(item, "e_gadcon_layout_data");
lc = E_NEW(E_Layout_Item_Container, 1);
lc->state_info.min_seq = lc->state_info.max_seq = bi->gcc->state_info.seq;
lc->sd = sd;
2012-06-20 05:43:15 -07:00
lc->pos = bi->x;
lc->size = bi->w;
2012-06-20 05:43:15 -07:00
lc->prev_pos = bi->ask.prev_pos;
lc->prev_size = bi->ask.prev_size;
2012-06-20 05:43:15 -07:00
E_LAYOUT_ITEM_CONTAINER_STATE_SET(lc->state, bi->gcc->state_info.state);
2012-06-20 05:43:15 -07:00
if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
(lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
lc->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
2012-06-20 05:43:15 -07:00
lc->items = eina_list_append(lc->items, bi);
list = eina_list_append(list, lc);
}
return list;
}
static void
_e_gadcon_layout_smart_gadcons_position(E_Smart_Data *sd, Eina_List **list)
{
int ok, lc_moving_prev_pos;
Eina_List *l, *l2, *l3;
2010-01-15 03:29:50 -08:00
E_Layout_Item_Container *lc_moving = NULL, *lc_back = NULL, *lc, *lc3;
E_Gadcon_Layout_Item *bi, *bi_moving = NULL;
if ((!list) || (!*list)) return;
EINA_LIST_FOREACH(*list, l, lc_moving)
{
2012-06-20 05:43:15 -07:00
if ((lc_moving->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
(lc_moving->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED))
{
lc_back = E_NEW(E_Layout_Item_Container, 1);
lc_back->pos = lc_moving->pos;
lc_back->prev_pos = lc_moving->prev_pos;
lc_back->size = lc_moving->size;
lc_back->prev_size = lc_moving->prev_size;
lc_back->state_info.min_seq = lc_moving->state_info.min_seq;
lc_back->state_info.max_seq = lc_moving->state_info.max_seq;
lc_back->sd = lc_moving->sd;
EINA_LIST_FOREACH(lc_moving->items, l2, lc)
lc_back->items = eina_list_append(lc_back->items, lc);
lc_back->state = lc_moving->state;
bi_moving = eina_list_data_get(lc_back->items);
break;
}
lc_moving = NULL;
}
if (!lc_moving)
{
if (lc_back) LC_FREE(lc_back);
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_gadcons_position_static(sd, list);
return;
}
2008-03-04 04:20:50 -08:00
lc_moving_prev_pos = lc_moving->prev_pos;
2012-06-20 05:43:15 -07:00
if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC)
{
_e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list);
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
ok = 0;
if ((l) && eina_list_prev(l))
{
lc = eina_list_data_get(eina_list_prev(l));
if (lc_moving->pos < (lc->pos + lc->size))
{
bi = eina_list_data_get(lc_moving->items);
if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
{
if (lc_moving->prev_pos == (lc->pos + lc->size))
ok = 1;
bi->gcc->state_info.resist++;
lc_moving->pos = lc->pos + lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
}
else
{
bi->gcc->state_info.resist = 0;
if (lc_moving->pos < lc->pos)
{
lc_moving->pos = (lc->pos + lc->size) - 1;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
}
lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc, lc_moving);
if (lc3)
{
if (lc_moving->prev_pos == (lc->pos + lc->size))
ok = 1;
l->data = lc3;
*list = eina_list_remove_list(*list, eina_list_prev(l));
LC_FREE(lc_moving);
LC_FREE(lc);
lc_moving = lc3;
}
}
}
}
if (!ok)
{
int pos, prev_pos, stop;
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
pos = lc_moving->pos + lc_moving->size;
prev_pos = lc_moving_prev_pos;
if ((l) && (eina_list_next(l)))
{
stop = 0;
EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
{
if (stop) break;
if (lc->pos != prev_pos) break;
prev_pos = lc->pos + lc->size;
EINA_LIST_FOREACH(lc->items, l3, bi)
{
if (bi->ask.pos <= pos)
{
bi->x = pos;
pos = (bi->x) + (bi->w);
}
else if (bi->ask.pos < bi->x)
{
bi->x = bi->ask.pos;
pos = (bi->x) + (bi->w);
}
else if (bi->ask.pos == bi->x)
{
stop = 1;
break;
}
}
}
}
}
}
else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC)
{
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list);
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
ok = 0;
if ((l) && eina_list_next(l))
{
lc = eina_list_data_get(eina_list_next(l));
if ((lc_moving->pos + lc_moving->size) > lc->pos)
{
bi = eina_list_data_get(lc_moving->items);
if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
{
if ((lc_moving->prev_pos + lc_moving->size) == lc->pos)
ok = 1;
bi->gcc->state_info.resist++;
lc_moving->pos = lc->pos - lc_moving->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
}
else
{
bi->gcc->state_info.resist = 0;
if ((lc_moving->pos + lc_moving->size) > lc->pos)
{
lc_moving->pos = (lc->pos - lc_moving->size) + 1;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
}
lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc_moving, lc);
if (lc3)
{
if ((lc_moving->prev_pos + lc_moving->size) == lc->pos)
ok = 1;
l->data = lc3;
*list = eina_list_remove_list(*list, eina_list_next(l));
LC_FREE(lc_moving);
LC_FREE(lc);
lc_moving = lc3;
}
}
}
}
if (!ok)
{
int pos, prev_pos, stop;
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
pos = lc_moving->pos;
prev_pos = lc_moving_prev_pos;
if ((l) && eina_list_prev(l))
{
stop = 0;
/* EINA_FUCK_REVERSE_FOREACH(eina_list_prev(l), l2, lc) */
for (l2 = l->prev; l2; l2 = l2->prev)
{
lc = l2->data;
if (stop) break;
if ((lc->pos + lc->size) == prev_pos) break;
prev_pos = lc->pos;
EINA_LIST_REVERSE_FOREACH(lc->items, l3, bi)
{
if ((bi->ask.pos + bi->w) >= pos)
{
bi->x = pos - bi->w;
pos = bi->x;
}
else if (bi->ask.pos > bi->x)
{
bi->x = bi->ask.pos;
pos = bi->x;
}
else if (bi->ask.pos == bi->x)
{
stop = 1;
break;
}
}
}
}
}
}
else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC)
2012-06-20 05:43:15 -07:00
{
_e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list);
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
if ((l) && eina_list_prev(l))
{
int new_pos = 0;
ok = 0;
new_pos = lc_moving->pos;
/* EINA_FUCK_REVERSE_FOREACH(eina_list_prev(l), l2, lc) */
for (l2 = l->prev; l2; l2 = l2->prev)
{
lc = l2->data;
if (new_pos >= (lc->pos + lc->size)) break;
ok = 1;
new_pos -= lc->size;
}
if (new_pos < 0)
{
lc_moving->size += new_pos;
lc_moving->pos -= new_pos;
bi = eina_list_data_get(lc_moving->items);
bi->w = lc_moving->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
new_pos = 0;
}
if (ok)
{
if (!l2) l2 = *list;
else l2 = eina_list_next(l2);
EINA_LIST_FOREACH(l2, l2, lc)
{
if (l2 == l) break;
lc->pos = new_pos;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
EINA_LIST_FOREACH(lc->items, l3, bi)
{
bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
}
new_pos += lc->size;
}
}
}
else if ((l) && (!eina_list_prev(l)))
{
if (lc_moving->pos <= 0)
{
lc_moving->size = lc_moving->prev_size;
lc_moving->pos = 0;
bi = eina_list_data_get(lc_moving->items);
bi->w = lc_moving->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
}
}
}
else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC)
{
2012-06-20 05:43:15 -07:00
lc_moving->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
_e_gadcon_layout_smart_gadcons_position_static(sd, list);
if (lc_back) LC_FREE(lc_back);
}
else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC)
{
2012-06-20 05:43:15 -07:00
_e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list);
EINA_LIST_FOREACH(*list, l, lc)
if (lc == lc_moving) break;
if ((l) && eina_list_next(l))
{
Eina_List *stop = NULL;
int new_pos = 0;
ok = 0;
new_pos = lc_moving->pos + lc_moving->size;
EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
{
if (new_pos <= lc->pos)
{
stop = l2;
break;
}
ok = 1;
/* new_pos += lc->size; */
}
if (new_pos > sd->w)
{
lc_moving->size -= (new_pos - sd->w);
bi = eina_list_data_get(lc_moving->items);
bi->w = lc_moving->size;
new_pos = lc_moving->pos + lc_moving->size;
}
if (ok)
{
EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
{
if (l2 == stop) break;
lc->pos = new_pos;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
EINA_LIST_FOREACH(lc->items, l3, bi)
{
bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
}
new_pos += lc->size;
}
}
}
else if ((l) && (!eina_list_next(l)))
{
if ((lc_moving->pos + lc_moving->size) >= sd->w)
{
lc_moving->size = lc_moving->prev_size;
bi = eina_list_data_get(lc_moving->items);
bi->w = lc_moving->size;
}
}
}
else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC)
{
2012-06-20 05:43:15 -07:00
lc_moving->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
_e_gadcon_layout_smart_gadcons_position_static(sd, list);
if (lc_back) LC_FREE(lc_back);
}
2010-01-15 03:29:50 -08:00
if (bi_moving)
{
2012-06-20 05:43:15 -07:00
bi_moving->gcc->config.pos = bi_moving->ask.pos = bi_moving->x;
bi_moving->gcc->config.size = bi_moving->w;
2010-01-15 03:29:50 -08:00
}
}
static void
_e_gadcon_layout_smart_gadcons_position_static(E_Smart_Data *sd, Eina_List **list)
{
int ok;
Eina_List *l;
E_Layout_Item_Container *lc, *lc2, *lc3;
*list = eina_list_sort(*list, eina_list_count(*list), _e_gadcon_layout_smart_containers_sort_cb);
2012-06-20 05:43:15 -07:00
__reposition_again:
EINA_LIST_FOREACH(*list, l, lc)
{
2012-06-20 05:43:15 -07:00
if (!eina_list_next(l)) continue;
2012-06-20 05:43:15 -07:00
lc2 = eina_list_data_get(eina_list_next(l));
2012-06-20 05:43:15 -07:00
if (LC_OVERLAP(lc, lc2))
{
lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc, lc2);
if (lc3)
{
l->data = lc3;
*list = eina_list_remove_list(*list, eina_list_next(l));
LC_FREE(lc);
LC_FREE(lc2);
goto __reposition_again;
}
}
}
ok = 1;
EINA_LIST_FOREACH(*list, l, lc)
{
2012-06-20 05:43:15 -07:00
if (lc->pos < 0)
{
ok = 0;
lc->pos = 0;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
continue;
}
if (((lc->pos + lc->size) > sd->w) && (lc->size <= sd->w))
{
ok = 0;
lc->pos = sd->w - lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
}
if (!ok)
_e_gadcon_layout_smart_gadcons_position_static(sd, list);
}
static E_Layout_Item_Container *
_e_gadcon_layout_smart_containers_position_adjust(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2)
{
int create_new = 0;
Eina_List *l;
E_Layout_Item_Container *lc3 = NULL;
E_Layout_Item_Container_State new_state;
E_Gadcon_Layout_Item *bi, *bi2;
if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
(lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
{
2012-06-20 05:43:15 -07:00
if (lc->state_info.max_seq <= lc2->state_info.min_seq)
{
lc2->pos = lc->pos + lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
}
else if (lc->state_info.min_seq > lc2->state_info.max_seq)
{
lc->pos = lc2->pos + lc2->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
else if (((lc->state_info.min_seq > lc2->state_info.min_seq) &&
(lc->state_info.min_seq < lc2->state_info.max_seq)) ||
((lc2->state_info.min_seq > lc->state_info.min_seq) &&
(lc2->state_info.min_seq < lc->state_info.max_seq)))
{
_e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
}
create_new = 1;
new_state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
}
else if ((lc->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
2012-06-20 05:43:15 -07:00
(lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
{
if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC)
{
int t;
bi = eina_list_data_get(lc->items);
bi2 = eina_list_data_get(lc2->items);
bi->x = ((bi2->x) + (bi2->w)) - (bi->w);
bi->gcc->config.pos = bi->ask.pos = bi->x;
bi->gcc->config.size = bi->w;
bi2->x = (bi->x) - (bi2->w);
bi2->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
t = bi->gcc->state_info.seq;
bi->gcc->state_info.seq = bi2->gcc->state_info.seq;
bi2->gcc->state_info.seq = t;
_e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
}
else if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED)
{
if (lc->state_info.max_seq < lc2->state_info.min_seq)
{
lc2->pos = lc->pos + lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
}
else if (lc->state_info.min_seq > lc2->state_info.max_seq)
{
lc2->pos = lc->pos - lc2->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
}
else if (((lc->state_info.min_seq > lc2->state_info.min_seq) &&
(lc->state_info.min_seq < lc2->state_info.max_seq)) ||
((lc2->state_info.min_seq > lc->state_info.min_seq) &&
(lc2->state_info.min_seq < lc->state_info.max_seq)))
{
int shift = 0;
_e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
EINA_LIST_FOREACH(lc->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION)
{
shift = bi->ask.pos - bi->x;
}
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
break;
}
if (shift)
{
EINA_LIST_FOREACH(lc->items, l, bi)
{
bi->x += shift;
if (l == lc->items)
lc->pos = bi->x;
}
}
}
}
create_new = 1;
new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
}
else if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
2012-06-20 05:43:15 -07:00
(lc2->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
{
if (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED)
{
if (lc->state_info.max_seq < lc2->state_info.min_seq)
{
lc->pos = lc2->pos - lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
else if (lc->state_info.min_seq > lc2->state_info.max_seq)
{
lc->pos = lc2->pos + lc2->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
else if (((lc->state_info.min_seq > lc2->state_info.min_seq) &&
(lc->state_info.min_seq < lc2->state_info.max_seq)) ||
((lc2->state_info.min_seq > lc->state_info.min_seq) &&
(lc2->state_info.min_seq < lc->state_info.max_seq)))
{
int shift = 0;
EINA_LIST_FOREACH(lc->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION)
{
shift = bi->ask.pos - bi->x;
}
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
break;
}
if (shift)
{
EINA_LIST_FOREACH(lc->items, l, bi)
{
bi->x += shift;
if (l == lc->items)
lc->pos = bi->x;
}
}
}
}
else if (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC)
{
int t;
bi = eina_list_last_data_get(lc->items);
2012-06-20 05:43:15 -07:00
bi2 = eina_list_data_get(lc2->items);
bi2->gcc->config.pos = bi2->ask.pos = (bi2->x) = (bi->x);
bi2->gcc->config.size = bi2->w;
bi->x = bi2->x + bi2->w;
t = bi->gcc->state_info.seq;
bi->gcc->state_info.seq = bi2->gcc->state_info.seq;
bi2->gcc->state_info.seq = t;
lc->items = eina_list_remove_list(lc->items, eina_list_last(lc->items));
lc->items = eina_list_append(lc->items, bi2);
lc->items = eina_list_append(lc->items, bi);
lc2->items = eina_list_free(lc2->items);
E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc, bi2, 1);
lc2->pos = lc->pos + lc->size;
lc2->size = 0;
}
create_new = 1;
new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
}
else if ((lc->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
2012-06-20 05:43:15 -07:00
(lc2->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
{
if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED) &&
(lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED))
{
if (lc->state_info.max_seq < lc2->state_info.min_seq)
{
int move_lc1 = 1;
int move_lc2 = 1;
EINA_LIST_FOREACH(lc->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
{
move_lc1 = 0;
break;
}
}
EINA_LIST_FOREACH(lc2->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
{
move_lc2 = 0;
break;
}
}
if ((move_lc1) && (!move_lc2))
{
lc->pos = lc2->pos - lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
else
{
lc2->pos = lc->pos + lc->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
}
}
else if (lc->state_info.min_seq > lc2->state_info.max_seq)
{
int move_lc1 = 1;
int move_lc2 = 1;
EINA_LIST_FOREACH(lc->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
{
move_lc1 = 0;
break;
}
}
EINA_LIST_FOREACH(lc2->items, l, bi)
{
if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
{
move_lc2 = 0;
break;
}
}
if ((!move_lc1) && (move_lc2))
{
lc2->pos = lc->pos - lc2->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
}
else
{
lc->pos = lc2->pos + lc2->size;
_e_gadcon_layout_smart_position_items_inside_container(sd, lc);
}
}
else if (((lc->state_info.min_seq > lc2->state_info.min_seq) &&
(lc->state_info.min_seq < lc2->state_info.max_seq)) ||
((lc2->state_info.min_seq > lc->state_info.min_seq) &&
(lc2->state_info.min_seq < lc->state_info.max_seq)))
{
int shift = 0;
_e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
EINA_LIST_FOREACH(lc->items, l, bi)
{
if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
(bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE))
{
shift = bi->ask.pos - bi->x;
break;
}
}
if (shift)
{
EINA_LIST_FOREACH(lc->items, l, bi)
{
bi->x += shift;
if (l == lc->items)
lc->pos = bi->x;
}
}
}
create_new = 1;
new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
}
}
if (create_new)
{
2012-06-20 05:43:15 -07:00
lc3 = E_NEW(E_Layout_Item_Container, 1);
lc3->sd = sd;
if (lc->pos < lc2->pos)
{
lc3->pos = lc->pos;
EINA_LIST_FOREACH(lc->items, l, bi)
lc3->items = eina_list_append(lc3->items, bi);
EINA_LIST_FOREACH(lc2->items, l, bi)
lc3->items = eina_list_append(lc3->items, bi);
lc3->state_info.min_seq = lc->state_info.min_seq;
if (lc2->items)
lc3->state_info.max_seq = lc2->state_info.max_seq;
else
lc3->state_info.max_seq = lc->state_info.max_seq;
}
else
{
lc3->pos = lc2->pos;
EINA_LIST_FOREACH(lc2->items, l, bi)
lc3->items = eina_list_append(lc3->items, bi);
EINA_LIST_FOREACH(lc->items, l, bi)
lc3->items = eina_list_append(lc3->items, bi);
lc3->state_info.min_seq = lc2->state_info.min_seq;
if (lc->items)
lc3->state_info.max_seq = lc->state_info.max_seq;
else
lc3->state_info.max_seq = lc2->state_info.max_seq;
}
lc3->size = lc->size + lc2->size;
lc3->state = new_state;
}
return lc3;
2012-06-20 05:43:15 -07:00
}
static void
_e_gadcon_layout_smart_position_items_inside_container(E_Smart_Data *sd __UNUSED__, E_Layout_Item_Container *lc)
{
int shift;
Eina_List *l;
E_Gadcon_Layout_Item *bi;
if (!lc->items) return;
bi = eina_list_data_get(lc->items);
shift = lc->pos - bi->x;
2012-06-20 05:43:15 -07:00
if (!shift) return;
EINA_LIST_FOREACH(lc->items, l, bi)
{
2012-06-20 05:43:15 -07:00
bi->x += shift;
if ((bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_DEC) ||
(bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_INC))
{
bi->gcc->config.pos = bi->ask.pos = bi->x;
}
}
2012-06-20 05:43:15 -07:00
}
static void
_e_gadcon_layout_smart_containers_merge(E_Smart_Data *sd __UNUSED__, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2)
{
int start = 0, size = 0, next = 0, min_seq = 0, max_seq = 0;
Eina_List *l, *nl = NULL;
E_Gadcon_Layout_Item *bi;
EINA_LIST_FOREACH(lc->items, l, bi)
nl = eina_list_append(nl, bi);
EINA_LIST_FOREACH(lc2->items, l, bi)
nl = eina_list_append(nl, bi);
nl = eina_list_sort(nl, eina_list_count(nl), _e_gadcon_layout_smart_seq_sort_cb);
EINA_LIST_FOREACH(nl, l, bi)
{
2012-06-20 05:43:15 -07:00
if (l == nl)
{
min_seq = max_seq = bi->gcc->state_info.seq;
start = bi->x;
size = bi->w;
next = bi->x + bi->w;
2012-06-20 05:43:15 -07:00
continue;
}
2012-06-20 05:43:15 -07:00
max_seq = bi->gcc->state_info.seq;
2012-06-20 05:43:15 -07:00
bi->x = next;
size += bi->w;
next = bi->x + bi->w;
}
lc->items = eina_list_free(lc->items);
lc2->items = eina_list_free(lc->items);
lc->items = nl;
lc->pos = start;
lc->size = size;
lc->state_info.min_seq = min_seq;
lc->state_info.max_seq = max_seq;
lc2->pos = lc->pos + lc->size;
lc2->size = 0;
2012-06-20 05:43:15 -07:00
}
static void
_e_gadcon_layout_smart_restore_gadcons_position_before_move(E_Smart_Data *sd, E_Layout_Item_Container **lc_moving, E_Layout_Item_Container *lc_back, Eina_List **con_list)
{
int ok;
Eina_List *l, *l2, *l3;
E_Gadcon_Layout_Item *bi, *bi2;
E_Layout_Item_Container *lc, *lc2, *lc3;
(*lc_moving)->pos = (*lc_moving)->prev_pos;
2012-06-20 05:43:15 -07:00
if (((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC) ||
((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC) ||
((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC) ||
((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC))
{
2012-06-20 05:43:15 -07:00
(*lc_moving)->size = (*lc_moving)->prev_size;
bi = eina_list_data_get((*lc_moving)->items);
2012-06-20 05:43:15 -07:00
bi->w = (*lc_moving)->prev_size;
}
_e_gadcon_layout_smart_position_items_inside_container(sd, (*lc_moving));
(*lc_moving)->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
_e_gadcon_layout_smart_gadcons_position_static(sd, con_list);
lc2 = NULL;
lc3 = NULL;
ok = 0;
EINA_LIST_FOREACH(*con_list, l, lc)
{
2012-06-20 05:43:15 -07:00
if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) continue;
if (eina_list_count(lc->items) == 1)
{
bi = eina_list_data_get(lc->items);
if (bi->gcc->state_info.state != E_LAYOUT_ITEM_STATE_NONE)
{
LC_FREE(lc);
l->data = *lc_moving = lc_back;
_e_gadcon_layout_smart_position_items_inside_container(sd, (*lc_moving));
if (((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC) &&
((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC))
{
bi = eina_list_data_get((*lc_moving)->items);
bi->w = (*lc_moving)->size;
}
}
}
else
{
EINA_LIST_FOREACH(lc->items, l2, bi)
{
if (bi->gcc->state_info.state != E_LAYOUT_ITEM_STATE_NONE)
{
ok = 1;
if (l2 != lc->items)
{
lc2 = E_NEW(E_Layout_Item_Container, 1);
lc2->sd = sd;
lc2->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
EINA_LIST_FOREACH(lc->items, l3, bi2)
{
if (l2 == l3) break;
lc2->items = eina_list_append(lc2->items, bi2);
if (l3 == lc->items)
{
lc2->state_info.min_seq = bi2->gcc->state_info.seq;
lc2->pos = lc2->prev_pos = bi2->x;
}
lc2->state_info.max_seq = bi2->gcc->state_info.seq;
E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc2, bi2, 1);
}
}
if (eina_list_next(l2))
{
lc3 = E_NEW(E_Layout_Item_Container, 1);
lc3->sd = sd;
lc3->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
EINA_LIST_FOREACH(eina_list_next(l2), l3, bi2)
{
lc3->items = eina_list_append(lc3->items, bi2);
if (l3 == eina_list_next(l2))
{
lc3->state_info.min_seq = bi2->gcc->state_info.seq;
lc3->pos = lc3->prev_pos = bi2->x;
}
lc3->state_info.max_seq = bi2->gcc->state_info.seq;
E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc3, bi2, 1);
}
}
*lc_moving = lc_back;
_e_gadcon_layout_smart_position_items_inside_container(sd, *lc_moving);
if (((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC) &&
((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC))
{
bi = eina_list_data_get((*lc_moving)->items);
bi->w = (*lc_moving)->size;
}
break;
}
}
if (ok)
{
LC_FREE(lc);
if (lc2)
{
l->data = lc2;
*con_list = eina_list_append(*con_list, *lc_moving);
if (lc3)
*con_list = eina_list_append(*con_list, lc3);
*con_list = eina_list_sort(*con_list, eina_list_count(*con_list),
_e_gadcon_layout_smart_containers_sort_cb);
}
else
{
l->data = *lc_moving;
if (lc3)
{
*con_list = eina_list_append(*con_list, lc3);
*con_list = eina_list_sort(*con_list, eina_list_count(*con_list),
_e_gadcon_layout_smart_containers_sort_cb);
}
}
break;
}
}
}
EINA_LIST_FOREACH(*con_list, l, lc)
{
2012-06-20 05:43:15 -07:00
if (lc == *lc_moving) continue;
lc->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
}
}
static void
_e_gadcon_event_populate_free(void *data __UNUSED__, void *event)
{
E_Event_Gadcon_Populate *ev = event;
e_object_unref(E_OBJECT(ev->gc));
free(ev);
}
static void
_e_gadcon_custom_populate_job(void *data __UNUSED__)
{
const E_Gadcon_Client_Class *cc;
E_Config_Gadcon_Client *cf_gcc;
Eina_List *l, *ll;
E_Gadcon *gc;
#ifndef E_RELEASE_BUILD
static Eina_Bool first = EINA_TRUE;
if (first)
e_main_ts("gadcon custom populate idler start");
#endif
EINA_LIST_FREE(custom_populate_requests, gc)
{
if (!gc->cf) continue;
2012-06-20 05:43:15 -07:00
e_gadcon_layout_freeze(gc->o_container);
EINA_LIST_FOREACH_SAFE(gc->cf->clients, l, ll, cf_gcc)
2012-06-20 05:43:15 -07:00
{
if ((!cf_gcc->name) || (!cf_gcc->name[0]) || (!cf_gcc->id) || (!cf_gcc->id[0]))
{
e_gadcon_client_config_del(gc->cf, cf_gcc);
continue;
}
cc = eina_hash_find(providers, cf_gcc->name);
if (!cc) continue;
if (gc->populate_class.func)
gc->populate_class.func(gc->populate_class.data, gc, cc);
else
e_gadcon_populate_class(gc, cc);
2012-06-20 05:43:15 -07:00
}
e_gadcon_layout_thaw(gc->o_container);
_e_gadcon_event_populate(gc);
}
#ifndef E_RELEASE_BUILD
if (first)
e_main_ts("gadcon custom populate idler end");
#endif
if (!custom_populate_requests)
{
custom_populate_job = NULL;
#ifndef E_RELEASE_BUILD
first = EINA_FALSE;
#endif
}
}
static void
_e_gadcon_provider_populate_job(void *data __UNUSED__)
{
E_Gadcon_Client_Class *cc;
Eina_List *l;
E_Gadcon *gc;
#ifndef E_RELEASE_BUILD
static Eina_Bool first = EINA_TRUE;
if (first)
e_main_ts("gadcon populate idler start");
#endif
EINA_LIST_FOREACH(gadcons, l, gc)
{
int x = 0;
Eina_Bool freeze = EINA_FALSE;
if (gc->populate_requests)
{
freeze = EINA_TRUE;
e_gadcon_layout_freeze(gc->o_container);
}
EINA_LIST_FREE(gc->populate_requests, cc)
{
#ifndef E_RELEASE_BUILD
if (first) e_main_ts(cc->name);
#endif
if (gc->populate_class.func)
gc->populate_class.func(gc->populate_class.data, gc, cc);
else
e_gadcon_populate_class(gc, cc);
if (!eina_list_data_find(gc->populated_classes, cc))
{
gc->populated_classes = eina_list_append(gc->populated_classes, cc);
if (gc->cf)
{
Eina_List *ll;
E_Config_Gadcon_Client *cf_gcc;
if (!gc->awaiting_classes) continue;
ll = eina_hash_set(gc->awaiting_classes, cc->name, NULL);
EINA_LIST_FREE(ll, cf_gcc)
_e_gadcon_client_populate(gc, cc, cf_gcc);
}
}
x++;
}
if (freeze) e_gadcon_layout_thaw(gc->o_container);
if (x && _modules_loaded) _e_gadcon_event_populate(gc);
}
//out:
#ifndef E_RELEASE_BUILD
if (first)
e_main_ts("gadcon populate idler end");
#endif
populate_job = NULL;
#ifndef E_RELEASE_BUILD
first = EINA_FALSE;
#endif
}
static void
_e_gadcon_provider_populate_request(E_Gadcon *gc, const E_Gadcon_Client_Class *cc)
{
if (eina_list_data_find(gc->populate_requests, cc)) return;
gc->populate_requests = eina_list_append(gc->populate_requests, cc);
if (populate_job) ecore_job_del(populate_job);
populate_job = ecore_job_add(_e_gadcon_provider_populate_job, NULL);
}
static void
_e_gadcon_provider_populate_unrequest(const E_Gadcon_Client_Class *cc)
{
E_Gadcon *gc;
Eina_List *l;
unsigned int more = 0;
EINA_LIST_FOREACH(gadcons, l, gc)
{
gc->populate_requests = eina_list_remove(gc->populate_requests, cc);
more += eina_list_count(gc->populate_requests);
}
if ((!more) && (populate_job))
{
ecore_job_del(populate_job);
populate_job = NULL;
}
}
2009-08-31 04:23:03 -07:00
/* gadgets movement between different gadcons */
EAPI E_Gadcon_Location *
2012-06-20 05:43:15 -07:00
e_gadcon_location_new(const char *name,
E_Gadcon_Site site,
int (*add_func)(void *data, E_Gadcon_Client *gcc, const E_Gadcon_Client_Class *cc),
2012-06-20 05:43:15 -07:00
void *add_data,
void (*remove_func)(void *data, E_Gadcon_Client *cc),
void *remove_data)
2009-08-31 04:23:03 -07:00
{
E_Gadcon_Location *loc;
2012-06-20 05:43:15 -07:00
loc = E_NEW(E_Gadcon_Location, 1);
2009-08-31 04:23:03 -07:00
loc->name = eina_stringshare_add(name);
loc->site = site;
2012-06-20 05:43:15 -07:00
loc->gadget_add.func = add_func;
loc->gadget_add.data = add_data;
loc->gadget_remove.func = remove_func;
loc->gadget_remove.data = remove_data;
2009-08-31 04:23:03 -07:00
loc->icon_name = NULL;
return loc;
}
EAPI void
e_gadcon_location_set_icon_name(E_Gadcon_Location *loc, const char *name)
{
if (loc->icon_name) eina_stringshare_del(loc->icon_name);
if (name)
loc->icon_name = eina_stringshare_add(name);
else
loc->icon_name = NULL;
}
EAPI void
e_gadcon_location_free(E_Gadcon_Location *loc)
{
eina_stringshare_del(loc->name);
if (loc->icon_name) eina_stringshare_del(loc->icon_name);
free(loc);
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_location_register(E_Gadcon_Location *loc)
2009-08-31 04:23:03 -07:00
{
gadcon_locations = eina_list_append(gadcon_locations, loc);
}
EAPI void
2012-06-20 05:43:15 -07:00
e_gadcon_location_unregister(E_Gadcon_Location *loc)
2009-08-31 04:23:03 -07:00
{
gadcon_locations = eina_list_remove(gadcon_locations, loc);
}
static int
2012-06-20 05:43:15 -07:00
_e_gadcon_location_change(E_Gadcon_Client *gcc, E_Gadcon_Location *src, E_Gadcon_Location *dst)
2009-08-31 04:23:03 -07:00
{
E_Gadcon_Client_Class *cc;
cc = eina_hash_find(providers, gcc->cf->name);
if (!cc) return 0;
if (!dst->gadget_add.func(dst->gadget_add.data, gcc, cc)) return 0;
gcc->cf = NULL;
2009-08-31 04:23:03 -07:00
src->gadget_remove.func(src->gadget_remove.data, gcc);
return 1;
}
EAPI Eina_Bool
e_gadcon_client_visible_get(const E_Gadcon_Client *gcc, const E_Desk *desk)
{
const Eina_List *l;
E_Zone *zone;
if (!gcc->gadcon) return EINA_FALSE;
switch (gcc->gadcon->location->site)
{
case E_GADCON_SITE_DESKTOP:
return EINA_TRUE; // FIXME for when gadman allows per-desk gadgets
case E_GADCON_SITE_SHELF:
if (desk) return e_shelf_desk_visible(gcc->gadcon->shelf, desk);
EINA_LIST_FOREACH(e_comp->zones, l, zone)
if (e_shelf_desk_visible(gcc->gadcon->shelf, e_desk_current_get(zone)))
return EINA_TRUE;
break;
case E_GADCON_SITE_TOOLBAR:
case E_GADCON_SITE_EFM_TOOLBAR:
if (desk) return (e_win_client_get(gcc->gadcon->toolbar->fwin)->desk == desk);
EINA_LIST_FOREACH(e_comp->zones, l, zone)
if (e_win_client_get(gcc->gadcon->toolbar->fwin)->desk == e_desk_current_get(zone)) return EINA_TRUE;
default:
break;
}
return EINA_FALSE;
}