369 lines
10 KiB
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;
|
||
|
}
|
||
|
}
|