enlightenment-module-desksa.../src/gadgets/bryce.c

369 lines
10 KiB
C

#include "e_mod_main.h"
#include "gadget.h"
typedef struct Bryce
{
Evas_Object *bryce;
Evas_Object *layout;
Evas_Object *site;
Evas_Object *scroller;
Evas_Object *autohide_event;
Evas_Object *parent; //comp_object is not an elm widget
char *style;
int size;
int x, y;
int autohide_size;
E_Layer layer;
Ecore_Job *calc_job;
Ecore_Timer *autohide_timer;
Eina_Bool autosize : 1;
Eina_Bool autohide : 1;
Eina_Bool hidden : 1;
Eina_Bool animating : 1;
} Bryce;
#define BRYCE_GET(obj) \
Bryce *b; \
b = evas_object_data_get((obj), "__bryce"); \
if (!b) abort()
static void
_bryce_autohide_end(void *data, Efx_Map_Data *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
{
Bryce *b = data;
b->animating = 0;
}
static void
_bryce_autohide_coords(Bryce *b, int *x, int *y)
{
int ox, oy, ow, oh;
Z_Gadget_Site_Anchor an;
if (b->parent == e_comp->elm)
{
E_Zone *zone;
zone = e_comp_object_util_zone_get(b->bryce);
ox = zone->w, oy = zone->y, ow = zone->w, oh = zone->h;
}
else
evas_object_geometry_get(b->parent, &ox, &oy, &ow, &oh);
an = z_gadget_site_anchor_get(b->site);
if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_HORIZONTAL)
{
*x = b->x;
if (an & Z_GADGET_SITE_ANCHOR_TOP)
*y = oy - b->size + b->autohide_size;
if (an & Z_GADGET_SITE_ANCHOR_BOTTOM)
*y = oy + oh + b->size - b->autohide_size;
}
else if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_VERTICAL)
{
*y = b->y;
if (an & Z_GADGET_SITE_ANCHOR_LEFT)
*x = ox - b->size + b->autohide_size;
if (an & Z_GADGET_SITE_ANCHOR_RIGHT)
*x = ox + ow + b->size - b->autohide_size;
}
}
static void
_bryce_position(Bryce *b, int w, int h)
{
int ox, oy, ow, oh;
int x, y;
Z_Gadget_Site_Anchor an;
if (b->parent == e_comp->elm)
{
E_Zone *zone;
zone = e_comp_object_util_zone_get(b->bryce);
ox = zone->x, oy = zone->y, ow = zone->w, oh = zone->h;
e_comp_object_util_center_pos_get(b->bryce, &x, &y);
}
else
{
evas_object_geometry_get(b->parent, &ox, &oy, &ow, &oh);
x = ox + (ow - w) / 2;
y = oy + (oh - h) / 2;
}
an = z_gadget_site_anchor_get(b->site);
if (an & Z_GADGET_SITE_ANCHOR_LEFT)
x = ox;
if (an & Z_GADGET_SITE_ANCHOR_TOP)
y = oy;
if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_HORIZONTAL)
{
if (an & Z_GADGET_SITE_ANCHOR_RIGHT)
x = ox + ow - w;
if (an & Z_GADGET_SITE_ANCHOR_BOTTOM)
y = oy + oh - b->size;
}
else if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_VERTICAL)
{
if (an & Z_GADGET_SITE_ANCHOR_RIGHT)
x = ox + ow - b->size;
if (an & Z_GADGET_SITE_ANCHOR_BOTTOM)
y = oy + oh - h;
}
b->x = x, b->y = y;
if (b->animating)
{
if (b->hidden)
{
_bryce_autohide_coords(b, &x, &y);
efx_move(b->bryce, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
}
else
efx_move(b->bryce, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
return;
}
else if (b->hidden)
_bryce_autohide_coords(b, &x, &y);
evas_object_move(b->bryce, x, y);
}
static void
_bryce_autosize(Bryce *b)
{
int lw, lh, sw, sh, maxw, maxh;
b->calc_job = NULL;
if (b->parent == e_comp->elm) //screen-based bryce
{
E_Zone *zone;
zone = e_comp_object_util_zone_get(b->bryce);
maxw = zone->w, maxh = zone->h;
}
else
evas_object_geometry_get(b->parent, NULL, NULL, &maxw, &maxh);
evas_object_size_hint_min_get(b->layout, &lw, &lh);
evas_object_size_hint_min_get(b->site, &sw, &sh);
if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_HORIZONTAL)
evas_object_resize(b->bryce, MIN(lw + sw, maxw), b->size);
else if (z_gadget_site_orient_get(b->site) == Z_GADGET_SITE_ORIENT_VERTICAL)
evas_object_resize(b->bryce, b->size, MIN(lh + sh, maxh));
if (b->parent == e_comp->elm) //screen-based bryce
_bryce_position(b, lw + sw, lh + sh);
}
static Eina_Bool
_bryce_autohide_timeout(Bryce *b)
{
int x, y;
b->autohide_timer = NULL;
b->hidden = b->animating = 1;
_bryce_autohide_coords(b, &x, &y);
efx_move(b->bryce, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(x, y), 0.5, _bryce_autohide_end, b);
return EINA_FALSE;
}
static void
_bryce_autohide_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Bryce *b = data;
int x, y, w, h;
evas_object_geometry_get(obj, &x, &y, &w, &h);
evas_object_geometry_set(b->autohide_event, x, y, w, h);
}
static void
_bryce_autohide_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Bryce *b = data;
b->autohide_timer = ecore_timer_add(1.0, (Ecore_Task_Cb)_bryce_autohide_timeout, b);
}
static void
_bryce_autohide_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Bryce *b = data;
if (b->animating && (!b->hidden)) return;
E_FREE_FUNC(b->autohide_timer, ecore_timer_del);
efx_move(b->bryce, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b);
b->animating = 1;
b->hidden = 0;
}
static void
_bryce_style(Evas_Object *bryce, Eina_Stringshare *name, Evas_Object *g)
{
Evas_Object *ly;
static int n;
char buf[1024];
BRYCE_GET(bryce);
ly = elm_layout_add(b->site);
if (n++ % 2)
snprintf(buf, sizeof(buf), "z/bryce/%s/inset", b->style ?: "default");
else
snprintf(buf, sizeof(buf), "z/bryce/%s/plain", b->style ?: "default");
e_theme_edje_object_set(ly, NULL, buf);
z_gadget_util_layout_style_init(g, ly);
elm_object_part_content_set(ly, "e.swallow.content", g);
}
static void
_bryce_site_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Bryce *b = data;
if (b->autosize && (!b->calc_job))
b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b);
}
static void
_bryce_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Bryce *b = data;
E_Layer layer;
layer = evas_object_layer_get(obj);
if (layer == b->layer) return;
if (layer == E_LAYER_DESKTOP)
e_comp_object_util_type_set(b->bryce, E_COMP_OBJECT_TYPE_NONE);
else
e_comp_object_util_type_set(b->bryce, E_COMP_OBJECT_TYPE_POPUP);
b->layer = layer;
}
static void
_bryce_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Bryce *b = data;
free(b->style);
free(data);
}
Z_API Evas_Object *
z_bryce_add(Evas_Object *parent)
{
Evas_Object *ly, *bryce, *scr, *site;
Bryce *b;
ly = elm_layout_add(parent);
e_theme_edje_object_set(ly, NULL, "z/bryce/default/base");
scr = elm_scroller_add(ly);
elm_object_style_set(scr, "bryce");
site = z_gadget_site_add(scr, Z_GADGET_SITE_ORIENT_HORIZONTAL);
z_gadget_site_owner_setup(site, Z_GADGET_SITE_ANCHOR_TOP, _bryce_style);
elm_object_content_set(scr, site);
elm_object_part_content_set(ly, "e.swallow.content", scr);
elm_layout_signal_emit(ly, "e,state,orient,top", "e");
//evas_object_geometry_set(ly, 0, 0, 48, e_comp->h);
evas_object_show(ly);
bryce = e_comp_object_util_add(ly, E_COMP_OBJECT_TYPE_POPUP);
evas_object_data_set(bryce, "comp_skip", (void*)1);
evas_object_layer_set(bryce, E_LAYER_POPUP);
evas_object_lower(bryce);
b = E_NEW(Bryce, 1);
b->bryce = bryce;
b->layout = ly;
b->site = site;
b->scroller = scr;
b->parent = parent;
b->size = 48;
{
const char *str;
str = elm_layout_data_get(ly, "hidden_state_size");
if (str && str[0])
b->autohide_size = strtol(str, NULL, 10);
}
evas_object_data_set(bryce, "__bryce", b);
evas_object_data_set(scr, "__bryce", b);
evas_object_event_callback_add(bryce, EVAS_CALLBACK_DEL, _bryce_del, b);
evas_object_event_callback_add(bryce, EVAS_CALLBACK_RESTACK, _bryce_restack, b);
evas_object_event_callback_add(site, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _bryce_site_hints, b);
evas_object_clip_set(bryce, e_comp_zone_xy_get(0, 0)->bg_clip_object);
return bryce;
}
Z_API Evas_Object *
z_bryce_site_get(Evas_Object *bryce)
{
BRYCE_GET(bryce);
return b->site;
}
Z_API void
z_bryce_autosize_set(Evas_Object *bryce, Eina_Bool set)
{
int w, h;
BRYCE_GET(bryce);
set = !!set;
if (b->autosize == set) return;
b->autosize = set;
if (set)
{
_bryce_autosize(b);
return;
}
evas_object_geometry_get(b->parent, NULL, NULL, &w, &h);
_bryce_position(b, w, h);
}
Z_API void
z_bryce_autohide_set(Evas_Object *bryce, Eina_Bool set)
{
BRYCE_GET(bryce);
set = !!set;
if (b->autohide == set) return;
b->autohide = set;
if (set)
{
int x, y, w, h;
b->autohide_event = evas_object_rectangle_add(evas_object_evas_get(bryce));
evas_object_geometry_get(bryce, &x, &y, &w, &h);
evas_object_geometry_set(b->autohide_event, x, y, w, h);
evas_object_color_set(b->autohide_event, 0, 0, 0, 0);
evas_object_repeat_events_set(b->autohide_event, 1);
evas_object_layer_set(b->autohide_event, E_LAYER_POPUP);
evas_object_show(b->autohide_event);
evas_object_event_callback_add(b->autohide_event, EVAS_CALLBACK_MOUSE_IN, _bryce_autohide_mouse_in, b);
evas_object_event_callback_add(b->autohide_event, EVAS_CALLBACK_MOUSE_OUT, _bryce_autohide_mouse_out, b);
evas_object_event_callback_add(bryce, EVAS_CALLBACK_MOVE, _bryce_autohide_moveresize, b);
evas_object_event_callback_add(bryce, EVAS_CALLBACK_RESIZE, _bryce_autohide_moveresize, b);
ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
if (!E_INSIDE(x, y, b->x, b->y, w, h))
b->autohide_timer = ecore_timer_add(1.0, (Ecore_Task_Cb)_bryce_autohide_timeout, b);
}
else
{
E_FREE_FUNC(b->autohide_event, evas_object_del);
evas_object_event_callback_del_full(bryce, EVAS_CALLBACK_MOVE, _bryce_autohide_moveresize, b);
evas_object_event_callback_del_full(bryce, EVAS_CALLBACK_RESIZE, _bryce_autohide_moveresize, b);
if (!b->hidden) return;
efx_move(b->bryce, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b);
b->animating = 1;
b->hidden = 0;
}
}