322 lines
9.2 KiB
C
322 lines
9.2 KiB
C
#include "e.h"
|
|
|
|
/* local subsystem functions */
|
|
|
|
static void _e_gadcon_popup_changed_size_hints_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
|
|
static void _e_gadcon_popup_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
|
|
|
|
static Eina_Bool
|
|
_e_popup_autoclose_deskafter_show_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
{
|
|
E_Event_Desk_After_Show *ev = event;
|
|
E_Gadcon_Popup *pop = data;
|
|
|
|
if (!pop) return ECORE_CALLBACK_RENEW;
|
|
if (!pop->visible) return ECORE_CALLBACK_RENEW;
|
|
if (!e_gadcon_client_visible_get(pop->gcc, ev->desk))
|
|
e_object_del(E_OBJECT(pop));
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_e_popup_autoclose_client_fullscreen_cb(void *data, int type EINA_UNUSED, void *event)
|
|
{
|
|
E_Event_Client *ev = event;
|
|
E_Gadcon_Popup *pop = data;
|
|
|
|
if (!pop) return ECORE_CALLBACK_RENEW;
|
|
if (!pop->visible) return ECORE_CALLBACK_RENEW;
|
|
if (!ev->ec->fullscreen) return ECORE_CALLBACK_RENEW;
|
|
if (e_gadcon_client_visible_get(pop->gcc, ev->ec->desk))
|
|
e_object_del(E_OBJECT(pop));
|
|
return ECORE_CALLBACK_RENEW;
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_locked_set(E_Gadcon_Popup *pop, Eina_Bool locked)
|
|
{
|
|
if (!pop->gcc)
|
|
return;
|
|
|
|
e_gadcon_locked_set(pop->gcc->gadcon, locked);
|
|
pop->gadcon_was_locked = locked;
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_delay_del(void *obj)
|
|
{
|
|
E_Gadcon_Popup *pop = obj;
|
|
|
|
if (pop->comp_object) evas_object_hide(pop->comp_object);
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_free(E_Gadcon_Popup *pop)
|
|
{
|
|
if (pop->content)
|
|
{
|
|
evas_object_event_callback_del_full(pop->content, EVAS_CALLBACK_DEL,
|
|
_e_gadcon_popup_del_cb, pop);
|
|
evas_object_event_callback_del_full(pop->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
_e_gadcon_popup_changed_size_hints_cb, pop);
|
|
pop->content = NULL;
|
|
}
|
|
E_FREE_FUNC(pop->autoclose_handlers[0], ecore_event_handler_del);
|
|
E_FREE_FUNC(pop->autoclose_handlers[1], ecore_event_handler_del);
|
|
|
|
if (pop->gadcon_was_locked)
|
|
_e_gadcon_popup_locked_set(pop, 0);
|
|
pop->gcc = NULL;
|
|
evas_object_hide(pop->comp_object);
|
|
E_FREE_FUNC(pop->comp_object, evas_object_del);
|
|
free(pop);
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_position(E_Gadcon_Popup *pop)
|
|
{
|
|
Evas_Coord gx = 0, gy = 0, gw, gh, zw, zh, zx, zy, px, py;
|
|
E_Zone *zone;
|
|
|
|
/* Popup positioning */
|
|
e_gadcon_client_geometry_get(pop->gcc, &gx, &gy, &gw, &gh);
|
|
zone = e_gadcon_zone_get(pop->gcc->gadcon);
|
|
zx = zone->x;
|
|
zy = zone->y;
|
|
zw = zone->w;
|
|
zh = zone->h;
|
|
switch (pop->gcc->gadcon->orient)
|
|
{
|
|
case E_GADCON_ORIENT_CORNER_RT:
|
|
case E_GADCON_ORIENT_CORNER_RB:
|
|
case E_GADCON_ORIENT_RIGHT:
|
|
px = gx - pop->w;
|
|
py = gy;
|
|
if (py + pop->h >= (zy + zh))
|
|
py = gy + gh - pop->h;
|
|
px = MIN(zx + zw - gw - pop->w - 3, px);
|
|
break;
|
|
|
|
case E_GADCON_ORIENT_LEFT:
|
|
case E_GADCON_ORIENT_CORNER_LT:
|
|
case E_GADCON_ORIENT_CORNER_LB:
|
|
px = gx + gw;
|
|
py = gy;
|
|
if (py + pop->h >= (zy + zh))
|
|
py = gy + gh - pop->h;
|
|
px = MIN(zx + zw - gw - pop->w + 3, px);
|
|
break;
|
|
|
|
case E_GADCON_ORIENT_TOP:
|
|
case E_GADCON_ORIENT_CORNER_TL:
|
|
case E_GADCON_ORIENT_CORNER_TR:
|
|
py = gy + gh;
|
|
px = (gx + (gw / 2)) - (pop->w / 2);
|
|
if ((px + pop->w) >= (zx + zw))
|
|
px = gx + gw - pop->w;
|
|
else if (px < zx)
|
|
px = zx;
|
|
py = MIN(zy + zh - gh - pop->h + 3, py);
|
|
break;
|
|
|
|
case E_GADCON_ORIENT_BOTTOM:
|
|
case E_GADCON_ORIENT_CORNER_BL:
|
|
case E_GADCON_ORIENT_CORNER_BR:
|
|
py = gy - pop->h;
|
|
px = (gx + (gw / 2)) - (pop->w / 2);
|
|
if ((px + pop->w) >= (zx + zw))
|
|
px = gx + gw - pop->w;
|
|
else if (px < zx)
|
|
px = zx;
|
|
py = MIN(zy + zh - gh - pop->h - 3, py);
|
|
break;
|
|
|
|
case E_GADCON_ORIENT_FLOAT:
|
|
px = (gx + (gw / 2)) - (pop->w / 2);
|
|
if (gy >= (zy + (zh / 2)))
|
|
py = gy - pop->h;
|
|
else
|
|
py = gy + gh;
|
|
if ((px + pop->w) >= (zx + zw))
|
|
px = gx + gw - pop->w;
|
|
else if (px < zx)
|
|
px = zx;
|
|
break;
|
|
|
|
default:
|
|
evas_object_move(pop->comp_object, 50, 50);
|
|
return;
|
|
}
|
|
if (px - zx < 0)
|
|
px = zx;
|
|
if (py - zy < 0)
|
|
py = zy;
|
|
evas_object_move(pop->comp_object, px, py);
|
|
|
|
if (pop->gadcon_lock && (!pop->gadcon_was_locked))
|
|
_e_gadcon_popup_locked_set(pop, 1);
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_size_recalc(E_Gadcon_Popup *pop, Evas_Object *obj)
|
|
{
|
|
Evas_Coord pw, ph, w = 0, h = 0;
|
|
|
|
if (!isedje(obj))
|
|
evas_object_size_hint_min_get(obj, &w, &h);
|
|
else
|
|
{
|
|
edje_object_size_min_get(obj, &w, &h);
|
|
edje_object_size_min_restricted_calc(obj, &w, &h, w, h);
|
|
evas_object_size_hint_min_set(obj, w, h);
|
|
}
|
|
edje_object_size_min_calc(pop->o_bg, &pw, &ph);
|
|
pop->w = MAX(pw, pop->w);
|
|
pop->h = MAX(ph, pop->h);
|
|
evas_object_resize(pop->comp_object, pop->w, pop->h);
|
|
|
|
_e_gadcon_popup_position(pop);
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_changed_size_hints_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
E_Gadcon_Popup *pop = data;
|
|
|
|
/* edje calc bug: hint updates on child are not updated for min_calc unless this happens first */
|
|
edje_object_part_unswallow(pop->o_bg, obj);
|
|
edje_object_part_swallow(pop->o_bg, "e.swallow.content", obj);
|
|
_e_gadcon_popup_size_recalc(data, obj);
|
|
}
|
|
|
|
static void
|
|
_e_gadcon_popup_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
|
{
|
|
E_Gadcon_Popup *pop = data;
|
|
|
|
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
|
|
_e_gadcon_popup_del_cb, pop);
|
|
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
_e_gadcon_popup_changed_size_hints_cb, pop);
|
|
pop->content = NULL;
|
|
}
|
|
|
|
/* externally accessible functions */
|
|
|
|
EAPI E_Gadcon_Popup *
|
|
e_gadcon_popup_new(E_Gadcon_Client *gcc, Eina_Bool noshadow)
|
|
{
|
|
E_Gadcon_Popup *pop;
|
|
Evas_Object *o;
|
|
|
|
pop = E_OBJECT_ALLOC(E_Gadcon_Popup, E_GADCON_POPUP_TYPE, _e_gadcon_popup_free);
|
|
if (!pop) return NULL;
|
|
e_object_delay_del_set(E_OBJECT(pop), _e_gadcon_popup_delay_del);
|
|
|
|
o = edje_object_add(e_comp_get(gcc)->evas);
|
|
e_theme_edje_object_set(o, "base/theme/gadman", "e/gadman/popup");
|
|
pop->o_bg = o;
|
|
|
|
pop->comp_object = e_comp_object_util_add(o, noshadow ? E_COMP_OBJECT_TYPE_NONE : E_COMP_OBJECT_TYPE_POPUP);
|
|
if (e_comp_get(gcc)->nocomp)
|
|
evas_object_layer_set(pop->comp_object, E_LAYER_CLIENT_NORMAL);
|
|
else
|
|
evas_object_layer_set(pop->comp_object, E_LAYER_POPUP);
|
|
|
|
pop->gcc = gcc;
|
|
pop->gadcon_lock = 1;
|
|
pop->gadcon_was_locked = 0;
|
|
|
|
return pop;
|
|
}
|
|
|
|
EAPI void
|
|
e_gadcon_popup_content_set(E_Gadcon_Popup *pop, Evas_Object *o)
|
|
{
|
|
Evas_Object *old_o;
|
|
|
|
if (!pop) return;
|
|
E_OBJECT_CHECK(pop);
|
|
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
|
|
|
|
old_o = edje_object_part_swallow_get(pop->o_bg, "e.swallow.content");
|
|
if (old_o != o)
|
|
{
|
|
if (old_o)
|
|
{
|
|
edje_object_part_unswallow(pop->o_bg, old_o);
|
|
evas_object_del(old_o);
|
|
}
|
|
edje_object_part_swallow(pop->o_bg, "e.swallow.content", o);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
|
|
_e_gadcon_popup_del_cb, pop);
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
_e_gadcon_popup_changed_size_hints_cb, pop);
|
|
}
|
|
pop->content = o;
|
|
_e_gadcon_popup_size_recalc(pop, o);
|
|
}
|
|
|
|
EAPI void
|
|
e_gadcon_popup_show(E_Gadcon_Popup *pop)
|
|
{
|
|
E_OBJECT_CHECK(pop);
|
|
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
|
|
|
|
if (pop->visible) return;
|
|
|
|
_e_gadcon_popup_position(pop);
|
|
pop->autoclose_handlers[0] = ecore_event_handler_add(E_EVENT_DESK_AFTER_SHOW, _e_popup_autoclose_deskafter_show_cb, NULL);
|
|
pop->autoclose_handlers[1] = ecore_event_handler_add(E_EVENT_CLIENT_FULLSCREEN, _e_popup_autoclose_client_fullscreen_cb, NULL);
|
|
if (pop->content)
|
|
e_comp_object_util_del_list_append(pop->comp_object, pop->content);
|
|
evas_object_show(pop->comp_object);
|
|
pop->visible = EINA_TRUE;
|
|
}
|
|
|
|
EAPI void
|
|
e_gadcon_popup_hide(E_Gadcon_Popup *pop)
|
|
{
|
|
E_OBJECT_CHECK(pop);
|
|
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
|
|
if (pop->pinned) return;
|
|
evas_object_hide(pop->comp_object);
|
|
if (pop->gadcon_was_locked)
|
|
_e_gadcon_popup_locked_set(pop, 0);
|
|
pop->visible = EINA_FALSE;
|
|
}
|
|
|
|
EAPI void
|
|
e_gadcon_popup_toggle_pinned(E_Gadcon_Popup *pop)
|
|
{
|
|
if (!pop) return;
|
|
E_OBJECT_CHECK(pop);
|
|
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
|
|
|
|
if (pop->pinned)
|
|
{
|
|
pop->pinned = 0;
|
|
edje_object_signal_emit(pop->o_bg, "e,state,unpinned", "e");
|
|
}
|
|
else
|
|
{
|
|
pop->pinned = 1;
|
|
edje_object_signal_emit(pop->o_bg, "e,state,pinned", "e");
|
|
}
|
|
}
|
|
|
|
EAPI void
|
|
e_gadcon_popup_lock_set(E_Gadcon_Popup *pop, Eina_Bool setting)
|
|
{
|
|
E_OBJECT_CHECK(pop);
|
|
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
|
|
|
|
setting = !!setting;
|
|
if (pop->gadcon_lock == setting) return;
|
|
pop->gadcon_lock = setting;
|
|
|
|
if (setting != pop->gadcon_was_locked)
|
|
_e_gadcon_popup_locked_set(pop, setting);
|
|
}
|