enlightenment-module-news/src/news_popup.c

236 lines
5.3 KiB
C

#include "News.h"
static Eina_List *_popups_warn;
static void _check_overlap(int *px, int *py, int *pw, int *ph, int tries, int org_x, int org_y);
static void _try_close(News_Popup *popw);
static Eina_Bool _cb_timer(void *data);
static void _cb_edje_close(void *data, Evas_Object *obj, const char *emission, const char *source);
static void _cb_edje_desactivate(void *data, Evas_Object *obj, const char *emission, const char *source);
/*
* Public functions
*/
int
news_popup_init(void)
{
_popups_warn = NULL;
return 1;
}
void
news_popup_shutdown(void)
{
Eina_List *l;
for (l = _popups_warn; l; l = eina_list_next(l))
{
News_Popup *p;
p = eina_list_data_get(l);
news_popup_del(p);
}
eina_list_free(_popups_warn);
_popups_warn = NULL;
}
News_Popup *
news_popup_add(int type, const char *title, const char *text, int timer, int (*func_close) (News_Popup *popw, void *data), void (*func_desactivate) (News_Popup *popw, void *data), void *data)
{
E_Zone *zone;
News_Popup *popw;
int fw, fh;
int ecanvas_w, ecanvas_h;
popw = E_NEW(News_Popup, 1);
popw->type = type;
popw->timer_org = timer;
zone = e_util_zone_current_get(e_manager_current_get());
news_util_ecanvas_geometry_get(&ecanvas_w, &ecanvas_h);
/* pop */
popw->pop = e_popup_new(zone, 0, 0, 1, 1);
if (!popw->pop)
{
news_popup_del(popw);
return 0;
}
evas_event_freeze(popw->pop->evas);
e_popup_layer_set(popw->pop, E_COMP_CANVAS_LAYER_POPUP, 0);
/* face and tb */
popw->face = edje_object_add(popw->pop->evas);
news_theme_edje_set(popw->face, NEWS_THEME_POPW);
edje_object_signal_callback_add(popw->face, "close", "popup",
_cb_edje_close, popw);
edje_object_signal_callback_add(popw->face, "desactivate", "popup",
_cb_edje_desactivate, popw);
// TODO
/* log */
// TODO
/* update times */
// TODO
/* type */
edje_object_message_send(popw->face, EDJE_MESSAGE_INT,
NEWS_POPUP_EDJE_MESSAGE_TYPE,
&type);
/* pos */
popw->x = ecanvas_w - (fw + 20);;
popw->y = ecanvas_h - (fh + 20);;
popw->w = fw;
popw->h = fh;
/* timer */
if (timer)
popw->timer = ecore_timer_add(timer, _cb_timer, popw);
/* close and desactivate functions */
popw->func_close = func_close;
if (func_desactivate)
{
int show_desactivate = 1;
popw->func_desactivate = func_desactivate;
edje_object_message_send(popw->face, EDJE_MESSAGE_INT,
NEWS_POPUP_EDJE_MESSAGE_SHOW_DESACTIVATE,
&show_desactivate);
}
/* attach data */
popw->data = data;
/* check for popup overlaps */
_check_overlap(&popw->x, &popw->y, &popw->w, &popw->h, 0, popw->x, popw->y);
e_popup_move_resize(popw->pop, popw->x, popw->y, popw->w, popw->h);
DPOP(("New: %dx%d : %dx%d", popw->x, popw->y, popw->w, popw->h));
DPOP(("New face: %dx%d", fw, fh));
/* go ! */
evas_object_show(popw->face);
e_popup_content_set(popw->pop, popw->face);
evas_event_thaw(popw->pop->evas);
e_popup_show(popw->pop);
_popups_warn = eina_list_append(_popups_warn, popw);
return popw;
}
void
news_popup_del(News_Popup *popw)
{
if (popw->timer)
ecore_timer_del(popw->timer);
if (popw->tb)
evas_object_del(popw->tb);
if (popw->face)
evas_object_del(popw->face);
if (popw->pop)
e_object_del(E_OBJECT(popw->pop));
_popups_warn = eina_list_remove(_popups_warn, popw);
free(popw);
}
/*
* Private functions
*
*/
static void
_check_overlap(int *px, int *py, int *pw, int *ph, int tries, int org_x, int org_y)
{
Eina_List *l;
News_Popup *p;
int pxw, pyh;
int p_xw, p_yh;
pxw = *px + *pw;
pyh = *py + *ph;
for (l = _popups_warn; l; l = eina_list_next(l))
{
p = eina_list_data_get(l);
p_xw = p->x + p->w;
p_yh = p->y + p->h;
if (((p->x >= *px) && (p->x <= pxw) &&
(p->y >= *py) && (p->y <= pyh))
||
((*px >= p->x) && (*px <= p_xw) &&
(*py >= p->y) && (*py <= p_yh)))
{
/* overlap ! correct coords */
/* try upper, and then on the left */
/* TODO...: try down and right, maybe placement policy ? */
DPOP(("Overlap !"));
*py = p->y - (*ph + NEWS_POPUP_OVERLAP_BORDER);
if (*py < 0)
{
*py = org_y;
*px = *px - (*px + NEWS_POPUP_OVERLAP_BORDER);
if (*px < 0) break;
}
tries++;
if (tries > NEWS_POPUP_OVERLAP_CHECK_MAX)
return;
else
_check_overlap(px, py, pw, ph, tries, org_x, org_y);
break;
}
}
}
static void
_try_close(News_Popup *popw)
{
int del = 1;
if (popw->func_close)
{
if (!popw->func_close(popw, popw->data))
del = 0;
}
if (del)
news_popup_del(popw);
}
static Eina_Bool
_cb_timer(void *data)
{
News_Popup *popw;
popw = data;
_try_close(popw);
return EINA_FALSE;
}
static void
_cb_edje_close(void *data, Evas_Object *obj, const char *emission, const char *source)
{
News_Popup *popw;
popw = data;
_try_close(popw);
}
static void
_cb_edje_desactivate(void *data, Evas_Object *obj, const char *emission, const char *source)
{
News_Popup *popw;
popw = data;
if (popw->func_desactivate)
popw->func_desactivate(popw, popw->data);
}