diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 675bccf3b..710112bc9 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -201,6 +201,7 @@ e_win.h \ e_xinerama.h \ e_xkb.h \ e_xsettings.h \ +e_zoomap.h \ e_zone.h if HAVE_WAYLAND_CLIENTS @@ -371,6 +372,7 @@ e_win.c \ e_xinerama.c \ e_xkb.c \ e_xsettings.c \ +e_zoomap.c \ e_zone.c \ $(ENLIGHTENMENTHEADERS) diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 5863b222b..70b5ceb25 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -55,6 +55,7 @@ #include "e_remember.h" #include "e_win.h" #include "e_pan.h" +#include "e_zoomap.h" #include "e_dialog.h" #include "e_configure.h" #include "e_configure_option.h" diff --git a/src/bin/e_menu.c b/src/bin/e_menu.c index e333eb8c0..0c37fad16 100644 --- a/src/bin/e_menu.c +++ b/src/bin/e_menu.c @@ -1170,6 +1170,8 @@ e_menu_idler_before(void) m->prev.h = m->cur.h; w = m->cur.w; h = m->cur.h; + evas_object_resize(m->bg_object, w, h); + evas_object_resize(m->bg_object_wrap, w, h); if (m->cw) e_comp_win_resize(m->cw, w, h); } @@ -1210,9 +1212,10 @@ e_menu_idler_before(void) m->prev.visible = m->cur.visible; if (!m->cw) { - evas_object_move(m->bg_object, m->cur.x, m->cur.y); evas_object_resize(m->bg_object, m->cur.w, m->cur.h); - E_LAYER_SET(m->bg_object, E_COMP_CANVAS_LAYER_MENU); + evas_object_move(m->bg_object_wrap, m->cur.x, m->cur.y); + evas_object_resize(m->bg_object_wrap, m->cur.w, m->cur.h); + E_LAYER_SET(m->bg_object_wrap, E_COMP_CANVAS_LAYER_MENU); } e_comp_win_show(m->cw); } @@ -1284,7 +1287,8 @@ _e_menu_free(E_Menu *m) if (m->parent_item) m->parent_item->submenu = NULL; /* del callback causes this to unrealize the menu */ - if (m->bg_object) evas_object_del(m->bg_object); + if (m->bg_object_wrap) evas_object_del(m->bg_object_wrap); + m->bg_object_wrap = NULL; EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi) e_object_del(E_OBJECT(mi)); if (m->in_active_list) @@ -1393,6 +1397,8 @@ _e_menu_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, vo E_Menu *m = data; m->bg_object = NULL; + evas_object_del(m->bg_object_wrap); + m->bg_object_wrap = NULL; _e_menu_unrealize(m); } @@ -1688,6 +1694,7 @@ _e_menu_realize(E_Menu *m) Evas_Object *o; Eina_List *l; E_Menu_Item *mi; + const char *s; if (m->realized || (!m->items)) return; m->realized = 1; @@ -1701,9 +1708,6 @@ _e_menu_realize(E_Menu *m) o = edje_object_add(m->evas); evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_menu_del_cb, m); m->bg_object = o; - evas_object_name_set(o, "menu->bg_object"); - evas_object_data_set(o, "e_menu", m); - evas_object_data_set(o, "eobj", m); e_theme_edje_object_set(o, "base/theme/menus", "e/widgets/menu/default/background"); if (m->header.title) { @@ -1712,6 +1716,17 @@ _e_menu_realize(E_Menu *m) edje_object_message_signal_process(o); } + o = e_zoomap_add(m->evas); + evas_object_name_set(o, "menu->bg_object_wrap"); + evas_object_data_set(o, "e_menu", m); + evas_object_data_set(o, "eobj", m); + m->bg_object_wrap = o; + s = edje_object_data_get(m->bg_object, "argb"); + if (!s) s = edje_object_data_get(m->bg_object, "shaped"); + if ((s) && (s[0] == '1')) e_zoomap_solid_set(o, EINA_FALSE); + else e_zoomap_solid_set(o, EINA_TRUE); + e_zoomap_child_set(o, m->bg_object); + o = e_box_add(m->evas); evas_object_name_set(o, "menu->container_object"); m->container_object = o; @@ -1981,6 +1996,8 @@ _e_menu_unrealize(E_Menu *m) m->header.icon = NULL; if (m->bg_object) evas_object_del(m->bg_object); m->bg_object = NULL; + if (m->bg_object_wrap) evas_object_del(m->bg_object_wrap); + m->bg_object_wrap = NULL; if (m->container_object) evas_object_del(m->container_object); m->container_object = NULL; m->cur.visible = 0; diff --git a/src/bin/e_menu.h b/src/bin/e_menu.h index 8c4d05c29..36f22cc89 100644 --- a/src/bin/e_menu.h +++ b/src/bin/e_menu.h @@ -56,6 +56,7 @@ struct _E_Menu E_Container_Shape *shape; Ecore_Job *dangling_job; Evas *evas; + Evas_Object *bg_object_wrap; Evas_Object *bg_object; Evas_Object *container_object; Evas_Coord container_x, container_y, container_w, container_h; diff --git a/src/bin/e_zoomap.c b/src/bin/e_zoomap.c new file mode 100644 index 000000000..8084076a7 --- /dev/null +++ b/src/bin/e_zoomap.c @@ -0,0 +1,323 @@ +#include "e.h" + +#define SMART_NAME "e_zoomap" +#define API_ENTRY E_Smart_Data * sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME))) +#define INTERNAL_ENTRY E_Smart_Data * sd; sd = evas_object_smart_data_get(obj); if (!sd) return; +typedef struct _E_Smart_Data E_Smart_Data; + +struct _E_Smart_Data +{ + Evas_Object *smart_obj, *child_obj; + Evas_Coord x, y, w, h; + Evas_Coord child_w, child_h; + Eina_Bool solid : 1; + Eina_Bool smooth : 1; + Eina_Bool always : 1; +}; + +/* local subsystem functions */ +static void _e_smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _e_smart_child_resize_hook(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _e_smart_reconfigure(E_Smart_Data *sd); +static void _e_smart_add(Evas_Object *obj); +static void _e_smart_del(Evas_Object *obj); +static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); +static void _e_smart_show(Evas_Object *obj); +static void _e_smart_hide(Evas_Object *obj); +static void _e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a); +static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip); +static void _e_smart_clip_unset(Evas_Object *obj); +static void _e_smart_init(void); + +/* local subsystem globals */ +static Evas_Smart *_e_smart = NULL; + +/* externally accessible functions */ +EAPI Evas_Object * +e_zoomap_add(Evas *evas) +{ + _e_smart_init(); + return evas_object_smart_add(evas, _e_smart); +} + +EAPI void +e_zoomap_child_set(Evas_Object *obj, Evas_Object *child) +{ + API_ENTRY return; + if (child == sd->child_obj) return; + if (sd->child_obj) + { + evas_object_clip_unset(sd->child_obj); + evas_object_smart_member_del(sd->child_obj); + evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_DEL, + _e_smart_child_del_hook); + evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_RESIZE, + _e_smart_child_resize_hook); + sd->child_obj = NULL; + } + if (child) + { + int r, g, b, a; + + sd->child_obj = child; + evas_object_smart_member_add(sd->child_obj, sd->smart_obj); + evas_object_geometry_get(sd->child_obj, NULL, NULL, + &sd->child_w, &sd->child_h); + evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, + _e_smart_child_del_hook, sd); + evas_object_event_callback_add(child, EVAS_CALLBACK_RESIZE, + _e_smart_child_resize_hook, sd); + if (evas_object_visible_get(obj)) evas_object_show(sd->child_obj); + else evas_object_hide(sd->child_obj); + evas_object_color_get(sd->smart_obj, &r, &g, &b, &a); + evas_object_color_set(sd->child_obj, r, g, b, a); + evas_object_clip_set(sd->child_obj, evas_object_clip_get(sd->smart_obj)); + _e_smart_reconfigure(sd); + } +} + +EAPI Evas_Object * +e_zoomap_child_get(Evas_Object *obj) +{ + API_ENTRY return NULL; + return sd->child_obj; +} + +EAPI void +e_zoomap_smooth_set(Evas_Object *obj, Eina_Bool smooth) +{ + API_ENTRY return; + smooth = !!smooth; + if (sd->smooth == smooth) return; + sd->smooth = smooth; + _e_smart_reconfigure(sd); +} + +EAPI Eina_Bool +e_zoomap_smooth_get(Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->smooth; +} + +EAPI void +e_zoomap_solid_set(Evas_Object *obj, Eina_Bool solid) +{ + API_ENTRY return; + solid = !!solid; + if (sd->solid == solid) return; + sd->solid = solid; + _e_smart_reconfigure(sd); +} + +EAPI Eina_Bool +e_zoomap_solid_get(Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->solid; +} + +EAPI void +e_zoomap_always_set(Evas_Object *obj, Eina_Bool always) +{ + API_ENTRY return; + always = !!always; + if (sd->always == always) return; + sd->always = always; + _e_smart_reconfigure(sd); +} + +EAPI Eina_Bool +e_zoomap_always_get(Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->always; +} + +/* local subsystem functions */ +static void +_e_smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + E_Smart_Data *sd; + + sd = data; + sd->child_obj = NULL; +} + +static void +_e_smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + E_Smart_Data *sd; + Evas_Coord w, h; + + sd = data; + if (!sd->child_obj) return; + evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h); + if ((w != sd->child_w) || (h != sd->child_h)) + { + sd->child_w = w; + sd->child_h = h; + _e_smart_reconfigure(sd); + } +} + +static void +_e_smart_reconfigure(E_Smart_Data *sd) +{ + if (!sd->child_obj) return; + if ((!sd->always) && + ((sd->w == sd->child_w) && (sd->h == sd->child_h))) + { + evas_object_map_set(sd->child_obj, NULL); + evas_object_map_enable_set(sd->child_obj, EINA_FALSE); + evas_object_move(sd->child_obj, sd->x, sd->y); + evas_object_resize(sd->child_obj, sd->w, sd->h); + } + else + { + Evas_Map *m; + Evas *e = evas_object_evas_get(sd->child_obj); + Evas_Coord cx = 0, cy = 0; + int r = 0, g = 0, b = 0, a = 0; + + evas_object_geometry_get(sd->child_obj, &cx, &cy, NULL, NULL); + evas_object_color_get(sd->child_obj, &r, &g, &b, &a); + if ((cx != sd->x) || (cy != sd->y)) + { + evas_smart_objects_calculate(e); + evas_nochange_push(e); + evas_object_move(sd->child_obj, sd->x, sd->y); + evas_smart_objects_calculate(e); + evas_nochange_pop(e); + } + m = evas_map_new(4); + evas_map_util_points_populate_from_geometry(m, sd->x, sd->y, + sd->w, sd->h, 0); + evas_map_point_image_uv_set(m, 0, 0, 0); + evas_map_point_image_uv_set(m, 1, sd->child_w, 0); + evas_map_point_image_uv_set(m, 2, sd->child_w, sd->child_h); + evas_map_point_image_uv_set(m, 3, 0, sd->child_h); + evas_map_smooth_set(m, sd->smooth); + evas_map_point_color_set(m, 0, r, g, b, a); + evas_map_point_color_set(m, 1, r, g, b, a); + evas_map_point_color_set(m, 2, r, g, b, a); + evas_map_point_color_set(m, 3, r, g, b, a); + //if (a >= 255) evas_map_alpha_set(m, !sd->solid); + //else evas_map_alpha_set(m, EINA_TRUE); + evas_map_alpha_set(m, EINA_TRUE); + evas_object_map_set(sd->child_obj, m); + evas_object_map_enable_set(sd->child_obj, EINA_TRUE); + evas_map_free(m); + } +} + +static void +_e_smart_add(Evas_Object *obj) +{ + E_Smart_Data *sd; + + sd = E_NEW(E_Smart_Data, 1); + if (!sd) return; + sd->smart_obj = obj; + sd->x = sd->y = sd->w = sd->h = 0; + sd->solid = EINA_TRUE; + sd->always = EINA_TRUE; + sd->smooth = EINA_TRUE; + evas_object_smart_data_set(obj, sd); +} + +static void +_e_smart_del(Evas_Object *obj) +{ + INTERNAL_ENTRY; + if (sd->child_obj) + { + evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_DEL, + _e_smart_child_del_hook); + evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_RESIZE, + _e_smart_child_resize_hook); + evas_object_del(sd->child_obj); + sd->child_obj = NULL; + } + E_FREE(sd); +} + +static void +_e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + INTERNAL_ENTRY; + sd->x = x; + sd->y = y; + _e_smart_reconfigure(sd); +} + +static void +_e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + INTERNAL_ENTRY; + sd->w = w; + sd->h = h; + _e_smart_reconfigure(sd); +} + +static void +_e_smart_show(Evas_Object *obj) +{ + INTERNAL_ENTRY; + if (sd->child_obj) evas_object_show(sd->child_obj); + if (!evas_object_map_enable_get(sd->child_obj)) _e_smart_reconfigure(sd); +} + +static void +_e_smart_hide(Evas_Object *obj) +{ + INTERNAL_ENTRY; + if ((!sd->always) && + (evas_object_map_enable_get(sd->child_obj))) + { + evas_object_map_set(sd->child_obj, NULL); + evas_object_map_enable_set(sd->child_obj, EINA_FALSE); + evas_object_move(sd->child_obj, sd->x, sd->y); + evas_object_resize(sd->child_obj, sd->w, sd->h); + } + if (sd->child_obj) evas_object_hide(sd->child_obj); +} + +static void +_e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a) +{ + INTERNAL_ENTRY; + if (sd->child_obj) evas_object_color_set(sd->child_obj, r, g, b, a); +} + +static void +_e_smart_clip_set(Evas_Object *obj, Evas_Object *clip) +{ + INTERNAL_ENTRY; + if (sd->child_obj) evas_object_clip_set(sd->child_obj, clip); +} + +static void +_e_smart_clip_unset(Evas_Object *obj) +{ + INTERNAL_ENTRY; + if (sd->child_obj) evas_object_clip_unset(sd->child_obj); +} + +/* never need to touch this */ +static void +_e_smart_init(void) +{ + static const Evas_Smart_Class sc = + { + SMART_NAME, EVAS_SMART_CLASS_VERSION, + _e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize, + _e_smart_show, _e_smart_hide, _e_smart_color_set, _e_smart_clip_set, + _e_smart_clip_unset, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + if (_e_smart) return; + _e_smart = evas_smart_class_new(&sc); +} + diff --git a/src/bin/e_zoomap.h b/src/bin/e_zoomap.h new file mode 100644 index 000000000..31ee69442 --- /dev/null +++ b/src/bin/e_zoomap.h @@ -0,0 +1,17 @@ +#ifdef E_TYPEDEFS +#else +#ifndef E_ZOOMAP_H +#define E_ZOOMAP_H + +EAPI Evas_Object *e_zoomap_add (Evas *evas); +EAPI void e_zoomap_child_set (Evas_Object *obj, Evas_Object *child); +EAPI Evas_Object *e_zoomap_child_get (Evas_Object *obj); +EAPI void e_zoomap_smooth_set (Evas_Object *obj, Eina_Bool smooth); +EAPI Eina_Bool e_zoomap_smooth_get (Evas_Object *obj); +EAPI void e_zoomap_solid_set (Evas_Object *obj, Eina_Bool solid); +EAPI Eina_Bool e_zoomap_solid_get (Evas_Object *obj); +EAPI void e_zoomap_always_set (Evas_Object *obj, Eina_Bool always); +EAPI Eina_Bool e_zoomap_always_get (Evas_Object *obj); + +#endif +#endif