From 6e032ce35d20a9b3b1adad70c336839d578f9eb3 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 2 Mar 2016 15:56:16 -0500 Subject: [PATCH] add bryces: new shelf replacement see e_bryce.h --- src/bin/Makefile.mk | 3 + src/bin/e_bryce.c | 1168 ++++++++++++++++++++++++++++++++++++++ src/bin/e_bryce.h | 22 + src/bin/e_bryce_editor.c | 414 ++++++++++++++ src/bin/e_config.c | 2 + src/bin/e_includes.h | 1 + src/bin/e_main.c | 7 + 7 files changed, 1617 insertions(+) create mode 100644 src/bin/e_bryce.c create mode 100644 src/bin/e_bryce.h create mode 100644 src/bin/e_bryce_editor.c diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 8c234c3e4..9c6ea40d1 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -69,6 +69,7 @@ src/bin/e_auth.h \ src/bin/e_backlight.h \ src/bin/e_bg.h \ src/bin/e_bindings.h \ +src/bin/e_bryce.h \ src/bin/e_client.h \ src/bin/e_client.x \ src/bin/e_color_dialog.h \ @@ -236,6 +237,8 @@ src/bin/e_auth.c \ src/bin/e_backlight.c \ src/bin/e_bg.c \ src/bin/e_bindings.c \ +src/bin/e_bryce.c \ +src/bin/e_bryce_editor.c \ src/bin/e_client.c \ src/bin/e_color.c \ src/bin/e_color_dialog.c \ diff --git a/src/bin/e_bryce.c b/src/bin/e_bryce.c new file mode 100644 index 000000000..834806390 --- /dev/null +++ b/src/bin/e_bryce.c @@ -0,0 +1,1168 @@ +#include "e.h" + +#define DEFAULT_LAYER E_LAYER_POPUP +#define E_BRYCE_TYPE 0xE31338 + +typedef struct Bryce +{ + E_Object *e_obj_inherit; + Eina_Stringshare *name; + + Evas_Object *bryce; + Evas_Object *layout; + Evas_Object *site; + Evas_Object *scroller; + Evas_Object *autohide_event; + Eina_List *zone_obstacles; + + Evas_Object *parent; //comp_object is not an elm widget + Eina_Stringshare *style; + int size; + int x, y; + int autohide_size; + E_Layer layer; + unsigned int zone; + E_Gadget_Site_Orient orient; + E_Gadget_Site_Anchor anchor; + + Ecore_Job *calc_job; + Ecore_Timer *save_timer; + Ecore_Timer *autohide_timer; + unsigned int autohide_blocked; + Eina_List *popups; + void *event_info; + uint64_t last_timestamp; + + /* config: do not bitfield! */ + Eina_Bool autosize; + Eina_Bool autohide; + + Eina_Bool hidden : 1; + Eina_Bool animating : 1; + Eina_Bool mouse_in : 1; + Eina_Bool noshadow : 1; + Eina_Bool size_changed : 1; +} Bryce; + +typedef struct Bryces +{ + Eina_List *bryces; +} Bryces; + +static E_Config_DD *edd_bryces; +static E_Config_DD *edd_bryce; +static Bryces *bryces; +static E_Action *resize_act; +static E_Action *menu_act; +static Eina_List *handlers; + +#define BRYCE_GET(obj) \ + Bryce *b; \ + b = evas_object_data_get((obj), "__bryce"); \ + if (!b) abort() + +static void +_bryce_obstacle_del(void *obs) +{ + Bryce *b = e_object_data_get(obs); + + b->zone_obstacles = eina_list_remove(b->zone_obstacles, obs); +} + +static void +_bryce_autohide_end(void *data, E_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; + E_Gadget_Site_Anchor an; + + if (b->parent == e_comp->elm) + { + E_Zone *zone; + + zone = e_comp_zone_number_get(b->zone); + ox = zone->x, oy = zone->y, ow = zone->w, oh = zone->h; + } + else + evas_object_geometry_get(b->parent, &ox, &oy, &ow, &oh); + an = e_gadget_site_anchor_get(b->site); + + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + { + *x = b->x; + + if (an & E_GADGET_SITE_ANCHOR_TOP) + *y = oy - b->size + b->autohide_size; + if (an & E_GADGET_SITE_ANCHOR_BOTTOM) + *y = oy + oh - b->autohide_size; + } + else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL) + { + *y = b->y; + + if (an & E_GADGET_SITE_ANCHOR_LEFT) + *x = ox - b->size + b->autohide_size; + if (an & E_GADGET_SITE_ANCHOR_RIGHT) + *x = ox + ow - b->autohide_size; + } +} + +static void +_bryce_position(Bryce *b, int w, int h, int *nx, int *ny) +{ + int ox, oy, ow, oh; + int x, y; + E_Gadget_Site_Anchor an; + + if (b->parent == e_comp->elm) + { + E_Zone *zone; + + zone = e_comp_zone_number_get(b->zone); + 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 = e_gadget_site_anchor_get(b->site); + if (an & E_GADGET_SITE_ANCHOR_LEFT) + x = ox; + if (an & E_GADGET_SITE_ANCHOR_TOP) + y = oy; + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + { + if (an & E_GADGET_SITE_ANCHOR_RIGHT) + x = ox + ow - w; + if (an & E_GADGET_SITE_ANCHOR_BOTTOM) + y = oy + oh - b->size; + if (!b->autosize) + x = ox; + } + else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL) + { + if (an & E_GADGET_SITE_ANCHOR_RIGHT) + x = ox + ow - b->size; + if (an & E_GADGET_SITE_ANCHOR_BOTTOM) + y = oy + oh - h; + if (!b->autosize) + y = oy; + } + b->x = x, b->y = y; + if (b->animating) + { + if (b->hidden) + { + _bryce_autohide_coords(b, &x, &y); + e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), 0.5, _bryce_autohide_end, b); + } + else + e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), 0.5, _bryce_autohide_end, b); + return; + } + else if (b->hidden) + _bryce_autohide_coords(b, &x, &y); + + if (nx && ny) + *nx = x, *ny = y; + else + evas_object_move(b->bryce, x, y); +} + +static void +_bryce_autosize(Bryce *b) +{ + int lw, lh, sw, sh, maxw, maxh, x, y, w, h; + + E_FREE_FUNC(b->calc_job, ecore_job_del); + if (!b->autosize) + { + evas_object_geometry_get(b->parent, NULL, NULL, &w, &h); + if (b->size_changed) + elm_object_content_unset(b->scroller); + _bryce_position(b, w, h, &x, &y); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), w, b->size * e_scale, 0.1, NULL, NULL); + else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL) + e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), b->size * e_scale, h, 0.1, NULL, NULL); + evas_object_smart_need_recalculate_set(b->site, 1); + evas_object_size_hint_min_set(b->site, -1, -1); + if (b->size_changed) + elm_object_content_set(b->scroller, b->site); + b->size_changed = 0; + return; + } + if (b->parent == e_comp->elm) //screen-based bryce + { + E_Zone *zone; + + zone = e_comp_zone_number_get(b->zone); + maxw = zone->w, maxh = zone->h; + } + else + evas_object_geometry_get(b->parent, NULL, NULL, &maxw, &maxh); + if (b->size_changed) + { + evas_object_geometry_get(b->bryce, NULL, NULL, &w, &h); + elm_object_content_unset(b->scroller); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + evas_object_resize(b->bryce, w * b->size * e_scale / h, b->size * e_scale); + else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL) + evas_object_resize(b->bryce, b->size * e_scale, h * b->size * e_scale / w); + evas_object_smart_need_recalculate_set(b->site, 1); + evas_object_size_hint_min_set(b->site, -1, -1); + evas_object_smart_calculate(b->site); + elm_object_content_set(b->scroller, b->site); + } + evas_object_size_hint_min_get(b->site, &sw, &sh); + edje_object_size_min_calc(elm_layout_edje_get(b->layout), &lw, &lh); + _bryce_position(b, lw + sw, lh + sh, &x, &y); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + w = MIN(MAX(lw + sw, b->size * e_scale), maxw), h = b->size * e_scale; + else if (b->orient == E_GADGET_SITE_ORIENT_VERTICAL) + w = b->size * e_scale, h = MIN(MAX(lh + sh, b->size * e_scale), maxh); + e_efx_resize(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(x, y), w, h, 0.1, NULL, NULL); + b->size_changed = 0; +} + +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); + e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_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_show(Bryce *b) +{ + E_FREE_FUNC(b->autohide_timer, ecore_timer_del); + if (b->animating && (!b->hidden)) return; + e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b); + b->animating = 1; + b->hidden = 0; +} + +static void +_bryce_autohide_hide(Bryce *b) +{ + if (b->autohide_blocked) return; + if (b->autohide_timer) + ecore_timer_reset(b->autohide_timer); + else + b->autohide_timer = ecore_timer_add(1.0, (Ecore_Task_Cb)_bryce_autohide_timeout, b); +} + +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; + + _bryce_autohide_hide(b); + b->mouse_in = 0; +} + +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; + + b->mouse_in = 1; + _bryce_autohide_show(b); +} + +static void +_bryce_autohide_setup(Bryce *b) +{ + int x, y, w, h; + + if (!b->autohide) return; + b->autohide_event = evas_object_rectangle_add(evas_object_evas_get(b->bryce)); + evas_object_geometry_get(b->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, b->layer + 1); + 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(b->bryce, EVAS_CALLBACK_MOVE, _bryce_autohide_moveresize, b); + evas_object_event_callback_add(b->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)) + _bryce_autohide_hide(b); +} + +static void +_bryce_style(Evas_Object *site, Eina_Stringshare *name, Evas_Object *g) +{ + Evas_Object *ly, *prev; + char buf[1024]; + + BRYCE_GET(site); + + ly = elm_layout_add(b->site); + snprintf(buf, sizeof(buf), "e/bryce/%s/%s", b->style ?: "default", name ?: "plain"); + e_theme_edje_object_set(ly, NULL, buf); + prev = e_gadget_util_layout_style_init(g, ly); + elm_object_part_content_set(ly, "e.swallow.content", g); + evas_object_del(prev); +} + +static void +_bryce_site_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + int w, h; + + evas_object_size_hint_min_get(obj, &w, &h); + if ((w < 0) || (h < 0)) return; + if (b->autosize && (!b->calc_job)) + b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b); +} + +static E_Comp_Object_Type +_bryce_shadow_type(const Bryce *b) +{ + if ((b->layer == E_LAYER_DESKTOP) || b->noshadow) + return E_COMP_OBJECT_TYPE_NONE; + return E_COMP_OBJECT_TYPE_POPUP; +} + +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); + b->layer = layer; + if ((!b->noshadow) && (layer != b->layer)) + e_comp_object_util_type_set(b->bryce, _bryce_shadow_type(b)); +} + +static Eina_Bool +_bryce_moveresize_save(void *data) +{ + Bryce *b = data; + int w, h; + int size; + + b->save_timer = NULL; + evas_object_geometry_get(b->bryce, NULL, NULL, &w, &h); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + size = h; + else + size = w; + size = lround(size / e_scale); + if (b->size == size) return EINA_FALSE; + e_config_save_queue(); + b->size = size; + return EINA_FALSE; +} + +static void +_bryce_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + int x, y, w, h; + E_Zone *zone; + int size; + + if (b->autohide) + { + E_FREE_LIST(b->zone_obstacles, e_object_del); + return; + } + evas_object_geometry_get(obj, &x, &y, &w, &h); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + size = h; + else + size = w; + + if (b->size != size) + { + if (b->save_timer) + ecore_timer_reset(b->save_timer); + else + b->save_timer = ecore_timer_add(0.5, _bryce_moveresize_save, b); + } + + zone = e_comp_object_util_zone_get(obj); + if (zone) + { + Eina_Bool vertical = b->orient == E_GADGET_SITE_ORIENT_VERTICAL; + if (b->zone_obstacles) + { + Eina_List *l; + E_Zone_Obstacle *obs; + + EINA_LIST_FOREACH(b->zone_obstacles, l, obs) + e_zone_obstacle_modify(obs, &(Eina_Rectangle){b->x, b->y, w, h}, vertical); + } + else + { + void *obs; + + obs = e_zone_obstacle_add(e_comp_object_util_zone_get(obj), NULL, + &(Eina_Rectangle){b->x, b->y, w, h}, vertical); + e_object_data_set(obs, b); + E_OBJECT_DEL_SET(obs, _bryce_obstacle_del); + b->zone_obstacles = eina_list_append(b->zone_obstacles, obs); + } + } + else + { + /* determine "closest" zone: + * calculate size of rect between bryce and zone + * smallest rect = closest zone + */ + Eina_List *l; + E_Zone *lz; + size = 0; + + E_FREE_LIST(b->zone_obstacles, e_object_del); + EINA_LIST_FOREACH(e_comp->zones, l, lz) + { + int cw, ch; + + if (x < lz->x) + cw = lz->x + lz->w - x; + else + cw = x + w - lz->x; + if (y < lz->y) + ch = lz->y + lz->h - y; + else + ch = y + h - lz->y; + if (size >= cw * ch) continue; + size = cw * ch; + zone = lz; + } + } + if (b->zone != zone->num) + e_config_save_queue(); + b->zone = zone->num; +} + +static Eina_Bool +_bryce_mouse_down_post(void *data, Evas *e EINA_UNUSED) +{ + Bryce *b = data; + Evas_Event_Mouse_Down *ev; + + ev = b->event_info; + b->event_info = NULL; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + return !!e_bindings_mouse_down_evas_event_handle(E_BINDING_CONTEXT_ANY, b->e_obj_inherit, ev); +} + +static void +_bryce_mouse_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Bryce *b = data; + + b->event_info = event_info; + evas_post_event_callback_push(e, _bryce_mouse_down_post, b); +} + +static Eina_Bool +_bryce_mouse_up_post(void *data, Evas *e EINA_UNUSED) +{ + Bryce *b = data; + Evas_Event_Mouse_Up *ev; + + ev = b->event_info; + b->event_info = NULL; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + return !!e_bindings_mouse_up_evas_event_handle(E_BINDING_CONTEXT_ANY, b->e_obj_inherit, ev); +} + +static void +_bryce_mouse_up(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Bryce *b = data; + + b->event_info = event_info; + evas_post_event_callback_push(e, _bryce_mouse_up_post, b); +} + +static Eina_Bool +_bryce_mouse_wheel_post(void *data, Evas *e EINA_UNUSED) +{ + Bryce *b = data; + Evas_Event_Mouse_Wheel *ev; + + ev = b->event_info; + b->event_info = NULL; + if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE; + return !!e_bindings_wheel_evas_event_handle(E_BINDING_CONTEXT_ANY, b->e_obj_inherit, ev); +} + +static void +_bryce_mouse_wheel(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Bryce *b = data; + + b->event_info = event_info; + evas_post_event_callback_push(e, _bryce_mouse_wheel_post, b); +} + +static void +_bryce_popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + + b->autohide_blocked--; + b->popups = eina_list_remove(b->popups, obj); + if (!b->autohide) return; + if (!b->mouse_in) + _bryce_autohide_hide(b); +} + +static void +_bryce_zone_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + e_object_del(E_OBJECT(b->e_obj_inherit)); +} + +static void +_bryce_zone_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + if (!b->calc_job) + b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b); +} + +static void +_bryce_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce *b = data; + Evas_Object *p; + E_Zone *zone; + void *obs; + + EINA_LIST_FREE(b->zone_obstacles, obs) + { + E_OBJECT_DEL_SET(obs, NULL); + e_object_del(obs); + } + evas_object_del(b->autohide_event); + E_FREE_FUNC(b->calc_job, ecore_job_del); + E_FREE_FUNC(b->autohide_timer, ecore_timer_del); + ecore_timer_del(b->save_timer); + EINA_LIST_FREE(b->popups, p) + evas_object_event_callback_del(p, EVAS_CALLBACK_HIDE, _bryce_popup_hide); + zone = e_comp_zone_number_get(b->zone); + if (zone) + { + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_DEL, _bryce_zone_del); + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize); + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize); + } + E_FREE(b->e_obj_inherit); +} + +static void +_bryce_object_free(E_Object *eobj) +{ + Bryce *b = e_object_data_get(eobj); + evas_object_hide(b->bryce); + evas_object_del(b->bryce); +} + +static void +_bryce_style_menu(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Bryce *b = data; + char buf[1024]; + + snprintf(buf, sizeof(buf), "e/bryce/%s", b->style ?: "default"); + e_object_data_set(event_info, e_theme_collection_items_find(NULL, buf)); +} + +static void +_bryce_gadgets_menu_close(void *data, Evas_Object *obj) +{ + Bryce *b = data; + + b->autohide_blocked--; + evas_object_layer_set(b->bryce, b->layer); + evas_object_hide(obj); + evas_object_del(obj); + if (b->autohide && (!b->mouse_in)) + _bryce_autohide_hide(b); +} + +static void +_bryce_gadgets_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + Bryce *b = data; + Evas_Object *comp_object; + + b->autohide_blocked++; + comp_object = e_gadget_site_edit(b->site); + evas_object_layer_set(b->bryce, E_LAYER_POPUP); + e_comp_object_util_autoclose(comp_object, _bryce_gadgets_menu_close, e_comp_object_util_autoclose_on_escape, b); +} + +static void +_bryce_autosize_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + Bryce *b = data; + + e_bryce_autosize_set(b->bryce, !b->autosize); +} + +static void +_bryce_autohide_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + Bryce *b = data; + + e_bryce_autohide_set(b->bryce, !b->autohide); +} + +static void +_bryce_remove_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + Bryce *b = data; + bryces->bryces = eina_list_remove(bryces->bryces, data); + e_gadget_site_del(b->site); + eina_stringshare_del(b->name); + eina_stringshare_del(b->style); + evas_object_hide(b->bryce); + evas_object_del(b->bryce); + e_config_save_queue(); +} + +static void +_bryce_wizard_menu(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) +{ + Bryce *b = data; + + e_bryce_edit(b->bryce); +} + +static void +_bryce_menu_populate(Bryce *b, E_Menu *m) +{ + E_Menu_Item *mi; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Wizard")); + e_menu_item_callback_set(mi, _bryce_wizard_menu, b); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Autosize")); + e_menu_item_check_set(mi, 1); + e_menu_item_toggle_set(mi, b->autosize); + e_menu_item_callback_set(mi, _bryce_autosize_menu, b); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Autohide")); + e_menu_item_check_set(mi, 1); + e_menu_item_toggle_set(mi, b->autohide); + e_menu_item_callback_set(mi, _bryce_autohide_menu, b); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Gadgets")); + e_menu_item_callback_set(mi, _bryce_gadgets_menu, b); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Remove")); + e_util_menu_item_theme_icon_set(mi, "list-remove"); + e_menu_item_callback_set(mi, _bryce_remove_menu, b); +} + +static void +_bryce_owner_menu(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Bryce *b = data; + E_Menu_Item *mi = event_info; + E_Menu *subm; + + e_menu_item_label_set(mi, _("Bryce")); + + subm = e_menu_new(); + e_menu_item_submenu_set(mi, subm); + e_object_unref(E_OBJECT(subm)); + + _bryce_menu_populate(b, subm); +} + +static void +_bryce_popup(Bryce *b, Evas_Object *popup) +{ + evas_object_event_callback_add(popup, EVAS_CALLBACK_HIDE, _bryce_popup_hide, b); + b->autohide_blocked++; + b->popups = eina_list_append(b->popups, popup); + if (b->autohide) + _bryce_autohide_show(b); +} + +static void +_bryce_gadget_popup(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + _bryce_popup(data, event_info); +} + +static void +_bryce_orient(Bryce *b) +{ + char buf[1024]; + + evas_object_del(b->site); + + snprintf(buf, sizeof(buf), "__bryce%s", b->name); + b->site = e_gadget_site_add(b->orient, buf); + E_EXPAND(b->site); + E_FILL(b->site); + evas_object_data_set(b->site, "__bryce", b); + elm_object_content_set(b->scroller, b->site); + e_gadget_site_owner_setup(b->site, b->anchor, _bryce_style); + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + elm_layout_signal_emit(b->layout, "e,state,orient,horizontal", "e"); + else + elm_layout_signal_emit(b->layout, "e,state,orient,vertical", "e"); +} + +static void +_bryce_style_apply(Bryce *b) +{ + char buf[1024]; + Eina_Bool noshadow; + + snprintf(buf, sizeof(buf), "e/bryce/%s/base", b->style ?: "default"); + e_theme_edje_object_set(b->layout, NULL, buf); + noshadow = b->noshadow; + b->noshadow = !!elm_layout_data_get(b->layout, "noshadow"); + if (b->bryce && (noshadow != b->noshadow)) + e_comp_object_util_type_set(b->bryce, _bryce_shadow_type(b)); +} + +static void +_bryce_create(Bryce *b, Evas_Object *parent) +{ + Evas_Object *ly, *bryce, *scr; + Evas_Object *zone_clip; + + b->e_obj_inherit = E_OBJECT_ALLOC(E_Object, E_BRYCE_TYPE, _bryce_object_free); + e_object_data_set(b->e_obj_inherit, b); + b->layout = ly = elm_layout_add(parent); + _bryce_style_apply(b); + + b->scroller = scr = elm_scroller_add(ly); + elm_object_style_set(scr, "bryce"); + _bryce_orient(b); + elm_object_part_content_set(ly, "e.swallow.content", scr); + evas_object_show(ly); + b->bryce = bryce = e_comp_object_util_add(ly, _bryce_shadow_type(b)); + evas_object_data_set(bryce, "comp_skip", (void*)1); + evas_object_layer_set(bryce, b->layer); + evas_object_lower(bryce); + + b->parent = parent; + { + 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_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(bryce, EVAS_CALLBACK_MOVE, _bryce_moveresize, b); + evas_object_event_callback_add(bryce, EVAS_CALLBACK_RESIZE, _bryce_moveresize, b); + evas_object_event_callback_add(bryce, EVAS_CALLBACK_MOUSE_DOWN, _bryce_mouse_down, b); + evas_object_event_callback_add(bryce, EVAS_CALLBACK_MOUSE_UP, _bryce_mouse_up, b); + evas_object_event_callback_add(bryce, EVAS_CALLBACK_MOUSE_WHEEL, _bryce_mouse_wheel, b); + evas_object_event_callback_add(b->site, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _bryce_site_hints, b); + + evas_object_smart_callback_add(b->site, "gadget_site_style_menu", _bryce_style_menu, b); + evas_object_smart_callback_add(b->site, "gadget_site_owner_menu", _bryce_owner_menu, b); + evas_object_smart_callback_add(b->site, "gadget_site_popup", _bryce_gadget_popup, b); + + zone_clip = e_comp_zone_number_get(b->zone)->bg_clip_object; + evas_object_clip_set(bryce, zone_clip); + evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_DEL, _bryce_zone_del, b); + evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize, b); + evas_object_event_callback_add(zone_clip, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize, b); + _bryce_autohide_setup(b); + _bryce_autosize(b); +} + +static Eina_Bool +_bryce_act_resize(E_Object *obj, const char *params, E_Binding_Event_Wheel *ev) +{ + Bryce *b; + int size, step = 4; + char buf[64]; + + if (obj->type != E_BRYCE_TYPE) return EINA_FALSE; + if (params && params[0]) + { + step = strtol(params, NULL, 10); + step = MAX(step, 4); + } + b = e_object_data_get(obj); + size = b->size; + if (ev->z < 0)//up + b->size += step; + else + b->size -= step; + b->size = E_CLAMP(b->size, 20, 256); + if (dblequal(e_scale, 1.0)) + snprintf(buf, sizeof(buf), "%dpx", b->size); + else + snprintf(buf, sizeof(buf), "%dpx (%ldpx scaled)", b->size, lround(b->size * e_scale)); + elm_object_part_text_set(b->layout, "e.text", buf); + elm_object_signal_emit(b->layout, "e,action,resize", "e"); + e_config_save_queue(); + if (size == b->size) return EINA_TRUE; + b->size_changed = 1; + if (!b->calc_job) + b->calc_job = ecore_job_add((Ecore_Cb)_bryce_autosize, b); + return EINA_TRUE; +} + +static void +_bryce_act_menu_job(void *data) +{ + Bryce *b = data; + E_Menu *m; + int x, y; + + m = e_menu_new(); + _bryce_menu_populate(b, m); + evas_pointer_canvas_xy_get(e_comp->evas, &x, &y); + e_menu_activate_mouse(m, e_zone_current_get(), x, y, 1, 1, E_MENU_POP_DIRECTION_AUTO, b->last_timestamp); + _bryce_popup(b, m->comp_object); +} + +static Eina_Bool +_bryce_act_menu(E_Object *obj, const char *params EINA_UNUSED, E_Binding_Event_Mouse_Button *ev EINA_UNUSED) +{ + Bryce *b; + if (obj->type != E_BRYCE_TYPE) return EINA_FALSE; + b = e_object_data_get(obj); + b->last_timestamp = ev->timestamp; + /* FIXME: T3144 */ + ecore_job_add(_bryce_act_menu_job, b); + return EINA_TRUE; +} + +static Eina_Bool +_bryce_zone_add(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Zone_Add *ev) +{ + Eina_List *l; + Bryce *b; + + EINA_LIST_FOREACH(bryces->bryces, l, b) + { + if (b->bryce) continue; + if (b->zone != ev->zone->num) continue; + _bryce_create(b, e_comp->elm); + evas_object_show(b->bryce); + } + return ECORE_CALLBACK_RENEW; +} + +E_API Evas_Object * +e_bryce_add(Evas_Object *parent, const char *name, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an) +{ + Bryce *b; + + b = E_NEW(Bryce, 1); + b->size = 48; + b->name = eina_stringshare_add(name); + b->anchor = an; + b->orient = orient; + b->layer = DEFAULT_LAYER; + _bryce_create(b, parent); + bryces->bryces = eina_list_append(bryces->bryces, b); + e_config_save_queue(); + return b->bryce; +} + +E_API void +e_bryce_orient(Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an) +{ + BRYCE_GET(bryce); + b->orient = orient; + b->anchor = an; + _bryce_orient(b); +} + +E_API Evas_Object * +e_bryce_site_get(Evas_Object *bryce) +{ + BRYCE_GET(bryce); + + return b->site; +} + +E_API void +e_bryce_autosize_set(Evas_Object *bryce, Eina_Bool set) +{ + BRYCE_GET(bryce); + set = !!set; + + if (b->autosize == set) return; + b->autosize = set; + + e_config_save_queue(); + _bryce_autosize(b); +} + +E_API void +e_bryce_autohide_set(Evas_Object *bryce, Eina_Bool set) +{ + BRYCE_GET(bryce); + set = !!set; + + if (b->autohide == set) return; + b->autohide = set; + + if (set) + _bryce_autohide_setup(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; + e_efx_move(b->bryce, E_EFX_EFFECT_SPEED_LINEAR, E_EFX_POINT(b->x, b->y), 0.5, _bryce_autohide_end, b); + b->animating = 1; + b->hidden = 0; + } + e_config_save_queue(); +} + +E_API Eina_List * +e_bryce_list(Evas_Object *parent) +{ + Eina_List *l, *ret = NULL; + Bryce *b; + + if (!parent) parent = e_comp->elm; + EINA_LIST_FOREACH(bryces->bryces, l, b) + { + if (!b->bryce) continue; + if (parent == b->parent) + ret = eina_list_append(ret, b->bryce); + } + return ret; +} + +E_API Eina_Bool +e_bryce_exists(Evas_Object *parent, Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an) +{ + Eina_List *l; + Bryce *b; + int zone = -1; + + if (!parent) parent = e_comp->elm; + if (parent == e_comp->elm) + { + E_Shelf *es; + E_Zone *z; + + z = e_zone_current_get(); + zone = z->num; + /* FIXME: remove shelf block once shelves are dead */ + l = e_shelf_list_all(); + EINA_LIST_FREE(l, es) + { + if (es->zone != z) continue; + switch (es->cfg->orient) + { +#define ORIENT_CHECK(ORIENT, ANCHOR1, ANCHOR2) \ + if ((orient == E_GADGET_SITE_ORIENT_##ORIENT) && \ + ((an == (E_GADGET_SITE_ANCHOR_##ANCHOR1)) || \ + ((an & E_GADGET_SITE_ANCHOR_##ANCHOR2) && (!es->cfg->fit_along)))) \ + return EINA_TRUE + default: break; + case E_GADCON_ORIENT_LEFT: + ORIENT_CHECK(VERTICAL, LEFT, LEFT); + case E_GADCON_ORIENT_RIGHT: + ORIENT_CHECK(VERTICAL, RIGHT, RIGHT); + case E_GADCON_ORIENT_TOP: + ORIENT_CHECK(HORIZONTAL, TOP, TOP); + case E_GADCON_ORIENT_BOTTOM: + ORIENT_CHECK(HORIZONTAL, BOTTOM, BOTTOM); + case E_GADCON_ORIENT_CORNER_TL: + ORIENT_CHECK(HORIZONTAL, TOP | E_GADGET_SITE_ANCHOR_LEFT, TOP); + case E_GADCON_ORIENT_CORNER_TR: + ORIENT_CHECK(HORIZONTAL, TOP | E_GADGET_SITE_ANCHOR_RIGHT, TOP); + case E_GADCON_ORIENT_CORNER_BL: + ORIENT_CHECK(HORIZONTAL, BOTTOM | E_GADGET_SITE_ANCHOR_LEFT, BOTTOM); + case E_GADCON_ORIENT_CORNER_BR: + ORIENT_CHECK(HORIZONTAL, BOTTOM | E_GADGET_SITE_ANCHOR_RIGHT, BOTTOM); + case E_GADCON_ORIENT_CORNER_LT: + ORIENT_CHECK(VERTICAL, LEFT | E_GADGET_SITE_ANCHOR_TOP, LEFT); + case E_GADCON_ORIENT_CORNER_RT: + ORIENT_CHECK(VERTICAL, RIGHT | E_GADGET_SITE_ANCHOR_TOP, RIGHT); + case E_GADCON_ORIENT_CORNER_LB: + ORIENT_CHECK(VERTICAL, LEFT | E_GADGET_SITE_ANCHOR_BOTTOM, LEFT); + case E_GADCON_ORIENT_CORNER_RB: + ORIENT_CHECK(VERTICAL, RIGHT | E_GADGET_SITE_ANCHOR_BOTTOM, RIGHT); +#undef ORIENT_CHECK + } + } + /* end FIXME */ + } + EINA_LIST_FOREACH(bryces->bryces, l, b) + { + if (!b->bryce) continue; + if (b->bryce == bryce) return EINA_FALSE; + if (parent != b->parent) continue; + if (b->orient != orient) continue; + if ((zone >= 0) && ((int)b->zone != zone)) continue; + if ((b->anchor & an) == an) return EINA_TRUE; + if (b->autosize) continue; + if (b->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + { + if ((b->anchor & E_GADGET_SITE_ANCHOR_BOTTOM) && (an & E_GADGET_SITE_ANCHOR_BOTTOM)) + return EINA_TRUE; + if ((b->anchor & E_GADGET_SITE_ANCHOR_TOP) && (an & E_GADGET_SITE_ANCHOR_TOP)) + return EINA_TRUE; + } + else + { + if ((b->anchor & E_GADGET_SITE_ANCHOR_LEFT) && (an & E_GADGET_SITE_ANCHOR_LEFT)) + return EINA_TRUE; + if ((b->anchor & E_GADGET_SITE_ANCHOR_RIGHT) && (an & E_GADGET_SITE_ANCHOR_RIGHT)) + return EINA_TRUE; + } + } + return EINA_FALSE; +} + +E_API void +e_bryce_style_set(Evas_Object *bryce, const char *style) +{ + BRYCE_GET(bryce); + + eina_stringshare_replace(&b->style, style); + _bryce_style_apply(b); + e_config_save_queue(); + evas_object_smart_callback_call(b->site, "gadget_site_style", NULL); +} + +/* FIXME */ +EINTERN void +e_bryce_save(void) +{ + e_config_domain_save("e_bryces", edd_bryces, bryces); +} + +EINTERN void +e_bryce_init(void) +{ + resize_act = e_action_add("bryce_resize"); + e_action_predef_name_set(_("Bryces"), _("Resize Bryce"), "bryce_resize", NULL, "syntax: step, example: 4", 1); + resize_act->func.go_wheel = _bryce_act_resize; + + menu_act = e_action_add("bryce_menu"); + e_action_predef_name_set(_("Bryces"), _("Bryce menu"), "bryce_menu", NULL, NULL, 0); + menu_act->func.go_mouse = _bryce_act_menu; + + edd_bryce = E_CONFIG_DD_NEW("Bryce", Bryce); + E_CONFIG_VAL(edd_bryce, Bryce, name, STR); + E_CONFIG_VAL(edd_bryce, Bryce, style, STR); + E_CONFIG_VAL(edd_bryce, Bryce, zone, UINT); + E_CONFIG_VAL(edd_bryce, Bryce, size, INT); + E_CONFIG_VAL(edd_bryce, Bryce, layer, UINT); + E_CONFIG_VAL(edd_bryce, Bryce, autosize, UCHAR); + E_CONFIG_VAL(edd_bryce, Bryce, autohide, UCHAR); + E_CONFIG_VAL(edd_bryce, Bryce, orient, UINT); + E_CONFIG_VAL(edd_bryce, Bryce, anchor, UINT); + + edd_bryces = E_CONFIG_DD_NEW("Bryces", Bryces); + E_CONFIG_LIST(edd_bryces, Bryces, bryces, edd_bryce); + bryces = e_config_domain_load("e_bryces", edd_bryces); + + if (bryces) + { + Eina_List *l; + Bryce *b; + + EINA_LIST_FOREACH(bryces->bryces, l, b) + { + if (!e_comp_zone_number_get(b->zone)) continue; + _bryce_create(b, e_comp->elm); + evas_object_show(b->bryce); + } + } + else + bryces = E_NEW(Bryces, 1); + + E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _bryce_zone_add, NULL); +} + +EINTERN void +e_bryce_shutdown(void) +{ + Bryce *b; + + E_CONFIG_DD_FREE(edd_bryce); + E_CONFIG_DD_FREE(edd_bryces); + EINA_LIST_FREE(bryces->bryces, b) + { + E_Zone *zone; + void *obs; + + EINA_LIST_FREE(b->zone_obstacles, obs) + { + E_OBJECT_DEL_SET(obs, NULL); + e_object_del(obs); + } + evas_object_event_callback_del(b->bryce, EVAS_CALLBACK_DEL, _bryce_del); + EINA_LIST_FREE(b->popups, obs) + evas_object_event_callback_del(obs, EVAS_CALLBACK_HIDE, _bryce_popup_hide); + evas_object_hide(b->bryce); + evas_object_del(b->bryce); + evas_object_del(b->autohide_event); + eina_stringshare_del(b->name); + eina_stringshare_del(b->style); + ecore_job_del(b->calc_job); + ecore_timer_del(b->save_timer); + ecore_timer_del(b->autohide_timer); + zone = e_comp_zone_number_get(b->zone); + if (zone) + { + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_DEL, _bryce_zone_del); + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_MOVE, _bryce_zone_moveresize); + evas_object_event_callback_del(zone->bg_clip_object, EVAS_CALLBACK_RESIZE, _bryce_zone_moveresize); + } + free(b->e_obj_inherit); + free(b); + } + E_FREE_LIST(handlers, ecore_event_handler_del); + E_FREE(bryces); +} diff --git a/src/bin/e_bryce.h b/src/bin/e_bryce.h new file mode 100644 index 000000000..3fa69b547 --- /dev/null +++ b/src/bin/e_bryce.h @@ -0,0 +1,22 @@ +#ifndef E_TYPEDEFS +#ifndef E_BRYCE_H +# define E_BRYCE_H + +EINTERN void e_bryce_init(void); +EINTERN void e_bryce_shutdown(void); + +E_API Evas_Object *e_bryce_add(Evas_Object *parent, const char *name, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an); +E_API void e_bryce_orient(Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an); +E_API Evas_Object *e_bryce_site_get(Evas_Object *bryce); +E_API void e_bryce_autosize_set(Evas_Object *bryce, Eina_Bool set); +E_API void e_bryce_autohide_set(Evas_Object *bryce, Eina_Bool set); +E_API Eina_Bool e_bryce_exists(Evas_Object *parent, Evas_Object *bryce, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an); +E_API Eina_List *e_bryce_list(Evas_Object *parent); +E_API void e_bryce_style_set(Evas_Object *bryce, const char *style); +E_API void e_bryce_autosize_set(Evas_Object *bryce, Eina_Bool set); +E_API void e_bryce_autohide_set(Evas_Object *bryce, Eina_Bool set); + +E_API Evas_Object *e_bryce_editor_add(Evas_Object *parent, Evas_Object *bryce); +E_API Evas_Object *e_bryce_edit(Evas_Object *bryce); +#endif +#endif diff --git a/src/bin/e_bryce_editor.c b/src/bin/e_bryce_editor.c new file mode 100644 index 000000000..4c1314988 --- /dev/null +++ b/src/bin/e_bryce_editor.c @@ -0,0 +1,414 @@ +#include "e.h" + +#define DEFAULT_AUTOSIZE EINA_TRUE +#define DEFAULT_AUTOHIDE EINA_FALSE +#define DEFAULT_LAYER E_LAYER_CLIENT_EDGE + +typedef struct Bryce_Info +{ + E_Gadget_Site_Anchor anchor; + E_Gadget_Site_Orient orient; + Eina_Stringshare *style; + Eina_Bool stack_under; + Eina_Bool autohide; + Eina_Bool autosize; +} Bryce_Info; + + +static void _editor_add_bottom(void *data, Evas_Object *obj, const char *sig, const char *src); +static void _editor_add_top(void *data, Evas_Object *obj, const char *sig, const char *src); +static void _editor_add_left(void *data, Evas_Object *obj, const char *sig, const char *src); +static void _editor_add_right(void *data, Evas_Object *obj, const char *sig, const char *src); + +static void +setup_exists(Evas_Object *bryce, Evas_Object *editor, Evas_Object *parent, E_Gadget_Site_Anchor an) +{ + if (e_bryce_exists(parent, bryce, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_BOTTOM | an)) + elm_object_signal_emit(editor, "e,bryce,exists,bottom", "e"); + if (e_bryce_exists(parent, bryce, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_TOP | an)) + elm_object_signal_emit(editor, "e,bryce,exists,top", "e"); + if (e_bryce_exists(parent, bryce, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_LEFT | an)) + elm_object_signal_emit(editor, "e,bryce,exists,left", "e"); + if (e_bryce_exists(parent, bryce, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_RIGHT | an)) + elm_object_signal_emit(editor, "e,bryce,exists,right", "e"); +} + +static void +_editor_bryce_add(Evas_Object *obj) +{ + Evas_Object *b, *site; + char buf[1024]; + const char *loc = "", *loc2 = ""; + Bryce_Info *bi; + E_Gadget_Site_Gravity gravity = E_GADGET_SITE_GRAVITY_CENTER; + + bi = evas_object_data_get(obj, "__bryce_info"); + b = evas_object_data_get(obj, "__bryce_editor_bryce"); + if (bi->anchor & E_GADGET_SITE_ANCHOR_TOP) + loc = "top"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_BOTTOM) + loc = "bottom"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_LEFT) + loc = "left"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_RIGHT) + loc = "right"; + if (bi->anchor & E_GADGET_SITE_ANCHOR_RIGHT) + loc2 = "right"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_LEFT) + loc2 = "left"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_TOP) + loc2 = "top"; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_BOTTOM) + loc2 = "bottom"; + + snprintf(buf, sizeof(buf), "bryce_%s_%s", loc, loc2); + if (bi->orient == E_GADGET_SITE_ORIENT_HORIZONTAL) + { + if (bi->anchor & E_GADGET_SITE_ANCHOR_LEFT) + gravity = E_GADGET_SITE_GRAVITY_LEFT; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_RIGHT) + gravity = E_GADGET_SITE_GRAVITY_RIGHT; + } + else + { + if (bi->anchor & E_GADGET_SITE_ANCHOR_TOP) + gravity = E_GADGET_SITE_GRAVITY_TOP; + else if (bi->anchor & E_GADGET_SITE_ANCHOR_BOTTOM) + gravity = E_GADGET_SITE_GRAVITY_BOTTOM; + } + if (b) + site = e_bryce_site_get(b); + else + { + b = e_bryce_add(e_comp->elm, buf, bi->orient, bi->anchor); + site = e_bryce_site_get(b); + + e_gadget_site_gadget_add(site, "Start", 0); + e_gadget_site_gadget_add(site, "Digital Clock", 0); + e_gadget_site_gadget_add(site, "Wireless", 0); + } + e_gadget_site_gravity_set(site, gravity); + e_bryce_style_set(b, bi->style); + e_bryce_autohide_set(b, bi->autohide); + e_bryce_autosize_set(b, bi->autosize); + evas_object_layer_set(b, bi->stack_under ? E_LAYER_DESKTOP : E_LAYER_CLIENT_EDGE); + evas_object_del(obj); +} + +static void +_editor_finish(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + _editor_bryce_add(data); +} + +static void +_editor_autosize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce_Info *bi = data; + + bi->autosize = !bi->autosize; +} + +static void +_editor_autohide(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce_Info *bi = data; + + bi->autohide = !bi->autohide; +} + +static void +_editor_stacking(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce_Info *bi = data; + + bi->stack_under = !bi->stack_under; +} + +static void +_editor_style_click(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + const char *g; + char style[1024] = {0}; + Bryce_Info *bi; + Evas_Object *ly, *box, *ck, *button; + + ly = elm_object_part_content_get(obj, "e.swallow.content"); + elm_layout_file_get(ly, NULL, &g); + g += (sizeof("e/bryce/") - 1); + memcpy(style, g, MIN(sizeof(style) - 1, strchr(g, '/') - g)); + + bi = evas_object_data_get(data, "__bryce_info"); + bi->style = eina_stringshare_add(style); + e_theme_edje_object_set(data, NULL, "e/bryce/editor/finish"); + elm_object_part_text_set(data, "e.text", _("Finishing touches... (4/4)")); + box = elm_box_add(data); + elm_box_padding_set(box, 0, 20 * e_scale); + + ck = elm_check_add(box); + E_ALIGN(ck, 0, 0.5); + evas_object_show(ck); + elm_object_text_set(ck, _("Automatically size based on contents")); + evas_object_smart_callback_add(ck, "changed", _editor_autosize, bi); + elm_box_pack_end(box, ck); + + ck = elm_check_add(box); + E_ALIGN(ck, 0, 0.5); + evas_object_show(ck); + elm_object_text_set(ck, _("Automatically hide")); + evas_object_smart_callback_add(ck, "changed", _editor_autohide, bi); + elm_box_pack_end(box, ck); + + ck = elm_check_add(box); + E_ALIGN(ck, 0, 0.5); + evas_object_show(ck); + elm_object_text_set(ck, _("Do not stack above windows")); + evas_object_smart_callback_add(ck, "changed", _editor_stacking, bi); + elm_box_pack_end(box, ck); + + //ck = elm_check_add(box); + //elm_object_text_set(ck, _("Allow windows to overlap")); + //evas_object_smart_callback_add(ck, "changed", _editor_overlap, data); + //elm_box_pack_end(box, ck); + + button = elm_button_add(data); + evas_object_show(button); + elm_object_text_set(button, _("Finish!")); + evas_object_smart_callback_add(button, "clicked", _editor_finish, data); + elm_box_pack_end(box, button); + + elm_object_part_content_set(data, "e.swallow.content", box); +} + +static void +_editor_style(Evas_Object *obj) +{ + Eina_List *l; + Eina_Stringshare *style; + Evas_Object *box; + int w; + + evas_object_geometry_get(obj, NULL, NULL, &w, NULL); + box = elm_box_add(obj); + e_theme_edje_object_set(obj, NULL, "e/bryce/editor/style"); + elm_object_part_text_set(obj, "e.text", _("Choose style (3/4)")); + elm_box_homogeneous_set(box, 1); + elm_box_padding_set(box, 0, 20 * e_scale); + l = elm_theme_group_base_list(NULL, "e/bryce/"); + EINA_LIST_FREE(l, style) + { + Evas_Object *ly, *bryce; + char buf[1024] = {0}; + size_t len; + + if (!eina_str_has_suffix(style, "/base")) + { + eina_stringshare_del(style); + continue; + } + ly = elm_layout_add(box); + e_theme_edje_object_set(ly, NULL, "e/bryce/editor/style/item"); + bryce = edje_object_add(evas_object_evas_get(box)); + elm_object_part_content_set(ly, "e.swallow.content", bryce); + len = strlen(style); + strncpy(buf, style + sizeof("e/bryce/") - 1, + MIN(sizeof(buf) - 1, len - (sizeof("e/bryce/") - 1) - (sizeof("/base") - 1))); + buf[0] = toupper(buf[0]); + elm_object_part_text_set(ly, "e.text", buf); + e_comp_object_util_del_list_append(ly, bryce); + e_theme_edje_object_set(bryce, NULL, style); + evas_object_size_hint_min_set(bryce, w * 2 / 3, 48 * e_scale); + evas_object_show(ly); + evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, _editor_style_click, obj); + elm_box_pack_end(box, ly); + } + elm_object_part_content_set(obj, "e.swallow.content", box); +} + +static void +_editor_info_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Bryce_Info *bi = data; + + eina_stringshare_del(bi->style); + free(bi); +} + +static void +_editor_add(Evas_Object *obj, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor an) +{ + char buf[1024]; + Bryce_Info *bi; + + bi = evas_object_data_get(obj, "__bryce_info"); + if (bi) + { + bi->anchor |= an; + _editor_style(obj); + } + else + { + bi = E_NEW(Bryce_Info, 1); + bi->anchor = an; + bi->orient = orient; + evas_object_data_set(obj, "__bryce_info", bi); + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _editor_info_del, bi); + snprintf(buf, sizeof(buf), "e/bryce/editor/side/%s", + orient == E_GADGET_SITE_ORIENT_HORIZONTAL ? "horizontal" : "vertical"); + e_theme_edje_object_set(obj, NULL, buf); + elm_object_part_text_set(obj, "e.text", _("Choose position (2/4)")); + if (an & E_GADGET_SITE_ANCHOR_BOTTOM) + elm_object_signal_emit(obj, "e,state,bottom", "e"); + else if (an & E_GADGET_SITE_ANCHOR_RIGHT) + elm_object_signal_emit(obj, "e,state,right", "e"); + setup_exists(evas_object_data_get(obj, "__bryce_editor_bryce"), obj, + evas_object_data_get(obj, "__bryce_editor_site"), an); + } +} + +static void +_editor_add_bottom(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + _editor_add(obj, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_BOTTOM); +} + +static void +_editor_add_top(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + _editor_add(obj, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_TOP); +} + +static void +_editor_add_left(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + _editor_add(obj, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_LEFT); +} + +static void +_editor_add_center(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + _editor_add(obj, E_GADGET_SITE_ORIENT_NONE, E_GADGET_SITE_ANCHOR_NONE); +} + +static void +_editor_add_right(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + _editor_add(obj, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_RIGHT); +} + +static void +_editor_dismiss(void *data EINA_UNUSED, Evas_Object *obj, const char *sig EINA_UNUSED, const char *src EINA_UNUSED) +{ + evas_object_del(obj); +} + +E_API Evas_Object * +e_bryce_editor_add(Evas_Object *parent, Evas_Object *bryce) +{ + Evas_Object *editor; + + editor = elm_layout_add(parent); + evas_object_data_set(editor, "__bryce_editor_site", parent); + evas_object_data_set(editor, "__bryce_editor_bryce", bryce); + e_theme_edje_object_set(editor, NULL, "e/bryce/editor/side"); + elm_object_part_text_set(editor, "e.text", _("Choose screen edge (1/4)")); + + setup_exists(bryce, editor, parent, 0); + + elm_object_signal_callback_add(editor, "e,action,dismiss", "e", _editor_dismiss, editor); + elm_object_signal_callback_add(editor, "e,bryce,add,bottom", "e", _editor_add_bottom, editor); + elm_object_signal_callback_add(editor, "e,bryce,add,top", "e", _editor_add_top, editor); + elm_object_signal_callback_add(editor, "e,bryce,add,left", "e", _editor_add_left, editor); + elm_object_signal_callback_add(editor, "e,bryce,add,right", "e", _editor_add_right, editor); + elm_object_signal_callback_add(editor, "e,bryce,add,center", "e", _editor_add_center, editor); + return editor; +} + +static Ecore_Event_Handler *handler; + +static void +_bryce_edit_key_location(Evas_Object *obj, Ecore_Event_Key *ev) +{ + if (eina_streq(ev->key, "Up")) + _editor_add(obj, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_TOP); + else if (eina_streq(ev->key, "Down")) + _editor_add(obj, E_GADGET_SITE_ORIENT_HORIZONTAL, E_GADGET_SITE_ANCHOR_BOTTOM); + else if (eina_streq(ev->key, "Left")) + _editor_add(obj, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_LEFT); + else if (eina_streq(ev->key, "Right")) + _editor_add(obj, E_GADGET_SITE_ORIENT_VERTICAL, E_GADGET_SITE_ANCHOR_RIGHT); +} + +static Eina_Bool +_bryce_edit_key_handler(void *data, int t EINA_UNUSED, Ecore_Event_Key *ev) +{ + if (eina_streq(ev->key, "Escape")) + { + elm_layout_signal_emit(data, "e,action,dismiss", "e"); + return ECORE_CALLBACK_RENEW; + } + if (evas_object_data_get(data, "__bryce_info")) + { + const char *grp; + + edje_object_file_get(data, NULL, &grp); + if (!strncmp(grp, "e/bryce/editor/side/", sizeof("e/bryce/editor/side/") - 1)) + _bryce_edit_key_location(data, ev); + else if (!strncmp(grp, "e/bryce/editor/style", sizeof("e/bryce/editor/style") - 1)) + { + Evas_Object *bx, *o; + Eina_List *l; + int n; + + bx = elm_object_part_content_get(data, "e.swallow.content"); + l = elm_box_children_get(bx); + n = strtol(ev->key, NULL, 10); + if (n > 0) + { + o = eina_list_nth(l, n - 1); + if (o) + _editor_style_click(data, NULL, o, NULL); + } + eina_list_free(l); + } + else if (eina_streq(ev->key, "Return") || eina_streq(ev->key, "KP_Enter")) + _editor_bryce_add(data); + } + else + _bryce_edit_key_location(data, ev); + return ECORE_CALLBACK_RENEW; +} + +static void +_bryce_edit_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + e_bindings_disabled_set(0); + e_comp_ungrab_input(1, 1); + evas_object_hide(data); + evas_object_del(data); + E_FREE_FUNC(handler, ecore_event_handler_del); +} + +E_API Evas_Object * +e_bryce_edit(Evas_Object *bryce) +{ + Evas_Object *editor, *comp_object; + E_Zone *zone; + int x, y, w, h; + + zone = e_zone_current_get(); + x = zone->x, y = zone->y, w = zone->w, h = zone->h; + e_bindings_disabled_set(1); + editor = e_bryce_editor_add(e_comp->elm, bryce); + + evas_object_geometry_set(editor, x, y, w, h); + comp_object = e_comp_object_util_add(editor, E_COMP_OBJECT_TYPE_NONE); + evas_object_event_callback_add(editor, EVAS_CALLBACK_DEL, _bryce_edit_end, comp_object); + evas_object_layer_set(comp_object, E_LAYER_POPUP); + evas_object_show(comp_object); + + e_comp_object_util_autoclose(comp_object, NULL, e_comp_object_util_autoclose_on_escape, NULL); + e_comp_grab_input(1, 1); + handler = ecore_event_handler_add(ECORE_EVENT_KEY_UP, (Ecore_Event_Handler_Cb)_bryce_edit_key_handler, editor); + return comp_object; +} diff --git a/src/bin/e_config.c b/src/bin/e_config.c index d6d30754a..eb0c013ce 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -2148,6 +2148,7 @@ static void _e_config_save_cb(void *data EINA_UNUSED) { EINTERN void e_gadget_save(void); + EINTERN void e_bryce_save(void); e_config_profile_save(); e_module_save_all(); @@ -2155,6 +2156,7 @@ _e_config_save_cb(void *data EINA_UNUSED) e_config_domain_save("e", _e_config_edd, e_config); e_config_domain_save("e_bindings", _e_config_binding_edd, e_bindings); e_gadget_save(); + e_bryce_save(); _e_config_save_defer = NULL; } diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 38f54846a..63133df11 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -151,6 +151,7 @@ #include "e_hints.h" #include "e_comp_x_randr.h" #include "e_gadget.h" +#include "e_bryce.h" #ifdef HAVE_WAYLAND # include "e_comp_wl.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 4142bcce8..f70e506f9 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -1053,6 +1053,13 @@ main(int argc, char **argv) e_test(); TS("E_Test Done"); + if (e_config->show_splash) + e_init_status_set(_("Setup Bryces")); + TS("Bryce Init"); + e_bryce_init(); + TS("Bryce Init Done"); + _e_main_shutdown_push((void*)e_bryce_shutdown); + if (e_config->show_splash) e_init_status_set(_("Setup Shelves")); TS("E_Shelf Init");