From 26a16c6515b67525ddf5b7d72ca12eb67ca65882 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Sat, 26 Feb 2011 06:57:41 +0000 Subject: [PATCH] e-modules/comp-scale: added fullscreen pager changed internal action names, so bindings need to be setup again. SVN revision: 57330 --- e-module-scale.edc | 151 ++++- src/Makefile.am | 4 +- src/e_mod_config.c | 163 +++-- src/e_mod_main.c | 1526 +---------------------------------------- src/e_mod_main.h | 16 +- src/e_mod_pager.c | 926 +++++++++++++++++++++++++ src/e_mod_scale.c | 1601 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 2776 insertions(+), 1611 deletions(-) create mode 100644 src/e_mod_pager.c create mode 100644 src/e_mod_scale.c diff --git a/e-module-scale.edc b/e-module-scale.edc index 43ac0e1..907370d 100644 --- a/e-module-scale.edc +++ b/e-module-scale.edc @@ -1,9 +1,9 @@ -images +images { image: "module_icon.png" COMP; } -collections +collections { group { name: "icon"; @@ -72,40 +72,22 @@ collections } } } - + group { name: "modules/scale/win"; parts { - + part { name: "e.swallow.win"; - type: RECT; - mouse_events: 1; + type: SWALLOW; description { state: "default" 0.0; - color: 255 255 255 0; - rel1 { - relative: 0.0 0.0; - offset: 0 0; - } - rel2 { - relative: 1.0 1.0; - offset: -1 -1; - } - + color: 255 255 255 200; } description { state: "focused" 0.0; - color: 255 255 255 80; - rel1 { - relative: 0.0 0.0; - offset: 0 0; - } - rel2 { - relative: 1.0 1.0; - offset: -1 -1; - } + color: 255 255 255 255; } } @@ -118,7 +100,7 @@ collections * aspect: 1.0 1.0; * aspect_preference: BOTH; * rel1.relative; - * + * * rel1.offset: 2 2; * rel2.offset: -3 -3; * image.normal: "module_icon.png"; @@ -130,15 +112,20 @@ collections * rel2.offset: 3 3; * } * } */ - /* part { - * name: "event"; - * mouse_events: 1; - * type: RECT; - * description { - * state: "default" 0.0; - * color: 255 255 255 100; - * } - * } */ + part { + name: "event"; + mouse_events: 1; + type: RECT; + description { + state: "default" 0.0; + color: 200 200 200 10; + } + description { + state: "focused" 0.0; + color: 255 255 255 150; + } + + } } programs { program { @@ -147,7 +134,7 @@ collections source: "e"; action: STATE_SET "focused" 0.0; transition: SINUSOIDAL 0.3; - target: "e.swallow.win"; + target: "event"; } program { name: "mouse_out"; @@ -155,9 +142,99 @@ collections source: "e"; action: STATE_SET "default" 0.0; transition: SINUSOIDAL 0.4; - target: "e.swallow.win"; + target: "event"; } } } + group { + name: "modules/scale/desk"; + + parts { + part { + name: "left"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 120; + rel2 { + relative: 0.0 1.0; + offset: 0 -1; + } + } + } + part { + name: "right"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 120; + rel1 { + relative: 1.0 0.0; + offset: -1 0; + } + } + } + part { + name: "top"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 120; + rel2 { + relative: 1.0 0.0; + offset: -1 0; + } + } + } + part { + name: "bottom"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 100; + rel1 { + relative: 0.0 1.0; + offset: 0 -1; + } + + } + } + part { + name: "event"; + mouse_events: 1; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 100; + } + description { + state: "focused" 0.0; + color: 0 0 0 80; + } + } + } + programs { + program { + name: "mouse_in"; + signal: "mouse,in"; + source: "e"; + action: STATE_SET "focused" 0.0; + transition: SINUSOIDAL 0.3; + target: "event"; + } + program { + name: "mouse_out"; + signal: "mouse,out"; + source: "e"; + action: STATE_SET "default" 0.0; + transition: SINUSOIDAL 0.4; + target: "event"; + } + } + } } diff --git a/src/Makefile.am b/src/Makefile.am index c34cf3e..3e576aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,9 @@ pkgdir = $(datadir)/$(MODULE_ARCH) pkg_LTLIBRARIES = module.la module_la_SOURCES = e_mod_main.h \ e_mod_main.c \ - e_mod_config.c + e_mod_config.c \ + e_mod_scale.c \ + e_mod_pager.c module_la_LIBADD = @E_LIBS@ module_la_LDFLAGS = -module -avoid-version diff --git a/src/e_mod_config.c b/src/e_mod_config.c index d0cf65d..2b47939 100644 --- a/src/e_mod_config.c +++ b/src/e_mod_config.c @@ -18,6 +18,11 @@ struct _E_Config_Dialog_Data int fade_popups; int fade_desktop; int fade_windows; + + double pager_duration; + int pager_fade_popups; + int pager_fade_desktop; + int pager_fade_windows; }; @@ -74,50 +79,31 @@ _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) static void _fill_data(E_Config_Dialog_Data *cfdata) { - cfdata->tight = scale_conf->tight; - cfdata->grow = scale_conf->grow; - cfdata->duration = scale_conf->scale_duration; - cfdata->spacing = scale_conf->spacing; - cfdata->desks_duration = scale_conf->desks_duration; - cfdata->desks_spacing = scale_conf->desks_spacing; - cfdata->fade_popups = scale_conf->fade_popups; - cfdata->fade_desktop = scale_conf->fade_desktop; - cfdata->fade_windows = scale_conf->fade_windows; - cfdata->fade_desktop = scale_conf->fade_desktop; - cfdata->layout_mode = scale_conf->layout_mode; - cfdata->desks_layout_mode = scale_conf->desks_layout_mode; - cfdata->desks_tight = scale_conf->desks_tight; - cfdata->desks_grow = scale_conf->desks_grow; - -} - -static void -_cb_test(void *data, void *data2) -{ - E_Config_Dialog_Data *cfdata = data; - - scale_conf->grow = cfdata->grow; - scale_conf->tight = cfdata->tight; - scale_conf->scale_duration = cfdata->duration; - scale_conf->spacing = cfdata->spacing; - scale_conf->desks_duration = cfdata->desks_duration; - scale_conf->desks_spacing = cfdata->desks_spacing; - scale_conf->fade_popups = cfdata->fade_popups; - scale_conf->fade_desktop = cfdata->fade_desktop; - scale_conf->fade_windows = cfdata->fade_windows; - scale_conf->fade_desktop = cfdata->fade_desktop; - scale_conf->layout_mode = cfdata->layout_mode; - scale_conf->desks_layout_mode = cfdata->desks_layout_mode; - scale_conf->desks_grow = cfdata->desks_grow; - scale_conf->desks_tight = cfdata->desks_tight; - - scale_run(e_manager_current_get()); + cfdata->tight = scale_conf->tight; + cfdata->grow = scale_conf->grow; + cfdata->duration = scale_conf->scale_duration; + cfdata->spacing = scale_conf->spacing; + cfdata->desks_duration = scale_conf->desks_duration; + cfdata->desks_spacing = scale_conf->desks_spacing; + cfdata->fade_popups = scale_conf->fade_popups; + cfdata->fade_desktop = scale_conf->fade_desktop; + cfdata->fade_windows = scale_conf->fade_windows; + cfdata->layout_mode = scale_conf->layout_mode; + cfdata->desks_layout_mode = scale_conf->desks_layout_mode; + cfdata->desks_tight = scale_conf->desks_tight; + cfdata->desks_grow = scale_conf->desks_grow; + cfdata->pager_duration = scale_conf->pager_duration; + cfdata->pager_fade_popups = scale_conf->pager_fade_popups; + cfdata->pager_fade_desktop = scale_conf->pager_fade_desktop; + cfdata->pager_fade_windows = scale_conf->pager_fade_windows; } static Evas_Object * _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) { - Evas_Object *o, *of, *ow, *ot; + Evas_Object *o, *of, *ow, *ot, *otb; + + otb = e_widget_toolbook_add(evas, 0, 0); ot = e_widget_table_add(evas, 0); @@ -126,21 +112,24 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) of = e_widget_framelist_add(evas, D_("Current Desktop"), 0); ow = e_widget_label_add (evas, D_("Minimum space between windows")); e_widget_framelist_object_append (of, ow); - ow = e_widget_slider_add (evas, 1, 0, D_("%1.0f"), 2.0, 64.0, - 1.0, 0, &(cfdata->spacing), NULL,100); + ow = e_widget_slider_add (evas, 1, 0, D_("%1.0f"), 2.0, 64.0, 1.0, 0, + &(cfdata->spacing), NULL,100); e_widget_framelist_object_append (of, ow); ow = e_widget_label_add (evas, D_("Scale duration")); e_widget_framelist_object_append (of, ow); - ow = e_widget_slider_add (evas, 1, 0, D_("%1.2f"), 0.1, 3.0, - 0.01, 0, &(cfdata->duration), NULL,100); + ow = e_widget_slider_add (evas, 1, 0, D_("%1.2f"), 0.01, 3.0, 0.01, 0, + &(cfdata->duration), NULL,100); e_widget_framelist_object_append (of, ow); - ow = e_widget_check_add(evas, D_("Slotted Layout"), &(cfdata->layout_mode)); + ow = e_widget_check_add(evas, D_("Slotted Layout"), + &(cfdata->layout_mode)); e_widget_framelist_object_append(of, ow); e_widget_framelist_content_align_set(of, 0.0, 0.0); - ow = e_widget_check_add(evas, D_("Grow more!"), &(cfdata->grow)); + ow = e_widget_check_add(evas, D_("Grow more!"), + &(cfdata->grow)); e_widget_framelist_object_append(of, ow); - ow = e_widget_check_add(evas, D_("Keep it tight!"), &(cfdata->tight)); + ow = e_widget_check_add(evas, D_("Keep it tight!"), + &(cfdata->tight)); e_widget_framelist_object_append(of, ow); e_widget_list_object_append(o, of, 1, 1, 0.5); e_widget_table_object_append(ot, o, 0, 0, 1, 1, 1, 1, 0, 0); @@ -155,50 +144,82 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) ow = e_widget_label_add (evas, D_("Scale duration")); e_widget_framelist_object_append (of, ow); - ow = e_widget_slider_add (evas, 1, 0, D_("%1.2f"), 0.1, 3.0, - 0.01, 0, &(cfdata->desks_duration), NULL,100); + ow = e_widget_slider_add (evas, 1, 0, D_("%1.2f"), 0.01, 3.0, 0.01, 0, + &(cfdata->desks_duration), NULL,100); e_widget_framelist_object_append (of, ow); - ow = e_widget_check_add(evas, D_("Slotted Layout"), &(cfdata->desks_layout_mode)); + ow = e_widget_check_add(evas, D_("Slotted Layout"), + &(cfdata->desks_layout_mode)); e_widget_framelist_object_append(of, ow); - ow = e_widget_check_add(evas, D_("Grow more!"), &(cfdata->desks_grow)); + ow = e_widget_check_add(evas, D_("Grow more!"), + &(cfdata->desks_grow)); e_widget_framelist_object_append(of, ow); - ow = e_widget_check_add(evas, D_("Keep it tight!"), &(cfdata->desks_tight)); + ow = e_widget_check_add(evas, D_("Keep it tight!"), + &(cfdata->desks_tight)); e_widget_framelist_object_append(of, ow); - ow = e_widget_check_add(evas, D_("Fade in windows"), &(cfdata->fade_windows)); + ow = e_widget_check_add(evas, D_("Fade in windows"), + &(cfdata->fade_windows)); e_widget_framelist_object_append(of, ow); e_widget_list_object_append(o, of, 1, 1, 0.5); e_widget_table_object_append(ot, o, 1, 0, 1, 1, 1, 1, 0, 0); of = e_widget_framelist_add(evas, D_(""), 1); - ow = e_widget_check_add(evas, D_("Fade out shelves and popups"), &(cfdata->fade_popups)); + ow = e_widget_check_add(evas, D_("Fade out shelves and popups"), + &(cfdata->fade_popups)); e_widget_framelist_object_append(of, ow); - ow = e_widget_check_add(evas, D_("Darken desktop"), &(cfdata->fade_desktop)); - e_widget_framelist_object_append(of, ow); - ow = e_widget_button_add(evas, D_("Test"), NULL, _cb_test, cfdata, NULL); + ow = e_widget_check_add(evas, D_("Darken desktop"), + &(cfdata->fade_desktop)); e_widget_framelist_object_append(of, ow); e_widget_table_object_append(ot, of, 0, 1, 2, 1, 1, 1, 0, 0); + e_widget_toolbook_page_append(otb, NULL, "Scale Windows", ot, 1, 1, 1, 1, 0, 0); - return ot; + ot = e_widget_table_add(evas, 0); + of = e_widget_framelist_add(evas, D_("Pager Settings"), 0); + + ow = e_widget_label_add (evas, D_("Zoom duration")); + e_widget_framelist_object_append(of, ow); + ow = e_widget_slider_add (evas, 1, 0, D_("%1.2f"), 0.01, 3.0, 0.01, 0, + &(cfdata->pager_duration), NULL,100); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, D_("Fade in windows"), + &(cfdata->pager_fade_windows)); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, D_("Fade out shelves and popups"), + &(cfdata->pager_fade_popups)); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, D_("Darken desktop"), + &(cfdata->fade_desktop)); + e_widget_framelist_object_append (of, ow); + e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 0); + + e_widget_toolbook_page_append(otb, NULL, "Pager", ot, 1, 1, 1, 1, 1, 1); + + e_widget_toolbook_page_show(otb, 0); + + return otb; } static int _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) { - scale_conf->grow = cfdata->grow; - scale_conf->tight = cfdata->tight; - scale_conf->scale_duration = cfdata->duration; - scale_conf->spacing = cfdata->spacing; - scale_conf->desks_duration = cfdata->desks_duration; - scale_conf->desks_spacing = cfdata->desks_spacing; - scale_conf->fade_popups = cfdata->fade_popups; - scale_conf->fade_desktop = cfdata->fade_desktop; - scale_conf->fade_windows = cfdata->fade_windows; - scale_conf->fade_desktop = cfdata->fade_desktop; - scale_conf->layout_mode = cfdata->layout_mode; - scale_conf->desks_layout_mode = cfdata->desks_layout_mode; - scale_conf->desks_grow = cfdata->desks_grow; - scale_conf->desks_tight = cfdata->desks_tight; + scale_conf->grow = cfdata->grow; + scale_conf->tight = cfdata->tight; + scale_conf->scale_duration = cfdata->duration; + scale_conf->spacing = cfdata->spacing; + scale_conf->desks_duration = cfdata->desks_duration; + scale_conf->desks_spacing = cfdata->desks_spacing; + scale_conf->fade_popups = cfdata->fade_popups; + scale_conf->fade_desktop = cfdata->fade_desktop; + scale_conf->fade_windows = cfdata->fade_windows; + scale_conf->fade_desktop = cfdata->fade_desktop; + scale_conf->layout_mode = cfdata->layout_mode; + scale_conf->desks_layout_mode = cfdata->desks_layout_mode; + scale_conf->desks_grow = cfdata->desks_grow; + scale_conf->desks_tight = cfdata->desks_tight; + scale_conf->pager_duration = cfdata->pager_duration; + scale_conf->pager_fade_popups = cfdata->pager_fade_popups; + scale_conf->pager_fade_windows = cfdata->pager_fade_windows; + scale_conf->pager_fade_desktop = cfdata->pager_fade_desktop; e_config_save_queue(); return 1; diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 2612720..8687549 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -7,15 +7,6 @@ // while scale is active? // -#define DBG(...) -/* #define DBG(...) printf(__VA_ARGS__) */ - -#define OFFSET 32 -#define PLACE_RUNS 10000 -#define GROW_RUNS 1000 -#define SHRINK_RUNS 2000 -#define GROW 6.0 - static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style); static void _gc_shutdown(E_Gadcon_Client *gcc); static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient); @@ -30,1513 +21,35 @@ static void _scale_gc_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, vo static void _scale_gc_cb_menu_post(void *data, E_Menu *menu); static void _scale_gc_cb_menu_configure(void *data, E_Menu *mn, E_Menu_Item *mi); -static void _scale_finish(void); -static void _scale_in(void); -static void _scale_out(void); - -static Eina_Bool _scale_cb_mouse_down(void *data, int type, void *event); -static Eina_Bool _scale_cb_mouse_move(void *data, int type, void *event); - -static void _scale_win_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info); -static void _scale_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); -static void _scale_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); -static void _scale_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a); -static void _scale_win_cb_intercept_layer(void *data, Evas_Object *obj, int l); - -typedef struct _Item Item; -typedef struct _Slot Slot; - -struct _Item -{ - Evas_Object *o, *o_win; - E_Border *bd; - E_Comp_Win *cw; - double scale; - int alpha; - - double x; - double y; - double w; - double h; - - double mx; - double my; - - /* border origin (is moved when scale on another desk) */ - double bd_x; - double bd_y; - - /* current position to draw by compositor */ - int cur_x, cur_y, cur_w, cur_h; - - /* borders' desk distance to the current desk */ - int dx, dy; - - int overlaps; - - int in_slots; -}; - -struct _Slot -{ - Eina_List *items; - int x, y, w, h; - Item *it; - double min; -}; - -static Ecore_X_Window input_win = 0; -static E_Msg_Handler *msg_handler = NULL; static E_Action *act = NULL; -static Eina_List *items = NULL; -static Eina_List *popups = NULL; -static Eina_List *handlers = NULL; -static Ecore_Animator *scale_animator = NULL; -static Eina_Bool scale_state = EINA_FALSE; -static double start_time; -static E_Zone *zone = NULL; -static int max_x, max_y, min_x, min_y; -static int use_x, use_y, use_w, use_h; -static int max_width, max_height; -static int spacing; -static int step_count; -static Item *background = NULL; -static Item *selected_item = NULL; -static E_Desk *current_desk = NULL; -static int show_all_desks = EINA_FALSE; -static int send_to_desk = EINA_FALSE; - -static Eina_Bool -_scale_redraw(void *blah) -{ - Eina_List *l; - Item *it; - double scale, a, in, duration; - - if (show_all_desks) - duration = scale_conf->desks_duration; - else - duration = scale_conf->scale_duration; - - if (scale_state) - scale = (ecore_time_get() - start_time) / duration; - else - scale = 1.0 - (ecore_time_get() - start_time) / duration; - - if (scale > 1.0) scale = 1.0; - if (scale < 0.0) scale = 0.0; - - in = log(10) * scale; - in = 1.0 / exp(in*in); - - EINA_LIST_FOREACH(items, l, it) - { - it->cur_w = it->bd->w * in + it->w * (1.0 - in); - it->cur_h = it->bd->h * in + it->h * (1.0 - in); - it->cur_x = it->bd_x * in + it->x * (1.0 - in); - it->cur_y = it->bd_y * in + it->y * (1.0 - in); - - evas_object_move(it->o, it->cur_x, it->cur_y); - evas_object_resize(it->o, it->cur_w, it->cur_h); - - evas_object_move(it->o_win, it->cur_x, it->cur_y); - evas_object_resize(it->o_win, it->cur_w, it->cur_h); - - a = 255.0 * (1.0 - in); - evas_object_color_set(it->o, a, a, a, a); - - if (!scale_conf->fade_windows) - continue; - - if ((it->bd->desk != current_desk) && (selected_item != it)) - { - double ax = it->cur_x - it->x; - double ay = it->cur_y - it->y; - double bx = it->bd_x - it->x; - double by = it->bd_y - it->y; - - a = (1.0 - sqrt(ax*ax + ay*ay) / sqrt(bx*bx + by*by)) * 255; - } - else - { - a = 255.0; - } - - it->alpha = a; - evas_object_color_set(it->o_win, a, a, a, a); - } - - if (scale_conf->fade_popups) - { - a = 255.0 * in; - - EINA_LIST_FOREACH(popups, l, it) - evas_object_color_set(it->o_win, a, a, a, a); - } - - if (scale_conf->fade_desktop && background) - { - a = 255.0 * (0.5 + in/2.0); - - evas_object_color_set(background->o_win, a, a, a, 255); - } - - e_manager_comp_evas_update(e_manager_current_get()); - - if (scale < 1.0 && scale > 0.0) - return 1; - - if (scale == 0.0) - _scale_finish(); - - scale_animator = NULL; - return 0; -} - static void -_scale_in() +_e_mod_action(const char *params) { - start_time = ecore_time_get(); - scale_state = EINA_TRUE; + if (!params) return; - if (!scale_animator) - scale_animator = ecore_animator_add(_scale_redraw, NULL); -} - -static void -_scale_out() -{ - double duration, now = ecore_time_get(); - - if (show_all_desks) - duration = scale_conf->desks_duration; - else - duration = scale_conf->scale_duration; - - if (now - start_time < duration) - start_time = now - (duration - (now - start_time)); - else - start_time = now; - - if (!scale_animator) - scale_animator = ecore_animator_add(_scale_redraw, NULL); - - scale_state = EINA_FALSE; -} - -static void -_scale_finish() -{ - Ecore_Event_Handler *handler; - Item *it; - E_Desk *desk; - - e_grabinput_release(input_win, input_win); - ecore_x_window_free(input_win); - input_win = 0; - - desk = e_desk_current_get(zone); - - if (selected_item && selected_item->bd->desk != desk) + if (!strncmp(params, "go_pager", 8)) { - if (send_to_desk) - { - e_border_desk_set(selected_item->bd, desk); - } - else - { - int tmp = e_config->desk_flip_animate_mode; - - desk = selected_item->bd->desk; - - e_config->desk_flip_animate_mode = 0; - e_desk_show(desk); - e_config->desk_flip_animate_mode = tmp; - } + pager_run(params); } - - EINA_LIST_FREE(items, it) + else if (!strncmp(params, "go_scale", 8)) { - evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, _scale_win_delorig); - evas_object_intercept_move_callback_del(it->o_win, _scale_win_cb_intercept_move); - evas_object_intercept_resize_callback_del(it->o_win, _scale_win_cb_intercept_resize); - evas_object_intercept_color_set_callback_del(it->o_win, _scale_win_cb_intercept_color); - evas_object_intercept_layer_set_callback_del(it->o_win, _scale_win_cb_intercept_layer); - - /* evas_object_clip_unset(it->o_win); */ - /* edje_object_part_unswallow(it->o, it->o_win); */ - evas_object_del(it->o); - - if (it->bd->desk != desk) - { - e_border_hide(it->bd, 2); - evas_object_hide(it->o_win); - evas_object_color_set(it->o_win, 255, 255, 255, 255); - evas_object_move(it->o_win, it->bd->x, it->bd->y); - evas_object_resize(it->o_win, it->cw->w, it->cw->h); - } - - e_object_unref(E_OBJECT(it->bd)); - E_FREE(it); + scale_run(params); } - - EINA_LIST_FREE(popups, it) - { - evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, _scale_win_delorig); - evas_object_color_set(it->o_win, 255, 255, 255, 255); - E_FREE(it); - } - - if (scale_conf->fade_desktop && background) - { - it = background; - evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, _scale_win_delorig); - evas_object_color_set(it->o_win, 255, 255, 255, 255); - E_FREE(it); - } - - EINA_LIST_FREE(handlers, handler) - ecore_event_handler_del(handler); - - e_msg_handler_del(msg_handler); - msg_handler = NULL; - zone = NULL; - selected_item = NULL; - current_desk = NULL; - send_to_desk = EINA_FALSE; - show_all_desks = EINA_FALSE; - - e_manager_comp_evas_update(e_manager_current_get()); -} - - -static void -_scale_win_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - Item *it = data; - - evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, _scale_win_delorig); - - if (it->bd) - { - e_object_unref(E_OBJECT(it->bd)); - _scale_out(); - - evas_object_intercept_move_callback_del(it->o_win, _scale_win_cb_intercept_move); - evas_object_intercept_resize_callback_del(it->o_win, _scale_win_cb_intercept_resize); - evas_object_intercept_color_set_callback_del(it->o_win, _scale_win_cb_intercept_color); - evas_object_intercept_layer_set_callback_del(it->o_win, _scale_win_cb_intercept_layer); - - /* evas_object_clip_unset(it->o_win); */ - /* edje_object_part_unswallow(it->o, it->o_win); */ - evas_object_del(it->o); - - items = eina_list_remove(items, it); - } - else - { - popups = eina_list_remove(popups, it); - } - - E_FREE(it); -} - -static void -_scale_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) -{ - Item *it = data; - - evas_object_move(obj, it->cur_x, it->cur_y); -} - -static void -_scale_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - Item *it = data; - - evas_object_resize(obj, it->cur_w, it->cur_h); -} - -static void -_scale_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a) -{ - Item *it = data; - - evas_object_color_set(obj, it->alpha, it->alpha, it->alpha, it->alpha); -} - -static void -_scale_win_cb_intercept_layer(void *data, Evas_Object *obj, int l) -{ - Item *it = data; - - evas_object_layer_set(it->o_win, l); - evas_object_stack_above(it->o, it->o_win); -} - -static void -_scale_win_new(Evas *e, E_Manager *man, E_Manager_Comp_Source *src, E_Desk *desk) -{ - Item *it; - - if (!e_manager_comp_src_image_get(man, src)) return; - - E_Comp_Win *cw = (void*)src; - - if (!cw->bd) - { - if (cw->win == zone->container->bg_win) - { - if (scale_conf->fade_desktop) - { - it = E_NEW(Item, 1); - it->o_win = e_manager_comp_src_shadow_get(man, src); - evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, - _scale_win_delorig, it); - background = it; - } - } - else if (scale_conf->fade_popups) - { - it = E_NEW(Item, 1); - it->o_win = e_manager_comp_src_shadow_get(man, src); - evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, - _scale_win_delorig, it); - - popups = eina_list_append(popups, it); - } - - return; - } - - if (!cw->bd) return; - - if (cw->bd->zone != desk->zone) - return; - - if ((!show_all_desks) && (cw->bd->desk != desk)) - return; - - if (cw->bd->iconic) - return; - - it = E_NEW(Item, 1); - it->scale = 1.0; - - it->dx = cw->bd->desk->x - desk->x; - it->dy = cw->bd->desk->y - desk->y; - - it->x = cw->bd->x + it->dx * desk->zone->w; - it->y = cw->bd->y + it->dy * desk->zone->h; - it->w = cw->bd->w; - it->h = cw->bd->h; - - it->bd_x = it->x; - it->bd_y = it->y; - - it->cur_x = it->x; - it->cur_y = it->y; - it->cur_w = it->w; - it->cur_h = it->h; - - e_object_ref(E_OBJECT(cw->bd)); - it->bd = cw->bd; - it->cw = cw; - - it->o_win = e_manager_comp_src_shadow_get(man, src); - it->o = edje_object_add(e); - if (!e_theme_edje_object_set(it->o, "base/theme/modules/scale", - "modules/scale/win")) - edje_object_file_set(it->o, scale_conf->theme_path, "modules/scale/win"); - - evas_object_stack_above(it->o, it->o_win); - /* edje_object_part_swallow(it->o, "e.swallow.win", it->o_win); */ - /* evas_object_clip_set(it->o_win, it->o); - * evas_object_move(it->o, it->x, it->y); */ - - evas_object_show(it->o); - - evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, _scale_win_delorig, it); - - evas_object_intercept_move_callback_add(it->o_win, _scale_win_cb_intercept_move, it); - evas_object_intercept_resize_callback_add(it->o_win, _scale_win_cb_intercept_resize, it); - evas_object_intercept_color_set_callback_add(it->o_win, _scale_win_cb_intercept_color, it); - evas_object_intercept_layer_set_callback_add(it->o_win, _scale_win_cb_intercept_layer, it); - - if (it->bd->desk != desk) - { - e_border_show(it->bd); - evas_object_move(it->o_win, it->x, it->y); - } - - items = eina_list_append(items, it); -} - -static int -_scale_grow() -{ - Item *it, *ot; - Eina_List *l, *ll; - - int cont = 0; - int overlap; - double grow_l, grow_r, grow_d, grow_u; - - double mean = 0; - EINA_LIST_FOREACH(items, l, it) - { - it->scale = it->w / (double)it->bd->w; - mean += it->scale; - } - - mean /= (double) eina_list_count(items); - - EINA_LIST_FOREACH(items, l, it) - { - overlap = 0; - - if (it->scale > mean) - continue; - - if (it->w >= it->bd->w) - continue; - if (it->h >= it->bd->h) - continue; - - if (it->bd->w > it->bd->h) - { - grow_l = grow_r = GROW; - grow_u = grow_d = GROW * (double)it->bd->h/(double)it->bd->w; - } - else - { - grow_l = grow_r = GROW * (double)it->bd->w/(double)it->bd->h; - grow_u = grow_d = GROW; - } - - if (it->x - grow_l < min_x) - grow_l = 0; - if (it->y - grow_u < min_y) - grow_u = 0; - if (it->x + it->w + grow_r > max_x) - grow_r = 0; - if (it->y + it->h + grow_d > max_y) - grow_d = 0; - - if ((grow_l + grow_r) == 0) - continue; - if ((grow_u + grow_d) == 0) - continue; - - EINA_LIST_FOREACH(items, ll, ot) - { - if (it == ot) - continue; - if (grow_l && E_INTERSECTS(it->x - grow_l - spacing ,it->y, - it->w + spacing*2, it->h + spacing*2, - ot->x, ot->y, ot->w, ot->h)) - grow_l = 0; - - if (grow_r && E_INTERSECTS(it->x - spacing, it->y - spacing, - it->w + grow_r + spacing*2, it->h + spacing*2, - ot->x, ot->y, ot->w, ot->h)) - grow_r = 0; - - if ((grow_l == 0) && (grow_r == 0) && (overlap = 1)) - break; - - if (grow_u && E_INTERSECTS(it->x - spacing, it->y - spacing - grow_u, - it->w + spacing*2, it->h + spacing*2, - ot->x, ot->y, ot->w, ot->h)) - grow_u = 0; - - if (grow_d && E_INTERSECTS(it->x - spacing, it->y - spacing, - it->w + spacing*2, it->h + grow_d + spacing*2, - ot->x, ot->y, ot->w, ot->h)) - grow_d = 0; - - if ((grow_u == 0) && (grow_d == 0) && (overlap = 1)) - break; - } - - if (overlap) - continue; - - if (it->bd->w > it->bd->h) - { - if ((grow_u > 0) && (grow_d > 0)) - it->w += grow_l + grow_r; - else - it->w += MAX(grow_l, grow_r); - - it->h = it->w * (double)it->bd->h / (double)it->bd->w; - } - else - { - if ((grow_r > 0) && (grow_l > 0)) - it->h += grow_u + grow_d; - else - it->h += MAX(grow_u, grow_d); - - it->w = it->h * (double)it->bd->w / (double)it->bd->h; - } - it->x -= grow_l; - it->y -= grow_u; - - cont++; - } - - return cont; -} - -static void -_scale_displace(Item *it, Item *ot, int disp) -{ - /* cycle items with same center around to get even distribution. - dont try to understand this but these initial conditions - are important.. you can have up to 9 maximized windows. - if you can figure out more please tell me :) */ - - if (disp % 8 == 0) - { - // 1. - it->y -= 1; - it->x -= 1; - // 2. - ot->x += 1; - ot->y -= 1; - } - else if (disp % 8 == 1) - { - // 3. - ot->y += 1; - } - else if (disp % 8 == 2) - { - // 4. - ot->x -= 2; - ot->y += 2; - } - else if (disp % 8 == 3) - { - // 5. - ot->x += 2; - ot->y += 2; - } - else if (disp % 8 == 4) - { - // 6. - ot->x += 1; - ot->y += 1; - } - else if (disp % 8 == 5) - { - // 7. - ot->x -= 1; - ot->y += 1; - } - else if (disp % 8 == 6) - { - // 8. - ot->x -= 1; - ot->y -= 1; - } - else if (disp % 8 == 7) - { - ot->x += 1; - ot->y -= 1; - } -} - -static int -_scale_place(int offset) -{ - Item *it, *ot; - Eina_List *l, *ll; - int overlap = 0; - int outside = 0; - - EINA_LIST_FOREACH(items, l, it) - { - it->mx = it->x; - it->my = it->y; - } - - int disp = 0; - - EINA_LIST_FOREACH(items, l, it) - { - EINA_LIST_FOREACH(items, ll, ot) - { - int w = it->w; - int h = it->h; - - if (it == ot) - continue; - - if (!E_INTERSECTS(it->x - offset, it->y - offset, - it->w + offset*2, it->h + offset*2, - ot->x, ot->y, ot->w, ot->h)) - continue; - - overlap += 1; - - it->overlaps++; - - if (it->x < ot->x) - w += it->x - ot->x; - if (w < 0) w = 0; - - if (it->x + it->w > ot->x + ot->w) - w = ot->x + ot->w - it->x; - - if (it->y < ot->y) - h += it->y - ot->y; - if (h < 0) h = 0; - - if (it->y + it->h > ot->y + ot->h) - h = ot->y + ot->h - it->y; - - double dist_y = (it->y + it->h/2) - (ot->y + ot->h/2); - double dist_x = (it->x + it->w/2) - (ot->x + ot->w/2); - - if (dist_x == 0 && dist_y == 0) - { - _scale_displace(it, ot, disp); - disp++; - } - else if (w > h) - { - if (dist_y) - { - dist_y = (dist_y > 0 ? 2 : -2); - it->my += dist_y; - } - if (dist_x) - { - dist_x = (dist_x > 0 ? 1 : -1); - it->mx += dist_x; - } - } - else //if (w < h) - { - if (dist_y) - { - dist_y = (dist_y > 0 ? 1 : -1); - it->my += dist_y; - } - if (dist_x) - { - dist_x = (dist_x > 0 ? 2 : -2); - it->mx += dist_x; - } - } - } - } - - EINA_LIST_FOREACH(items, l, it) - { - it->x = it->mx; - it->y = it->my; - - if (it->x < min_x) - { - outside = 1; - it->x = min_x; - } - - if (it->y < min_y) - { - outside = 1; - it->y = min_y; - } - - if (it->x + it->w > max_x) - { - outside = 1; - it->x = max_x - it->w; - } - - if (it->y + it->h > max_y) - { - outside = 1; - it->y = max_y - it->h; - } - } - - if (!(overlap || outside)) - return 0; - - if (outside && (step_count++ > 50)) - { - double zone_diag = sqrt(zone->w * zone->h); - double sw, sh; - step_count = 0; - EINA_LIST_FOREACH(items, l, it) - { - if (!it->overlaps) - continue; - - if (it->scale <= 0.005) - continue; - - it->scale -= it->scale * - (0.001 + (sqrt(it->bd->w * it->bd->h) / zone_diag) / 50.0); - - sw = (double)it->bd->w * it->scale; - sh = (double)it->bd->h * it->scale; - it->x += (it->w - sw)/2.0; - it->y += (it->h - sh)/2.0; - it->w = sw; - it->h = sh; - - it->overlaps = 0; - } - return 1; - } - - return overlap || outside; -} - -static int -_scale_shrink() -{ - Eina_List *l, *ll; - Item *it, *ot; - int shrunk = 0; - double move_x; - double move_y; - - EINA_LIST_REVERSE_FOREACH(items, l, it) - { - if (show_all_desks) - { - move_x = ((it->x + it->w/2.0) - zone->w/2.0) / 5.0; - move_y = ((it->y + it->h/2.0) - zone->h/2.0) / 5.0; - } - else - { - move_x = ((it->x + it->w/2.0) - (double)(it->bd->x + it->bd->w/2.0)) / 10.0; - move_y = ((it->y + it->h/2.0) - (double)(it->bd->y + it->bd->h/2.0)) / 10.0; - } - - if (!(move_y || move_x)) - continue; - - EINA_LIST_FOREACH(items, ll, ot) - { - if (it == ot) continue; - - while(move_x) - { - if (E_INTERSECTS(it->x - move_x, it->y, it->w, it->h, - ot->x - spacing, ot->y - spacing, - ot->w + spacing*2, ot->h + spacing*2)) - move_x = move_x / 2.0; - else break; - } - - while(move_y) - { - if (E_INTERSECTS(it->x, it->y - move_y, it->w, it->h, - ot->x - spacing, ot->y - spacing, - ot->w + spacing*2, ot->h + spacing*2)) - move_y = move_y / 2.0; - else break; - } - - if (!(move_y || move_x)) break; - } - - it->x -= move_x; - it->y -= move_y; - - if (move_y > 1 || move_x > 1) - shrunk++; - } - - return shrunk; -} - - -/* TODO add slot item an calc distance only once */ -static Slot *cur_slot = NULL; - -static double -_slot_dist(const Item *it, const Slot *slot) -{ - double dx = it->x - slot->x; - double dy = it->y - slot->y; - double dw = (it->x + it->w) - (slot->x + slot->w); - double dh = (it->y + it->h) - (slot->y + slot->h); - - return (sqrt(dx*dx + dy*dy + dw*dw + dh*dh)); -} - -static int -_cb_sort_nearest(const void *d1, const void *d2) -{ - const Item *it1 = d1; - const Item *it2 = d2; - - return (_slot_dist(it1, cur_slot) < _slot_dist(it2, cur_slot)) ? -1 : 1; -} - -static int -_scale_place_slotted() -{ - Eina_List *l, *ll, *slots = NULL; - Slot *slot, *slot2; - Item *it; - int rows, cols, cnt, x, y, w, h, start; - int fast = 1; - int cont = 0, i = 0; - double min_x, max_x, min_y, max_y; - - cnt = eina_list_count(items); - - rows = sqrt(cnt); - cols = cnt/rows; - - if (cols*rows < cnt) - cols += 1; - - if (cnt <= 2) - { - cols = 2; - rows = 1; - } - else if (cnt <= 4) - { - cols = 2; - rows = 2; - } - else if (cnt <= 6) - { - cols = 3; - rows = 2; - } - else if (cnt <= 8) - { - cols = 3; - rows = 3; - } - - DBG("%d rows, %d cols -- cnt %d\n", rows, cols, cnt); - - max_x = max_y = 0; - min_x = min_y = 100000; - - EINA_LIST_FOREACH(items, l, it) - { - if (it->x < min_x) min_x = it->x; - if (it->y < min_y) min_y = it->y; - if (it->x + it->w > max_x) max_x = it->x + it->w; - if (it->y + it->h > max_y) max_y = it->y + it->h; - } - - w = (max_x - min_x) / cols; - h = (max_y - min_y) / rows; - l = items; - - for (y = 0; y < rows; y++) - { - for (x = 0; x < cols; x++) - { - if (fast && !l) break; - - slot = E_NEW(Slot, 1); - slot->x = min_x + x * w; - slot->y = min_y + y * h; - slot->w = w; - slot->h = h; - - if (fast) - { - slot->it = eina_list_data_get(l); - if (l) l = l->next; - } - else - { - cur_slot = slot; - slot->items = eina_list_clone(items); - slot->items = eina_list_sort(slot->items, cnt, _cb_sort_nearest); - slot->it = eina_list_data_get(slot->items); - slot->items = eina_list_remove_list(slot->items, slot->items); - slot->min = _slot_dist(slot->it, slot); - } - - slots = eina_list_append(slots, slot); - - DBG("add slot: %dx%d, \t%f -> %d:%d\n", slot->x, slot->y, slot->min, - (int)(slot->it->x), (int)(slot->it->y)); - } - } - - if (!fast) - { - cont = 1; - EINA_LIST_FOREACH(items, l, it) - it->in_slots = cols * rows; - } - - for (i = 0; (i < PLACE_RUNS) && cont; i++) - { - cont = 0; - EINA_LIST_FOREACH(slots, l, slot) - { - EINA_LIST_FOREACH(slots, ll, slot2) - { - if (slot == slot2) - continue; - - if (slot->it != slot2->it) - continue; - - Item *it1 = eina_list_data_get(slot->items); - Item *it2 = eina_list_data_get(slot2->items); - if (!it1 || !it2) - continue; - - double d1 = _slot_dist(it1, slot); - double d2 = _slot_dist(it2, slot2); - - cont = 1; - - DBG("%dx%d - compare:\n\ts1: %dx%d (%dx%d:%f),\n\ts2 %dx%d (%dx%d:%f)\n", - (int)slot->it->x, (int)slot->it->y, - slot->x, slot->y, (int)it1->x, (int)it1->y, d1, - slot2->x, slot2->y, (int)it2->x, (int)it2->y, d2); - - if (slot->it->in_slots > 1 && slot->min + d1 >= slot2->min + d2) - { - slot->it->in_slots--; - slot->it = it1; - slot->min = d1; - slot->items = eina_list_remove_list(slot->items, slot->items); - break; - } - } - } - } - - cont = 1; - - for (i = 0; (i < PLACE_RUNS) && ( fast && cont); i++) - { - cont = 0; - EINA_LIST_FOREACH(slots, l, slot) - { - EINA_LIST_FOREACH(l->next, ll, slot2) - { - double d1, d2; - - d1 = _slot_dist(slot->it, slot) + _slot_dist(slot2->it, slot2); - d2 = _slot_dist(slot->it, slot2) + _slot_dist(slot2->it, slot); - if (d1 > d2) - { - it = slot->it; - slot->it = slot2->it; - slot2->it = it; - cont = 1; - } - } - } - } - - EINA_LIST_FOREACH(slots, l, slot) - { - if (!slot->it) - continue; - - EINA_LIST_FOREACH(slots, ll, slot2) - { - if (slot == slot2) - continue; - - if (slot->it != slot2->it) - continue; - - if (_slot_dist(slot->it, slot) > _slot_dist(slot2->it, slot2)) - slot->it = NULL; - else - slot2->it = NULL; - } - } - - h = (zone->h - spacing) / rows; - w = (zone->w - spacing) / cols; - - for (y = 0, l = slots; l && (y < rows); y++) - { - ll = l; - for (x = 0, cnt = 0; l && x < cols; x++, l = eina_list_next(l)) - { - slot = eina_list_data_get(l); - if (slot->it) cnt++; - } - - if (cnt < cols) - start = (w * (cols - cnt))/2.0; - else - start = spacing/2.0; - - for (x = 0; ll && x < cnt; ll = eina_list_next(ll)) - { - slot = eina_list_data_get(ll); - if (!slot->it) continue; - - slot->x = start + x * w; - slot->y = y * h; - slot->w = w; - slot->h = h; - x++; - } - } - - EINA_LIST_FOREACH(slots, l, slot) - { - if (slot->it) - { - it = slot->it; - - if (it->w > slot->w - spacing) - { - it->w = slot->w - spacing; - it->h = it->w * (double)it->bd->h / (double)it->bd->w; - } - if (it->h > slot->h - spacing) - { - it->h = slot->h - spacing; - it->w = it->h * (double)it->bd->w / (double)it->bd->h; - } - it->x = slot->x + (slot->w - it->w)/2.0; - it->y = slot->y + (slot->h - it->h)/2.0; - - DBG("place: %d:%d %dx%d -> %d:%d %dx%d\n", - (int)it->bd_x, (int)it->bd_y, (int)it->bd->w, (int)it->bd->h, - (int)it->x, (int)it->y, (int)it->w, (int)it->h); - } - - EINA_LIST_FREE(slot->items, it); - E_FREE(slot); - } - - return 1; -} - - -static int -_cb_sort_center(const void *d1, const void *d2) -{ - const Item *it1 = d1; - const Item *it2 = d2; - - double dx1 = ((it1->x + it1->w/2.0) - (double)(max_width/2)); - double dy1 = ((it1->y + it1->h/2.0) - (double)(max_height/2)); - - double dx2 = ((it2->x + it2->w/2.0) - (double)(max_width/2)); - double dy2 = ((it2->y + it2->h/2.0) - (double)(max_height/2)); - - return (sqrt(dx1*dx1 + dy1*dy1) > sqrt(dx2*dx2 + dy2*dy2)) ? -1 : 1; -} - -static void -_scale_place_natural() -{ - Eina_List *l; - int offset, i = 0; - Item *it; - - max_width = zone->w; - max_height = zone->h; - - if (show_all_desks) - { - max_width = zone->h * zone->desk_x_count; - max_height = zone->w * zone->desk_y_count; - } - - items = eina_list_sort(items, eina_list_count(items), _cb_sort_center); - - offset = spacing; - - if (scale_conf->grow && (spacing < OFFSET)) - offset = OFFSET; - if (scale_conf->tight && (spacing < OFFSET)) - offset = OFFSET; - - step_count = 0; - - while ((i++ < PLACE_RUNS) && - (_scale_place(offset) || - (min_x < use_x) || - (min_y < use_y) || - (max_x > use_w) || - (max_y > use_h))) - { - /* shrink region to visible region */ - if (min_x < use_x) min_x += 2; - if (min_y < use_y) min_y += 2; - if (min_x > use_x) min_x = use_x; - if (min_y > use_y) min_y = use_y; - - if (max_x > use_w) max_x -= 2; - if (max_y > use_h) max_y -= 2; - if (max_x < use_w) max_x = use_w; - if (max_y < use_h) max_y = use_h; - - if (!show_all_desks) - continue; - - /* move other desks windows into visible region */ - EINA_LIST_FOREACH(items, l, it) - { - if ((min_x < use_x) && (it->dx < 0) && it->x < 0) it->x += 4.0; - if ((min_y < use_y) && (it->dy < 0) && it->y < 0) it->y += 4.0; - - if ((max_x > use_w) && (it->dx > 0) && it->x > zone->w) it->x -= 4.0; - if ((max_y > use_h) && (it->dy > 0) && it->y > zone->h) it->y -= 4.0; - } - } -} - -void -scale_run(E_Manager *man) -{ - Eina_List *l; - E_Manager_Comp_Source *src; - Evas *e; - int i; - Item *it; - - zone = e_util_zone_current_get(e_manager_current_get()); - current_desk = e_desk_current_get(zone); - - start_time = ecore_time_get(); - - input_win = ecore_x_window_input_new(zone->container->win, 0, 0, 1, 1); - ecore_x_window_show(input_win); - if (!e_grabinput_get(input_win, 0, input_win)) - { - ecore_x_window_free(input_win); - input_win = 0; - return; - } - - handlers = eina_list_append - (handlers, ecore_event_handler_add - (ECORE_EVENT_MOUSE_BUTTON_DOWN, _scale_cb_mouse_down, NULL)); - - handlers = eina_list_append - (handlers, ecore_event_handler_add - (ECORE_EVENT_MOUSE_MOVE, _scale_cb_mouse_move, NULL)); - - e = e_manager_comp_evas_get(man); - - EINA_LIST_FOREACH((Eina_List *)e_manager_comp_src_list(man), l, src) - { - _scale_win_new(e, man, src, current_desk); - } - - if ((eina_list_count(items) < 2) && (!show_all_desks)) - { - _scale_finish(); - return; - } - - if (show_all_desks) - spacing = scale_conf->desks_spacing; - else - spacing = scale_conf->spacing; - - if (!scale_conf->fade_popups) - { - e_zone_useful_geometry_get(zone, &use_x, &use_y, &use_w, &use_h); - use_w += use_x - spacing*2; - use_h += use_y - spacing*2; - use_x += spacing; - use_y += spacing; - } - else - { - use_w = zone->w - spacing; - use_h = zone->h - spacing; - use_x = use_y = spacing; - } - - min_x = -zone->w * zone->desk_x_current; - min_y = -zone->h * zone->desk_y_current; - max_x = zone->w + zone->w * ((zone->desk_x_count - 1) - zone->desk_x_current); - max_y = zone->h + zone->h * ((zone->desk_y_count - 1) - zone->desk_y_current); - - /* scale all windows down to be next to each other on one zone */ - if (show_all_desks) - { - if (scale_conf->desks_layout_mode) - _scale_place_slotted(); - else - _scale_place_natural(); - } - else - { - if (scale_conf->layout_mode) - _scale_place_slotted(); - else - _scale_place_natural(); - } - - min_x = use_x; - min_y = use_y; - max_x = use_w; - max_y = use_h; - - if ((scale_conf->grow && !show_all_desks) || - (scale_conf->desks_grow && show_all_desks)) - { - i = 0; - while (i++ < GROW_RUNS && _scale_grow()); - DBG("grow %d", i); - } - - if ((scale_conf->tight && !show_all_desks) || - (scale_conf->desks_tight && show_all_desks)) - { - items = eina_list_sort(items, eina_list_count(items), _cb_sort_center); - i = 0; - while (i++ < SHRINK_RUNS && _scale_shrink()); - DBG("shrunk %d", i); - - /* if (scale_conf->grow) - * { - * i = 0; - * while (i++ < GROW_RUNS && _scale_grow()); - * DBG("grow %d", i); - * } */ - } - - if (show_all_desks)//&& !scale_conf->desks_layout_mode) - { - /* center and move windows near visible desk - * to make the sliding smoother */ - - min_x = zone->w; - min_y = zone->h; - max_x = 0; - max_y = 0; - - EINA_LIST_FOREACH(items, l, it) - { - if (it->x < min_x) min_x = it->x; - if (it->y < min_y) min_y = it->y; - if (it->x + it->w > max_x) max_x = it->x + it->w; - if (it->y + it->h > max_y) max_y = it->y + it->h; - } - - EINA_LIST_FOREACH(items, l, it) - { - it->x = (it->x - min_x) + use_x + ((use_w - use_x) - (max_x - min_x))/2.0; - it->y = (it->y - min_y) + use_y + ((use_h - use_y) - (max_y - min_y))/2.0; - - if (it->dx > 0) it->bd_x = zone->w + it->bd->x/4; - if (it->dy > 0) it->bd_y = zone->h + it->bd->y/4; - if (it->dx < 0) it->bd_x = -(zone->w - it->bd->x)/4; - if (it->dy < 0) it->bd_y = -(zone->h + it->bd->y)/4; - } - } - - DBG("time: %f\n", ecore_time_get() - start_time); - - _scale_in(); -} - - -static Eina_Bool -_scale_cb_mouse_move(void *data, int type, void *event) -{ - Ecore_Event_Mouse_Move *ev = event; - Item *it; - Eina_List *l; - - if (ev->window != input_win) - return ECORE_CALLBACK_PASS_ON; - - if (!scale_state) - return ECORE_CALLBACK_PASS_ON; - - EINA_LIST_FOREACH(items, l, it) - if (E_INTERSECTS(ev->x, ev->y, 1, 1, it->x, it->y, it->w, it->h)) - break; - - if (selected_item && (it != selected_item)) - { - edje_object_signal_emit(selected_item->o, "mouse,out", "e"); - selected_item = NULL; - } - - if (it) - { - edje_object_signal_emit(it->o, "mouse,in", "e"); - selected_item = it; - } - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_scale_cb_mouse_down(void *data, int type, void *event) -{ - Ecore_Event_Mouse_Button *ev = event; - Item *it, *ot; - Eina_List *l; - - if (ev->window != input_win) - return ECORE_CALLBACK_PASS_ON; - - if (!scale_state) - return ECORE_CALLBACK_PASS_ON; - - EINA_LIST_FOREACH(items, l, it) - if (E_INTERSECTS(ev->x, ev->y, 1, 1, it->x, it->y, it->w, it->h)) - break; - - if (!it) - { - _scale_out(); - return ECORE_CALLBACK_PASS_ON; - } - - e_border_raise(it->bd); - - - if (it->bd->desk != e_desk_current_get(it->bd->zone)) - { - if (ev->buttons == 1) - { - selected_item = it; - current_desk = it->bd->desk; - - EINA_LIST_FOREACH(items, l, ot) - { - if (ot->bd->desk == it->bd->desk) - { - ot->bd_x = ot->bd->x; - ot->bd_y = ot->bd->y; - } - else - { - if (ot->dx > it->dx) - ot->bd_x = ot->bd->x + zone->w; - else if (ot->dx < it->dx) - ot->bd_x = ot->bd->x - zone->w; - - if (ot->dy > it->dy) - ot->bd_y = ot->bd->y + zone->h; - else if (ot->dy < it->dy) - ot->bd_y = ot->bd->y - zone->h; - } - } - } - else if (ev->buttons == 3) - { - send_to_desk = EINA_TRUE; - selected_item = it; - it->bd_x = it->bd->x; - it->bd_y = it->bd->y; - } - } - - _scale_out(); - - return ECORE_CALLBACK_PASS_ON; -} - -static void -_scale_handler(void *data, const char *name, const char *info, int val, - E_Object *obj, void *msgdata) -{ - E_Manager *man = (E_Manager *)obj; - E_Manager_Comp_Source *src = (E_Manager_Comp_Source *)msgdata; - Evas *e; - - /* DBG("handler... '%s' '%s'\n", name, info); */ - if (strcmp(name, "comp.manager")) return; - - e = e_manager_comp_evas_get(man); - if (!strcmp(info, "change.comp")) - { - if (!e) DBG("TTT: No comp manager\n"); - else DBG("TTT: comp canvas = %p\n", e); - } - else if (!strcmp(info, "resize.comp")) - { - DBG("%s: %p | %p\n", info, man, src); - } - else if (!strcmp(info, "add.src")) - { - /* DBG("%s: %p | %p\n", info, man, src); */ - _scale_win_new(e, man, src, e_desk_current_get(e_util_zone_current_get(man))); - - } - else if (!strcmp(info, "del.src")) - { - DBG("%s: %p | %p\n", info, man, src); - } - else if (!strcmp(info, "config.src")) - { - - DBG("%s: %p | %p\n", info, man, src); - } - /* else if (!strcmp(info, "visible.src")) - * { - * DBG("%s: %p | %p\n", info, man, src); - * } */ } static void _e_mod_action_cb_edge(E_Object *obj, const char *params, E_Event_Zone_Edge *ev) { - Eina_List *list, *l; - E_Manager *man; - - msg_handler = e_msg_handler_add(_scale_handler, NULL); - list = e_manager_list(); - - if (params && !strcmp(params, "show_all_desks")) - show_all_desks = EINA_TRUE; - else - show_all_desks = EINA_FALSE; - - EINA_LIST_FOREACH(list, l, man) - { - Evas *e = e_manager_comp_evas_get(man); - if (e) scale_run(man); - } + _e_mod_action(params); } static void _e_mod_action_cb(E_Object *obj, const char *params) { - Eina_List *list, *l; - E_Manager *man; - - msg_handler = e_msg_handler_add(_scale_handler, NULL); - list = e_manager_list(); - - if (params && !strcmp(params, "show_all_desks")) - show_all_desks = EINA_TRUE; - else - show_all_desks = EINA_FALSE; - - EINA_LIST_FOREACH(list, l, man) - { - Evas *e = e_manager_comp_evas_get(man); - if (e) scale_run(man); - } + _e_mod_action(params); } - /* Module and Gadcon stuff */ typedef struct _Instance Instance; @@ -1611,6 +124,11 @@ e_modapi_init(E_Module *m) E_CONFIG_VAL(D, T, desks_spacing, DOUBLE); E_CONFIG_VAL(D, T, fade_windows, UCHAR); + E_CONFIG_VAL(D, T, pager_duration, DOUBLE); + E_CONFIG_VAL(D, T, pager_fade_windows, UCHAR); + E_CONFIG_VAL(D, T, pager_fade_popups, UCHAR); + E_CONFIG_VAL(D, T, pager_fade_desktop, UCHAR); + E_CONFIG_LIST(D, T, conf_items, conf_item_edd); scale_conf = e_config_domain_load("module.scale", conf_edd); @@ -1638,8 +156,12 @@ e_modapi_init(E_Module *m) { act->func.go = _e_mod_action_cb; act->func.go_edge = _e_mod_action_cb_edge; - e_action_predef_name_set(D_("Desktop"), D_("Scale Windows"), "scale-windows", "", NULL, 0); - e_action_predef_name_set(D_("Desktop"), D_("Scale Windows / All Desktops"), "scale-windows", "show_all_desks", NULL, 0); + e_action_predef_name_set(D_("Desktop"), D_("Scale Windows"), + "scale-windows", "go_scale", NULL, 0); + e_action_predef_name_set(D_("Desktop"), D_("Scale Windows (All Desktops)"), + "scale-windows", "go_scale_all", NULL, 0); + e_action_predef_name_set(D_("Desktop"), D_("Scale Pager"), + "scale-windows", "go_pager", NULL, 0); } return m; @@ -1679,8 +201,9 @@ e_modapi_shutdown(E_Module *m) if (act) { - e_action_predef_name_del(D_("Desktop"), - D_("Scale Windows")); + e_action_predef_name_del(D_("Desktop"), D_("Scale Windows")); + e_action_predef_name_del(D_("Desktop"), D_("Scale Windows (All Desktops)")); + e_action_predef_name_del(D_("Desktop"), D_("Scale Pager")); e_action_del("scale-windows"); } @@ -1797,6 +320,10 @@ _scale_conf_new(void) scale_conf->desks_spacing = 44; scale_conf->layout_mode = 0; scale_conf->desks_layout_mode = 1; + scale_conf->pager_duration = 0.4; + scale_conf->pager_fade_popups = 1; + scale_conf->pager_fade_desktop = 0; + scale_conf->pager_fade_windows = 1; _scale_conf_item_get(NULL); IFMODCFGEND; @@ -1911,7 +438,6 @@ _scale_gc_cb_menu_post(void *data, E_Menu *menu) inst->menu = NULL; } -/* call configure from popup */ static void _scale_gc_cb_menu_configure(void *data, E_Menu *mn, E_Menu_Item *mi) { diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 69186ea..9a50d3e 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -1,7 +1,7 @@ #ifndef E_MOD_MAIN_H #define E_MOD_MAIN_H -#define MOD_CONFIG_FILE_EPOCH 0x0004 +#define MOD_CONFIG_FILE_EPOCH 0x0005 #define MOD_CONFIG_FILE_GENERATION 0x0001 #define MOD_CONFIG_FILE_VERSION \ ((MOD_CONFIG_FILE_EPOCH << 16) | MOD_CONFIG_FILE_GENERATION) @@ -10,6 +10,9 @@ #include #define D_(str) dgettext(PACKAGE, str) +#define DBG(...) +/* #define DBG(...) printf(__VA_ARGS__) */ + typedef struct _Config_Item Config_Item; typedef struct _Config Config; typedef struct _E_Comp_Win E_Comp_Win; @@ -22,12 +25,14 @@ struct _Config E_Config_Dialog *cfd; const char *theme_path; + /* scale current desk */ int layout_mode; unsigned char tight; unsigned char grow; double scale_duration; double spacing; + /* scale all desk */ int desks_layout_mode; unsigned char desks_tight; unsigned char desks_grow; @@ -37,6 +42,12 @@ struct _Config unsigned char fade_popups; unsigned char fade_desktop; + + /* pager */ + double pager_duration; + unsigned char pager_fade_windows; + unsigned char pager_fade_popups; + unsigned char pager_fade_desktop; }; struct _Config_Item @@ -123,7 +134,8 @@ EAPI int e_modapi_save(E_Module *m); E_Config_Dialog *e_int_config_scale_module(E_Container *con, const char *params); -void scale_run(E_Manager *man); +void scale_run(const char *params); +void pager_run(const char *params); extern Config *scale_conf; diff --git a/src/e_mod_pager.c b/src/e_mod_pager.c new file mode 100644 index 0000000..e4e1bbb --- /dev/null +++ b/src/e_mod_pager.c @@ -0,0 +1,926 @@ +#include +#include "e_mod_main.h" + +#define OFFSET 2.5 + +typedef struct _Item Item; + +struct _Item +{ + Evas_Object *o, *o_win; + E_Border *bd; + E_Desk *desk; + E_Comp_Win *cw; + double scale; + int alpha; + + double x; + double y; + double w; + double h; + + double mx; + double my; + + /* border origin (is moved when scale on another desk) */ + double bd_x; + double bd_y; + + /* current position to draw by compositor */ + int cur_x, cur_y, cur_w, cur_h; + + /* borders' desk distance to the current desk */ + int dx, dy; + + int layer; + + int mouse_down; +}; + +static Eina_Bool _pager_cb_mouse_down(void *data, int type, void *event); +static Eina_Bool _pager_cb_mouse_up(void *data, int type, void *event); +static Eina_Bool _pager_cb_mouse_move(void *data, int type, void *event); + +static void _pager_win_cb_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _pager_win_cb_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _pager_win_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _pager_win_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _pager_win_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _pager_win_cb_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _pager_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _pager_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _pager_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a); +static void _pager_win_cb_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above); + +static void _pager_win_new(Evas *e, E_Manager *man, E_Manager_Comp_Source *src); +static void _pager_win_del(Item *it); + +static void _pager_finish(); + + +static Ecore_X_Window input_win = 0; +static E_Msg_Handler *msg_handler = NULL; + +static Eina_List *items = NULL; +static Eina_List *desks = NULL; +static Eina_List *popups = NULL; + +static Eina_List *handlers = NULL; +static Ecore_Animator *scale_animator = NULL; +static Eina_Bool scale_state = EINA_FALSE; +static double start_time; +static E_Zone *zone = NULL; +static Item *background = NULL; +static Item *selected_item = NULL; +static E_Desk *current_desk = NULL; +static int min_x, min_y, max_x, max_y; +static double desk_w, desk_h; +static double zoom = 0.0; + +static void +_pager_place_desks(double scale) +{ + Evas_Object *o; + int x, y; + Eina_List *l = desks; + + int a = (1.0 - scale) * 255.0; + + for (y = 0; y < zone->desk_y_count; y++) + { + for (x = 0; x < zone->desk_x_count; x++) + { + o = eina_list_data_get(l); + + evas_object_move(o, + (scale * (x - current_desk->x) * zone->w) + + (1.0 - scale) * (min_x + x * desk_w), + (scale * (y - current_desk->y) * zone->h) + + (1.0 - scale) * (min_y + y * desk_h)); + evas_object_resize(o, + (scale * zone->w) + + (1.0 - scale) * (desk_w - OFFSET), + (scale * zone->h) + + (1.0 - scale) * (desk_h - OFFSET)); + + evas_object_color_set(o, a, a, a, a); + + l = eina_list_next(l); + } + } +} + +static void +_pager_place_windows(double scale) +{ + Eina_List *l; + Item *it; + + EINA_LIST_FOREACH(items, l, it) + { + it->cur_w = it->bd->w * scale + it->w * (1.0 - scale); + it->cur_h = it->bd->h * scale + it->h * (1.0 - scale); + it->cur_x = it->bd_x * scale + it->x * (1.0 - scale); + it->cur_y = it->bd_y * scale + it->y * (1.0 - scale); + + evas_object_move(it->o, it->cur_x, it->cur_y); + evas_object_resize(it->o, it->cur_w, it->cur_h); + } +} + +static Eina_Bool +_pager_redraw(void *data) +{ + Eina_List *l; + Item *it; + double scale, a, in, duration; + + duration = scale_conf->pager_duration; + scale = (ecore_time_get() - start_time) / duration; + + if (!scale_state) + scale = 1.0 - scale; + + if (scale > 1.0) scale = 1.0; + if (scale < 0.0) scale = 0.0; + + in = log(10) * scale; + in = 1.0 / exp(in*in); + + if (in > 1.0) in = 1.0; + if (in < 0.0) in = 0.0; + + _pager_place_desks(in); + _pager_place_windows(in); + + if (scale_conf->pager_fade_windows) + { + EINA_LIST_FOREACH(items, l, it) + { + if (it->desk != current_desk) + { + double ax = it->cur_x - it->x; + double ay = it->cur_y - it->y; + double bx = it->bd_x - it->x; + double by = it->bd_y - it->y; + + a = (1.0 - sqrt(ax*ax + ay*ay) / + sqrt(bx*bx + by*by)) * 220; + } + else + { + a = 220.0 + (35.0 * in); + } + + it->alpha = a; + evas_object_color_set(it->o_win, a, a, a, a); + } + } + + if (scale_conf->pager_fade_popups) + { + a = 255.0 * in; + + EINA_LIST_FOREACH(popups, l, it) + evas_object_color_set(it->o_win, a, a, a, a); + } + + if (scale_conf->pager_fade_desktop && background) + { + a = 255.0 * (0.5 + in/2.0); + + evas_object_color_set(background->o_win, a, a, a, 255); + } + + if (scale < 1.0 && scale > 0.0) + return 1; + + if (scale == 0.0) + _pager_finish(); + else + { + _pager_place_windows(0.0); + _pager_place_desks(0.0); + } + scale_animator = NULL; + return 0; +} + +static void +_pager_in() +{ + start_time = ecore_time_get(); + scale_state = EINA_TRUE; + + if (!scale_animator) + scale_animator = ecore_animator_add(_pager_redraw, NULL); +} +static void +_pager_out() +{ + double duration, now = ecore_time_get(); + + duration = scale_conf->pager_duration; + + if (now - start_time < duration) + start_time = now - (duration - (now - start_time)); + else + start_time = now; + + if (!scale_animator) + scale_animator = ecore_animator_add(_pager_redraw, NULL); + + /* if (selected_item) + * edje_object_signal_emit(selected_item->o, "mouse,out", "e"); */ + + scale_state = EINA_FALSE; +} + +static void +_pager_finish() +{ + Ecore_Event_Handler *handler; + Item *it; + E_Desk *desk; + Eina_List *l; + Evas_Object *o; + + e_grabinput_release(input_win, input_win); + ecore_x_window_free(input_win); + input_win = 0; + + desk = e_desk_current_get(zone); + + if (current_desk && (desk != current_desk)) + { + { + int tmp = e_config->desk_flip_animate_mode; + e_config->desk_flip_animate_mode = 0; + e_desk_show(current_desk); + e_config->desk_flip_animate_mode = tmp; + + EINA_LIST_FOREACH(items, l, it) + if (it->desk && (it->desk != it->bd->desk)) + e_border_desk_set(it->bd, it->desk); + } + } + + EINA_LIST_FREE(desks, o) + { + evas_object_del(o); + } + + EINA_LIST_FREE(items, it) + { + if (it->desk && (it->desk != it->bd->desk)) + e_border_desk_set(it->bd, it->desk); + + if (it->bd->desk != current_desk) + { + e_border_hide(it->bd, 2); + evas_object_hide(it->o_win); + } + + it->cur_x = it->bd->x; + it->cur_y = it->bd->y; + it->cur_w = it->bd->w; + it->cur_h = it->bd->h; + evas_object_move(it->o, it->bd->x, it->bd->y); + evas_object_resize(it->o, it->cw->w, it->cw->h); + + _pager_win_del(it); + } + + EINA_LIST_FREE(popups, it) + _pager_win_del(it); + + if (background) + _pager_win_del(background); + + /* XXX fix stacking */ + E_Comp_Win *cw, *prev = NULL; + Eina_List *list = (Eina_List *)e_manager_comp_src_list(e_manager_current_get()); + EINA_LIST_FOREACH(list, l, cw) + { + if (!cw->shobj) continue; + if (prev) evas_object_stack_above(cw->shobj, prev->shobj); + prev = cw; + } + + EINA_LIST_FREE(handlers, handler) + ecore_event_handler_del(handler); + + e_msg_handler_del(msg_handler); + msg_handler = NULL; + zone = NULL; + selected_item = NULL; + current_desk = NULL; + background = NULL; + + /* e_manager_comp_evas_update(e_manager_current_get()); */ +} + +static E_Desk * +_pager_desk_at_xy_get(double x, double y) +{ + x = ((x * zoom) - (min_x * zoom)) / (double)zone->w; + y = ((y * zoom) - (min_y * zoom)) / (double)zone->h; + if (x > zone->desk_x_count - 1) x = zone->desk_x_count - 1; + if (y > zone->desk_y_count - 1) y = zone->desk_y_count - 1; + + return e_desk_at_xy_get(zone, x, y); +} + +static void +_pager_desk_select(E_Desk *desk) +{ + Item *it; + Eina_List *l; + + current_desk = desk; + + EINA_LIST_FOREACH(items, l, it) + { + it->bd_x = it->bd->x + (it->desk->x - desk->x) * zone->w; + it->bd_y = it->bd->y + (it->desk->y - desk->y) * zone->h; + } +} + +static void +_pager_win_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + Evas_Event_Mouse_Down *ev = event_info; + + if ((ev->button == 2) || (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)) + { + selected_item = it; + + _pager_desk_select(it->desk); + + _pager_out(); + return; + } + else if (ev->button == 1) + { + e_border_raise(it->bd); + } + + it->mx = ev->canvas.x; + it->my = ev->canvas.y; + it->mouse_down = EINA_TRUE; +} + +static void +_pager_win_final_position_set(Item *it) +{ + /* move to desk position */ + it->x = it->desk->x * desk_w; + it->y = it->desk->y * desk_h; + /* center desks*/ + it->x += min_x + 1.0; /* XXX get offset from desk theme */ + it->y += min_y + 1.0; + /* move window to relative position on desk */ + it->x += (double)it->bd->x * (1.0 / zoom); + it->y += (double)it->bd->y * (1.0 / zoom); +} + +static void +_pager_win_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + int x = it->bd->x; + int y = it->bd->y; + + it->mouse_down = EINA_FALSE; + + if (x + it->bd->w > zone->w) x = zone->w - it->bd->w; + if (y + it->bd->h > zone->h) y = zone->h - it->bd->h; + if (x < 0) x = 0; + if (y < 0) y = 0; + + e_border_move(it->bd, x, y); + + _pager_win_final_position_set(it); + + it->cur_x = it->x; + it->cur_y = it->y; + + evas_object_move(it->o, it->cur_x, it->cur_y); +} + +static void +_pager_win_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Move *ev = event_info; + Item *it = data; + int x, y; + E_Desk *desk, *desk2; + + if (!it || !it->mouse_down) + return; + + if (abs(ev->cur.canvas.x - it->mx) + + abs(ev->cur.canvas.y - it->my) < 15) + return; + + x = it->x + (ev->cur.canvas.x - ev->prev.canvas.x); + y = it->y + (ev->cur.canvas.y - ev->prev.canvas.y); + + if (x < min_x) + x = min_x; + else if (x + it->w > max_x) + x = max_x - it->w; + + if (y < min_y) + y = min_y; + else if (y + it->h > max_y) + y = max_y - it->h; + + desk = _pager_desk_at_xy_get(ev->cur.canvas.x, ev->cur.canvas.y); + if (!desk) return; + + if ((!it->bd->fullscreen) && (!it->bd->maximized)) + { + it->x = x; + it->y = y; + it->cur_x = x; + it->cur_y = y; + + it->bd_x = ((it->x * zoom) - min_x * zoom); + it->bd_y = ((it->y * zoom) - min_y * zoom); + + x = (int)(it->bd_x) % zone->w; + y = (int)(it->bd_y) % zone->h; + + if ((desk2 = _pager_desk_at_xy_get(it->x, it->y))) + { + x += (desk2->x - desk->x) * zone->w; + y += (desk2->y - desk->y) * zone->h; + } + + e_border_move(it->bd, x, y); + + it->desk = desk; + } + else if (desk && (desk != it->desk)) + { + + it->desk = desk; + + _pager_win_final_position_set(it); + + it->cur_x = it->x; + it->cur_y = it->y; + } + + evas_object_move(it->o, it->cur_x, it->cur_y); +} + +static void +_pager_win_cb_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + + if (selected_item && (it != selected_item)) + { + edje_object_signal_emit(selected_item->o, "mouse,out", "e"); + selected_item = NULL; + } + + edje_object_signal_emit(it->o, "mouse,in", "e"); + selected_item = it; +} + +static void +_pager_win_cb_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + /* Item *it = data; */ + + if (selected_item) + { + edje_object_signal_emit(selected_item->o, "mouse,out", "e"); + selected_item = NULL; + } +} + +static void +_pager_win_cb_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + + if (it->bd) + items = eina_list_remove(items, it); + else + popups = eina_list_remove(popups, it); + + _pager_win_del(it); +} + +static void +_pager_win_cb_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above) +{ + Item *ot, *it = data; + Eina_List *l; + + EINA_LIST_FOREACH(items, l, ot) + if (ot->o_win == above) break; + + if (ot) + evas_object_stack_above(it->o, ot->o); +} + +static void +_pager_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + Item *it = data; + evas_object_move(obj, it->cur_x, it->cur_y); +} + +static void +_pager_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + Item *it = data; + evas_object_resize(obj, it->cur_w, it->cur_h); +} + +static void +_pager_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a) +{ + Item *it = data; + evas_object_color_set(obj, it->alpha, it->alpha, it->alpha, it->alpha); +} + +static void +_pager_win_del(Item *it) +{ + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_IN, + _pager_win_cb_mouse_in); + + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_OUT, + _pager_win_cb_mouse_out); + + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_DOWN, + _pager_win_cb_mouse_down); + + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_UP, + _pager_win_cb_mouse_up); + + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_MOVE, + _pager_win_cb_mouse_move); + + evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, + _pager_win_cb_delorig); + + evas_object_intercept_move_callback_del + (it->o_win, _pager_win_cb_intercept_move); + + evas_object_intercept_resize_callback_del + (it->o_win, _pager_win_cb_intercept_resize); + + evas_object_intercept_color_set_callback_del + (it->o_win, _pager_win_cb_intercept_color); + + evas_object_intercept_stack_above_callback_del + (it->o_win, _pager_win_cb_intercept_stack_above); + + if (it->bd) + { + it->alpha = 255; + evas_object_color_set(it->o_win, 255, 255, 255, 255); + edje_object_part_unswallow(it->o, it->o_win); + evas_object_stack_above(it->o_win, it->o); + e_object_unref(E_OBJECT(it->bd)); + } + + evas_object_del(it->o); + + E_FREE(it); +} + +static void +_pager_win_new(Evas *e, E_Manager *man, E_Manager_Comp_Source *src) +{ + Item *it; + E_Comp_Win *cw = (void*)src; + Evas_Object *o; + + if (!e_manager_comp_src_image_get(man, src)) + return; + + if (!cw->bd) + { + o = e_manager_comp_src_shadow_get(man, src); + if (!o) return; + + if (cw->win == zone->container->bg_win) + { + it = E_NEW(Item, 1); + it->o_win = o; + evas_object_event_callback_add + (it->o_win, EVAS_CALLBACK_DEL, + _pager_win_cb_delorig, it); + background = it; + } + else if (scale_conf->pager_fade_popups) + { + it = E_NEW(Item, 1); + it->o_win = o; + evas_object_event_callback_add + (it->o_win, EVAS_CALLBACK_DEL, + _pager_win_cb_delorig, it); + + popups = eina_list_append(popups, it); + } + return; + } + + if (cw->bd->zone != zone) + return; + + if (cw->bd->iconic) + return; + + it = E_NEW(Item, 1); + it->bd = cw->bd; + it->desk = it->bd->desk; + it->cw = cw; + it->alpha = 255.0; + e_object_ref(E_OBJECT(it->bd)); + + it->o_win = e_manager_comp_src_shadow_get(man, src); + it->o = edje_object_add(e); + if (!e_theme_edje_object_set(it->o, "base/theme/modules/scale", + "modules/scale/win")) + edje_object_file_set(it->o, scale_conf->theme_path, + "modules/scale/win"); + + evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, + _pager_win_cb_delorig, it); + + evas_object_intercept_move_callback_add + (it->o_win, _pager_win_cb_intercept_move, it); + + evas_object_intercept_resize_callback_add + (it->o_win, _pager_win_cb_intercept_resize, it); + + evas_object_intercept_color_set_callback_add + (it->o_win, _pager_win_cb_intercept_color, it); + + evas_object_intercept_stack_above_callback_add + (it->o_win, _pager_win_cb_intercept_stack_above, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_IN, + _pager_win_cb_mouse_in, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_OUT, + _pager_win_cb_mouse_out, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_DOWN, + _pager_win_cb_mouse_down, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_UP, + _pager_win_cb_mouse_up, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_MOVE, + _pager_win_cb_mouse_move, it); + + evas_object_stack_above(it->o, it->o_win); + edje_object_part_swallow(it->o, "e.swallow.win", it->o_win); + + evas_object_show(it->o); + + it->dx = it->desk->x - current_desk->x; + it->dy = it->desk->y - current_desk->y; + + it->x = it->bd->x + it->dx * zone->w; + it->y = it->bd->y + it->dy * zone->h; + + it->bd_x = it->x; + it->bd_y = it->y; + + it->cur_x = it->x; + it->cur_y = it->y; + it->cur_w = it->bd->w; + it->cur_h = it->bd->h; + + if (it->desk != current_desk) + { + e_border_show(it->bd); + evas_object_move(it->o, it->cur_x, it->cur_y); + + if (scale_conf->pager_fade_windows) + { + it->alpha = 0.0; + evas_object_color_set(it->o_win, 0, 0, 0, 0); + } + } + + _pager_win_final_position_set(it); + evas_object_color_set(it->o, 255, 255, 255, 255); + it->w = it->bd->w / zoom - OFFSET*2.0; + it->h = it->bd->h / zoom - OFFSET*2.0; + + items = eina_list_append(items, it); + + if (scale_state) + _pager_redraw(NULL); +} + +static Eina_Bool +_pager_cb_mouse_move(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Move *ev = event; + + evas_event_feed_mouse_move((Evas *) data, ev->x, ev->y, + ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_pager_cb_mouse_up(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + + evas_event_feed_mouse_up((Evas *)data, ev->buttons, + flags, ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_pager_cb_mouse_down(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + Item *it; + Eina_List *l; + + if (ev->window != input_win) + return ECORE_CALLBACK_PASS_ON; + + if (!scale_state) + return ECORE_CALLBACK_PASS_ON; + + EINA_LIST_FOREACH(items, l, it) + if (E_INTERSECTS(ev->x, ev->y, 1, 1, + it->x, it->y, it->w, it->h)) + break; + + if (!it) + { + E_Desk *desk = _pager_desk_at_xy_get(ev->x, ev->y); + if (desk) current_desk = desk; + + _pager_desk_select(current_desk); + + _pager_out(); + return ECORE_CALLBACK_PASS_ON; + } + + if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; + if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; + evas_event_feed_mouse_down((Evas *)data, ev->buttons, flags, + ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +static void +_pager_run(E_Manager *man) +{ + Eina_List *l; + E_Manager_Comp_Source *src; + Ecore_Event_Handler *h; + Evas *e; + + e = e_manager_comp_evas_get(man); + if (!e) return; + + zone = e_util_zone_current_get(man); + current_desk = e_desk_current_get(zone); + + input_win = ecore_x_window_input_new(zone->container->win, + 0, 0, 1, 1); + ecore_x_window_show(input_win); + + if (!e_grabinput_get(input_win, 0, input_win)) + { + ecore_x_window_free(input_win); + input_win = 0; + return; + } + + h = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, + _pager_cb_mouse_down, e); + handlers = eina_list_append(handlers, h); + + h = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, + _pager_cb_mouse_up, e); + handlers = eina_list_append(handlers, h); + + h = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, + _pager_cb_mouse_move, e); + handlers = eina_list_append(handlers, h); + + zoom = zone->desk_x_count; + if (zoom < zone->desk_y_count) + zoom = zone->desk_y_count; + + desk_w = (zone->w / zoom); + desk_h = (zone->h / zoom); + + min_x = OFFSET + (zoom - zone->desk_x_count) * desk_w / 2.0; + min_y = OFFSET + (zoom - zone->desk_y_count) * desk_h / 2.0; + + max_x = min_x + (zone->desk_x_count * desk_w); + max_y = min_y + (zone->desk_y_count * desk_h); + + EINA_LIST_FOREACH((Eina_List *)e_manager_comp_src_list(man), l, src) + _pager_win_new(e, man, src); + + if (background) + { + Evas_Object *o; + int i; + + for (i = 0; i < zone->desk_x_count * zone->desk_y_count; i++) + { + o = edje_object_add(e); + if (!e_theme_edje_object_set(o, "base/theme/modules/scale", + "modules/scale/desk")) + edje_object_file_set(o, scale_conf->theme_path, + "modules/scale/desk"); + evas_object_stack_above(o, background->o_win); + evas_object_show(o); + + desks = eina_list_append(desks, o); + } + _pager_place_desks(1.0); + } + + evas_event_feed_mouse_in(e, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_move(e, -1000000, -1000000, + ecore_x_current_time_get(), NULL); + _pager_in(); +} + +static void +_pager_handler(void *data, const char *name, const char *info, int val, + E_Object *obj, void *msgdata) +{ + E_Manager *man = (E_Manager *)obj; + E_Manager_Comp_Source *src = (E_Manager_Comp_Source *)msgdata; + Evas *e; + + /* DBG("handler... '%s' '%s'\n", name, info); */ + if (strcmp(name, "comp.manager")) return; + + e = e_manager_comp_evas_get(man); + if (!strcmp(info, "change.comp")) + { + if (!e) DBG("TTT: No comp manager\n"); + else DBG("TTT: comp canvas = %p\n", e); + } + else if (!strcmp(info, "resize.comp")) + { + DBG("%s: %p | %p\n", info, man, src); + } + else if (!strcmp(info, "add.src")) + { + /* DBG("%s: %p | %p\n", info, man, src); */ + _pager_win_new(e, man, src); + } + else if (!strcmp(info, "del.src")) + { + DBG("%s: %p | %p\n", info, man, src); + } + else if (!strcmp(info, "config.src")) + { + + DBG("%s: %p | %p\n", info, man, src); + } + /* else if (!strcmp(info, "visible.src")) + * { + * DBG("%s: %p | %p\n", info, man, src); + * } */ +} + +void +pager_run(const char *params) +{ + Eina_List *l; + E_Manager *man; + + msg_handler = e_msg_handler_add(_pager_handler, NULL); + + EINA_LIST_FOREACH(e_manager_list(), l, man) + { + Evas *e = e_manager_comp_evas_get(man); + if (e) _pager_run(man); + } +} + diff --git a/src/e_mod_scale.c b/src/e_mod_scale.c new file mode 100644 index 0000000..d142dd2 --- /dev/null +++ b/src/e_mod_scale.c @@ -0,0 +1,1601 @@ +#include +#include "e_mod_main.h" + +#define OFFSET 32 +#define PLACE_RUNS 10000 +#define GROW_RUNS 1000 +#define SHRINK_RUNS 2000 +#define GROW 6.0 + +typedef struct _Item Item; +typedef struct _Slot Slot; + +struct _Item +{ + Evas_Object *o, *o_win; + E_Border *bd; + E_Comp_Win *cw; + double scale; + int alpha; + + double x; + double y; + double w; + double h; + + double mx; + double my; + + /* border origin (is moved when scale on another desk) */ + double bd_x; + double bd_y; + + /* current position to draw by compositor */ + int cur_x, cur_y, cur_w, cur_h; + + /* borders' desk distance to the current desk */ + int dx, dy; + + int overlaps; + + int in_slots; +}; + +struct _Slot +{ + Eina_List *items; + int x, y, w, h; + Item *it; + double min; +}; + +static Eina_Bool _scale_cb_mouse_down(void *data, int type, void *event); +static Eina_Bool _scale_cb_mouse_up(void *data, int type, void *event); +static Eina_Bool _scale_cb_mouse_move(void *data, int type, void *event); + +static void _scale_win_cb_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _scale_win_cb_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _scale_win_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _scale_win_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info); + +static void _scale_win_cb_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _scale_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _scale_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _scale_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a); +static void _scale_win_cb_intercept_layer(void *data, Evas_Object *obj, int l); + +static void _scale_win_new(Evas *e, E_Manager *man, E_Manager_Comp_Source *src, E_Desk *desk); +static void _scale_win_del(Item *it); + +static void _scale_finish(void); +static void _scale_in(void); +static void _scale_out(void); + +static Ecore_X_Window input_win = 0; +static E_Msg_Handler *msg_handler = NULL; + +static Eina_List *items = NULL; +static Eina_List *popups = NULL; +static Eina_List *handlers = NULL; +static Ecore_Animator *scale_animator = NULL; +static Eina_Bool scale_state = EINA_FALSE; +static double start_time; +static E_Zone *zone = NULL; +static int max_x, max_y, min_x, min_y; +static int use_x, use_y, use_w, use_h; +static int max_width, max_height; +static int spacing; +static int step_count; +static Item *background = NULL; +static Item *selected_item = NULL; +static E_Desk *current_desk = NULL; +static int show_all_desks = EINA_FALSE; +static int send_to_desk = EINA_FALSE; + +static Eina_Bool +_scale_redraw(void *blah) +{ + Eina_List *l; + Item *it; + double scale, a, in, duration; + + if (show_all_desks) + duration = scale_conf->desks_duration; + else + duration = scale_conf->scale_duration; + + if (scale_state) + scale = (ecore_time_get() - start_time) / duration; + else + scale = 1.0 - (ecore_time_get() - start_time) / duration; + + if (scale > 1.0) scale = 1.0; + if (scale < 0.0) scale = 0.0; + + in = log(10) * scale; + in = 1.0 / exp(in*in); + + EINA_LIST_FOREACH(items, l, it) + { + it->cur_w = it->bd->w * in + it->w * (1.0 - in); + it->cur_h = it->bd->h * in + it->h * (1.0 - in); + it->cur_x = it->bd_x * in + it->x * (1.0 - in); + it->cur_y = it->bd_y * in + it->y * (1.0 - in); + + evas_object_move(it->o, it->cur_x, it->cur_y); + evas_object_resize(it->o, it->cur_w, it->cur_h); + + evas_object_move(it->o_win, it->cur_x, it->cur_y); + evas_object_resize(it->o_win, it->cur_w, it->cur_h); + + a = 255.0 * (1.0 - in); + evas_object_color_set(it->o, a, a, a, a); + + if (!scale_conf->fade_windows) + continue; + + if ((it->bd->desk != current_desk) && (selected_item != it)) + { + double ax = it->cur_x - it->x; + double ay = it->cur_y - it->y; + double bx = it->bd_x - it->x; + double by = it->bd_y - it->y; + + a = (1.0 - sqrt(ax*ax + ay*ay) / sqrt(bx*bx + by*by)) * 255; + } + else + { + a = 255.0; + } + + it->alpha = a; + evas_object_color_set(it->o_win, a, a, a, a); + } + + if (scale_conf->fade_popups) + { + a = 255.0 * in; + + EINA_LIST_FOREACH(popups, l, it) + evas_object_color_set(it->o_win, a, a, a, a); + } + + if (scale_conf->fade_desktop && background) + { + a = 255.0 * (0.5 + in/2.0); + + evas_object_color_set(background->o_win, a, a, a, 255); + } + + e_manager_comp_evas_update(e_manager_current_get()); + + if (scale < 1.0 && scale > 0.0) + return 1; + + if (scale == 0.0) + _scale_finish(); + + scale_animator = NULL; + return 0; +} + +static void +_scale_in() +{ + start_time = ecore_time_get(); + scale_state = EINA_TRUE; + + if (!scale_animator) + scale_animator = ecore_animator_add(_scale_redraw, NULL); +} + +static void +_scale_out() +{ + double duration, now = ecore_time_get(); + + if (show_all_desks) + duration = scale_conf->desks_duration; + else + duration = scale_conf->scale_duration; + + if (now - start_time < duration) + start_time = now - (duration - (now - start_time)); + else + start_time = now; + + if (!scale_animator) + scale_animator = ecore_animator_add(_scale_redraw, NULL); + + scale_state = EINA_FALSE; +} + +static void +_scale_finish() +{ + Ecore_Event_Handler *handler; + Item *it; + E_Desk *desk; + + e_grabinput_release(input_win, input_win); + ecore_x_window_free(input_win); + input_win = 0; + + desk = e_desk_current_get(zone); + + if (selected_item && selected_item->bd->desk != desk) + { + if (send_to_desk) + { + e_border_desk_set(selected_item->bd, desk); + } + else + { + int tmp = e_config->desk_flip_animate_mode; + desk = selected_item->bd->desk; + + e_config->desk_flip_animate_mode = 0; + e_desk_show(desk); + e_config->desk_flip_animate_mode = tmp; + } + } + + EINA_LIST_FREE(items, it) + { + if (it->bd->desk != desk) + { + e_border_hide(it->bd, 2); + evas_object_hide(it->o_win); + it->cur_x = it->bd->x; + it->cur_y = it->bd->y; + it->cur_w = it->bd->w; + it->cur_h = it->bd->h; + evas_object_move(it->o_win, it->bd->x, it->bd->y); + evas_object_resize(it->o_win, it->cw->w, it->cw->h); + } + _scale_win_del(it); + } + + EINA_LIST_FREE(popups, it) + _scale_win_del(it); + + if (scale_conf->fade_desktop && background) + _scale_win_del(background); + + EINA_LIST_FREE(handlers, handler) + ecore_event_handler_del(handler); + + e_msg_handler_del(msg_handler); + msg_handler = NULL; + zone = NULL; + selected_item = NULL; + current_desk = NULL; + send_to_desk = EINA_FALSE; + show_all_desks = EINA_FALSE; + + e_manager_comp_evas_update(e_manager_current_get()); +} + +static void +_scale_win_cb_mouse_in(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + + if (selected_item && (it != selected_item)) + { + edje_object_signal_emit(selected_item->o, "mouse,out", "e"); + selected_item = NULL; + } + + edje_object_signal_emit(it->o, "mouse,in", "e"); + selected_item = it; +} + +static void +_scale_win_cb_mouse_out(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + + if (selected_item && (it != selected_item)) + { + edje_object_signal_emit(selected_item->o, "mouse,out", "e"); + selected_item = NULL; + } +} + +static void +_scale_win_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *ot, *it = data; + Evas_Event_Mouse_Down *ev = event_info; + Eina_List *l; + + e_border_raise(it->bd); + + if (it->bd->desk == e_desk_current_get(it->bd->zone)) + { + _scale_out(); + return; + } + + if (ev->button == 1) + { + selected_item = it; + current_desk = it->bd->desk; + + EINA_LIST_FOREACH(items, l, ot) + { + if (ot->bd->desk == it->bd->desk) + { + ot->bd_x = ot->bd->x; + ot->bd_y = ot->bd->y; + } + else + { + if (ot->dx > it->dx) + ot->bd_x = ot->bd->x + zone->w; + else if (ot->dx < it->dx) + ot->bd_x = ot->bd->x - zone->w; + + if (ot->dy > it->dy) + ot->bd_y = ot->bd->y + zone->h; + else if (ot->dy < it->dy) + ot->bd_y = ot->bd->y - zone->h; + } + } + } + else if (ev->button == 3) + { + send_to_desk = EINA_TRUE; + selected_item = it; + it->bd_x = it->bd->x; + it->bd_y = it->bd->y; + } + + _scale_out(); +} + +static void +_scale_win_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + /* Item *it = data; */ +} + +static void +_scale_win_cb_delorig(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Item *it = data; + + if (it->bd) + { + _scale_out(); + items = eina_list_remove(items, it); + } + else + { + popups = eina_list_remove(popups, it); + } + + _scale_win_del(it); +} + +static void +_scale_win_cb_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + Item *it = data; + evas_object_move(obj, it->cur_x, it->cur_y); +} + +static void +_scale_win_cb_intercept_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + Item *it = data; + evas_object_resize(obj, it->cur_w, it->cur_h); +} + +static void +_scale_win_cb_intercept_color(void *data, Evas_Object *obj, int r, int g, int b, int a) +{ + Item *it = data; + evas_object_color_set(obj, it->alpha, it->alpha, it->alpha, it->alpha); +} + +static void +_scale_win_cb_intercept_layer(void *data, Evas_Object *obj, int l) +{ + Item *it = data; + evas_object_layer_set(it->o_win, l); + evas_object_stack_above(it->o, it->o_win); +} + +static void +_scale_win_del(Item *it) +{ + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_IN, _scale_win_cb_mouse_in); + evas_object_event_callback_del(it->o, EVAS_CALLBACK_MOUSE_OUT, _scale_win_cb_mouse_out); + evas_object_event_callback_del(it->o_win, EVAS_CALLBACK_DEL, _scale_win_cb_delorig); + evas_object_intercept_move_callback_del(it->o_win, _scale_win_cb_intercept_move); + evas_object_intercept_resize_callback_del(it->o_win, _scale_win_cb_intercept_resize); + evas_object_intercept_color_set_callback_del(it->o_win, _scale_win_cb_intercept_color); + evas_object_intercept_layer_set_callback_del(it->o_win, _scale_win_cb_intercept_layer); + evas_object_del(it->o); + + evas_object_color_set(it->o_win, 255, 255, 255, 255); + + if (it->bd) + e_object_unref(E_OBJECT(it->bd)); + + E_FREE(it); +} + +static void +_scale_win_new(Evas *e, E_Manager *man, E_Manager_Comp_Source *src, E_Desk *desk) +{ + Item *it; + + if (!e_manager_comp_src_image_get(man, src)) return; + + E_Comp_Win *cw = (void*)src; + + if (!cw->bd) + { + if (cw->win == zone->container->bg_win) + { + if (scale_conf->fade_desktop) + { + it = E_NEW(Item, 1); + it->o_win = e_manager_comp_src_shadow_get(man, src); + evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, + _scale_win_cb_delorig, it); + background = it; + } + } + else if (scale_conf->fade_popups) + { + it = E_NEW(Item, 1); + it->o_win = e_manager_comp_src_shadow_get(man, src); + evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, + _scale_win_cb_delorig, it); + + popups = eina_list_append(popups, it); + } + return; + } + + if (!cw->bd) return; + + if (cw->bd->zone != desk->zone) + return; + + if ((!show_all_desks) && (cw->bd->desk != desk)) + return; + + if (cw->bd->iconic) + return; + + it = E_NEW(Item, 1); + it->scale = 1.0; + + it->dx = cw->bd->desk->x - desk->x; + it->dy = cw->bd->desk->y - desk->y; + + it->x = cw->bd->x + it->dx * desk->zone->w; + it->y = cw->bd->y + it->dy * desk->zone->h; + it->w = cw->bd->w; + it->h = cw->bd->h; + + it->bd_x = it->x; + it->bd_y = it->y; + + it->cur_x = it->x; + it->cur_y = it->y; + it->cur_w = it->w; + it->cur_h = it->h; + + e_object_ref(E_OBJECT(cw->bd)); + it->bd = cw->bd; + it->cw = cw; + + it->o_win = e_manager_comp_src_shadow_get(man, src); + it->o = edje_object_add(e); + if (!e_theme_edje_object_set(it->o, "base/theme/modules/scale", + "modules/scale/win")) + edje_object_file_set(it->o, scale_conf->theme_path, "modules/scale/win"); + + evas_object_stack_above(it->o, it->o_win); + evas_object_event_callback_add(it->o_win, EVAS_CALLBACK_DEL, _scale_win_cb_delorig, it); + + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_IN, _scale_win_cb_mouse_in, it); + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_OUT, _scale_win_cb_mouse_out, it); + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_DOWN, _scale_win_cb_mouse_down, it); + evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_UP, _scale_win_cb_mouse_up, it); + + /* evas_object_event_callback_add(it->o, EVAS_CALLBACK_MOUSE_IN, _scale_win_cb_mouse_in, it); */ + /* edje_object_part_swallow(it->o, "e.swallow.win", it->o_win); */ + /* evas_object_clip_set(it->o_win, it->o); + * evas_object_move(it->o, it->x, it->y); */ + + evas_object_show(it->o); + + evas_object_intercept_move_callback_add(it->o_win, _scale_win_cb_intercept_move, it); + evas_object_intercept_resize_callback_add(it->o_win, _scale_win_cb_intercept_resize, it); + evas_object_intercept_color_set_callback_add(it->o_win, _scale_win_cb_intercept_color, it); + evas_object_intercept_layer_set_callback_add(it->o_win, _scale_win_cb_intercept_layer, it); + + if (it->bd->desk != desk) + { + e_border_show(it->bd); + evas_object_move(it->o_win, it->x, it->y); + } + + items = eina_list_append(items, it); +} + +static int +_scale_grow() +{ + Item *it, *ot; + Eina_List *l, *ll; + + int cont = 0; + int overlap; + double grow_l, grow_r, grow_d, grow_u; + + double mean = 0; + EINA_LIST_FOREACH(items, l, it) + { + it->scale = it->w / (double)it->bd->w; + mean += it->scale; + } + + mean /= (double) eina_list_count(items); + + EINA_LIST_FOREACH(items, l, it) + { + overlap = 0; + + if (it->scale > mean) + continue; + + if (it->w >= it->bd->w) + continue; + if (it->h >= it->bd->h) + continue; + + if (it->bd->w > it->bd->h) + { + grow_l = grow_r = GROW; + grow_u = grow_d = GROW * (double)it->bd->h/(double)it->bd->w; + } + else + { + grow_l = grow_r = GROW * (double)it->bd->w/(double)it->bd->h; + grow_u = grow_d = GROW; + } + + if (it->x - grow_l < min_x) + grow_l = 0; + if (it->y - grow_u < min_y) + grow_u = 0; + if (it->x + it->w + grow_r > max_x) + grow_r = 0; + if (it->y + it->h + grow_d > max_y) + grow_d = 0; + + if ((grow_l + grow_r) == 0) + continue; + if ((grow_u + grow_d) == 0) + continue; + + EINA_LIST_FOREACH(items, ll, ot) + { + if (it == ot) + continue; + if (grow_l && E_INTERSECTS(it->x - grow_l - spacing ,it->y, + it->w + spacing*2, it->h + spacing*2, + ot->x, ot->y, ot->w, ot->h)) + grow_l = 0; + + if (grow_r && E_INTERSECTS(it->x - spacing, it->y - spacing, + it->w + grow_r + spacing*2, it->h + spacing*2, + ot->x, ot->y, ot->w, ot->h)) + grow_r = 0; + + if ((grow_l == 0) && (grow_r == 0) && (overlap = 1)) + break; + + if (grow_u && E_INTERSECTS(it->x - spacing, it->y - spacing - grow_u, + it->w + spacing*2, it->h + spacing*2, + ot->x, ot->y, ot->w, ot->h)) + grow_u = 0; + + if (grow_d && E_INTERSECTS(it->x - spacing, it->y - spacing, + it->w + spacing*2, it->h + grow_d + spacing*2, + ot->x, ot->y, ot->w, ot->h)) + grow_d = 0; + + if ((grow_u == 0) && (grow_d == 0) && (overlap = 1)) + break; + } + + if (overlap) + continue; + + if (it->bd->w > it->bd->h) + { + if ((grow_u > 0) && (grow_d > 0)) + it->w += grow_l + grow_r; + else + it->w += MAX(grow_l, grow_r); + + it->h = it->w * (double)it->bd->h / (double)it->bd->w; + } + else + { + if ((grow_r > 0) && (grow_l > 0)) + it->h += grow_u + grow_d; + else + it->h += MAX(grow_u, grow_d); + + it->w = it->h * (double)it->bd->w / (double)it->bd->h; + } + it->x -= grow_l; + it->y -= grow_u; + + cont++; + } + + return cont; +} + +static void +_scale_displace(Item *it, Item *ot, int disp) +{ + /* cycle items with same center around to get even distribution. + dont try to understand this but these initial conditions + are important.. you can have up to 9 maximized windows. + if you can figure out more please tell me :) */ + + if (disp % 8 == 0) + { + // 1. + it->y -= 1; + it->x -= 1; + // 2. + ot->x += 1; + ot->y -= 1; + } + else if (disp % 8 == 1) + { + // 3. + ot->y += 1; + } + else if (disp % 8 == 2) + { + // 4. + ot->x -= 2; + ot->y += 2; + } + else if (disp % 8 == 3) + { + // 5. + ot->x += 2; + ot->y += 2; + } + else if (disp % 8 == 4) + { + // 6. + ot->x += 1; + ot->y += 1; + } + else if (disp % 8 == 5) + { + // 7. + ot->x -= 1; + ot->y += 1; + } + else if (disp % 8 == 6) + { + // 8. + ot->x -= 1; + ot->y -= 1; + } + else if (disp % 8 == 7) + { + ot->x += 1; + ot->y -= 1; + } +} + +static int +_scale_place(int offset) +{ + Item *it, *ot; + Eina_List *l, *ll; + int overlap = 0; + int outside = 0; + + EINA_LIST_FOREACH(items, l, it) + { + it->mx = it->x; + it->my = it->y; + } + + int disp = 0; + + EINA_LIST_FOREACH(items, l, it) + { + EINA_LIST_FOREACH(items, ll, ot) + { + int w = it->w; + int h = it->h; + + if (it == ot) + continue; + + if (!E_INTERSECTS(it->x - offset, it->y - offset, + it->w + offset*2, it->h + offset*2, + ot->x, ot->y, ot->w, ot->h)) + continue; + + overlap += 1; + + it->overlaps++; + + if (it->x < ot->x) + w += it->x - ot->x; + if (w < 0) w = 0; + + if (it->x + it->w > ot->x + ot->w) + w = ot->x + ot->w - it->x; + + if (it->y < ot->y) + h += it->y - ot->y; + if (h < 0) h = 0; + + if (it->y + it->h > ot->y + ot->h) + h = ot->y + ot->h - it->y; + + double dist_y = (it->y + it->h/2) - (ot->y + ot->h/2); + double dist_x = (it->x + it->w/2) - (ot->x + ot->w/2); + + if (dist_x == 0 && dist_y == 0) + { + _scale_displace(it, ot, disp); + disp++; + } + else if (w > h) + { + if (dist_y) + { + dist_y = (dist_y > 0 ? 2 : -2); + it->my += dist_y; + } + if (dist_x) + { + dist_x = (dist_x > 0 ? 1 : -1); + it->mx += dist_x; + } + } + else //if (w < h) + { + if (dist_y) + { + dist_y = (dist_y > 0 ? 1 : -1); + it->my += dist_y; + } + if (dist_x) + { + dist_x = (dist_x > 0 ? 2 : -2); + it->mx += dist_x; + } + } + } + } + + EINA_LIST_FOREACH(items, l, it) + { + it->x = it->mx; + it->y = it->my; + + if (it->x < min_x) + { + outside = 1; + it->x = min_x; + } + + if (it->y < min_y) + { + outside = 1; + it->y = min_y; + } + + if (it->x + it->w > max_x) + { + outside = 1; + it->x = max_x - it->w; + } + + if (it->y + it->h > max_y) + { + outside = 1; + it->y = max_y - it->h; + } + } + + if (!(overlap || outside)) + return 0; + + if (outside && (step_count++ > 50)) + { + double zone_diag = sqrt(zone->w * zone->h); + double sw, sh; + step_count = 0; + EINA_LIST_FOREACH(items, l, it) + { + if (!it->overlaps) + continue; + + if (it->scale <= 0.005) + continue; + + it->scale -= it->scale * + (0.001 + (sqrt(it->bd->w * it->bd->h) / zone_diag) / 50.0); + + sw = (double)it->bd->w * it->scale; + sh = (double)it->bd->h * it->scale; + it->x += (it->w - sw)/2.0; + it->y += (it->h - sh)/2.0; + it->w = sw; + it->h = sh; + + it->overlaps = 0; + } + return 1; + } + + return overlap || outside; +} + +static int +_scale_shrink() +{ + Eina_List *l, *ll; + Item *it, *ot; + int shrunk = 0; + double move_x; + double move_y; + + EINA_LIST_REVERSE_FOREACH(items, l, it) + { + if (show_all_desks) + { + move_x = ((it->x + it->w/2.0) - zone->w/2.0) / 5.0; + move_y = ((it->y + it->h/2.0) - zone->h/2.0) / 5.0; + } + else + { + move_x = ((it->x + it->w/2.0) - + (double)(it->bd->x + it->bd->w/2.0)) / 10.0; + move_y = ((it->y + it->h/2.0) - + (double)(it->bd->y + it->bd->h/2.0)) / 10.0; + } + + if (!(move_y || move_x)) + continue; + + EINA_LIST_FOREACH(items, ll, ot) + { + if (it == ot) continue; + + while(move_x) + { + if (E_INTERSECTS(it->x - move_x, it->y, it->w, it->h, + ot->x - spacing, ot->y - spacing, + ot->w + spacing*2, ot->h + spacing*2)) + move_x = move_x / 2.0; + else break; + } + + while(move_y) + { + if (E_INTERSECTS(it->x, it->y - move_y, it->w, it->h, + ot->x - spacing, ot->y - spacing, + ot->w + spacing*2, ot->h + spacing*2)) + move_y = move_y / 2.0; + else break; + } + + if (!(move_y || move_x)) break; + } + + it->x -= move_x; + it->y -= move_y; + + if (move_y > 1 || move_x > 1) + shrunk++; + } + + return shrunk; +} + + +/* TODO add slot item an calc distance only once */ +static Slot *cur_slot = NULL; + +static double +_slot_dist(const Item *it, const Slot *slot) +{ + double dx = it->x - slot->x; + double dy = it->y - slot->y; + double dw = (it->x + it->w) - (slot->x + slot->w); + double dh = (it->y + it->h) - (slot->y + slot->h); + + return (sqrt(dx*dx + dy*dy + dw*dw + dh*dh)); +} + +static int +_cb_sort_nearest(const void *d1, const void *d2) +{ + const Item *it1 = d1; + const Item *it2 = d2; + + return (_slot_dist(it1, cur_slot) < _slot_dist(it2, cur_slot)) ? -1 : 1; +} + +static int +_scale_place_slotted() +{ + Eina_List *l, *ll, *slots = NULL; + Slot *slot, *slot2; + Item *it; + int rows, cols, cnt, x, y, w, h, start; + int fast = 0; + int cont = 0, i = 0; + double min_x, max_x, min_y, max_y; + + cnt = eina_list_count(items); + + rows = sqrt(cnt); + cols = cnt/rows; + + if (cols*rows < cnt) + cols += 1; + + if (cnt <= 2) + { + cols = 2; + rows = 1; + } + else if (cnt <= 4) + { + cols = 2; + rows = 2; + } + else if (cnt <= 6) + { + cols = 3; + rows = 2; + } + else if (cnt <= 8) + { + cols = 3; + rows = 3; + } + + DBG("%d rows, %d cols -- cnt %d\n", rows, cols, cnt); + + max_x = max_y = 0; + min_x = min_y = 100000; + + EINA_LIST_FOREACH(items, l, it) + { + if (it->x < min_x) min_x = it->x; + if (it->y < min_y) min_y = it->y; + if (it->x + it->w > max_x) max_x = it->x + it->w; + if (it->y + it->h > max_y) max_y = it->y + it->h; + } + + w = (max_x - min_x) / cols; + h = (max_y - min_y) / rows; + l = items; + + for (y = 0; y < rows; y++) + { + for (x = 0; x < cols; x++) + { + if (fast && !l) break; + + slot = E_NEW(Slot, 1); + slot->x = min_x + x * w; + slot->y = min_y + y * h; + slot->w = w; + slot->h = h; + + if (fast) + { + slot->it = eina_list_data_get(l); + if (l) l = l->next; + } + else + { + cur_slot = slot; + slot->items = eina_list_clone(items); + slot->items = eina_list_sort(slot->items, cnt, _cb_sort_nearest); + slot->it = eina_list_data_get(slot->items); + slot->items = eina_list_remove_list(slot->items, slot->items); + slot->min = _slot_dist(slot->it, slot); + } + + slots = eina_list_append(slots, slot); + + DBG("add slot: %dx%d, \t%f -> %d:%d\n", slot->x, slot->y, slot->min, + (int)(slot->it->x), (int)(slot->it->y)); + } + } + + if (!fast) + { + cont = 1; + EINA_LIST_FOREACH(items, l, it) + it->in_slots = cols * rows; + } + + for (i = 0; (i < PLACE_RUNS) && cont; i++) + { + cont = 0; + EINA_LIST_FOREACH(slots, l, slot) + { + EINA_LIST_FOREACH(slots, ll, slot2) + { + if (slot == slot2) + continue; + + if (slot->it != slot2->it) + continue; + + Item *it1 = eina_list_data_get(slot->items); + Item *it2 = eina_list_data_get(slot2->items); + if (!it1 || !it2) + continue; + + double d1 = _slot_dist(it1, slot); + double d2 = _slot_dist(it2, slot2); + + cont = 1; + + DBG("%dx%d - compare:\n\ts1: %dx%d (%dx%d:%f),\n\ts2 %dx%d (%dx%d:%f)\n", + (int)slot->it->x, (int)slot->it->y, + slot->x, slot->y, (int)it1->x, (int)it1->y, d1, + slot2->x, slot2->y, (int)it2->x, (int)it2->y, d2); + + if (slot->it->in_slots > 1 && slot->min + d1 >= slot2->min + d2) + { + slot->it->in_slots--; + slot->it = it1; + slot->min = d1; + slot->items = eina_list_remove_list(slot->items, slot->items); + break; + } + } + } + } + + cont = 1; + + for (i = 0; (i < PLACE_RUNS) && cont; i++) + { + cont = 0; + EINA_LIST_FOREACH(slots, l, slot) + { + EINA_LIST_FOREACH(l->next, ll, slot2) + { + double d1, d2; + + d1 = _slot_dist(slot->it, slot) + _slot_dist(slot2->it, slot2); + d2 = _slot_dist(slot->it, slot2) + _slot_dist(slot2->it, slot); + if (d1 > d2) + { + it = slot->it; + slot->it = slot2->it; + slot2->it = it; + cont = 1; + } + } + } + } + + EINA_LIST_FOREACH(slots, l, slot) + { + if (!slot->it) + continue; + + EINA_LIST_FOREACH(slots, ll, slot2) + { + if (slot == slot2) + continue; + + if (slot->it != slot2->it) + continue; + + if (_slot_dist(slot->it, slot) > _slot_dist(slot2->it, slot2)) + slot->it = NULL; + else + slot2->it = NULL; + } + } + + h = (zone->h - spacing) / rows; + w = (zone->w - spacing) / cols; + + for (y = 0, l = slots; l && (y < rows); y++) + { + ll = l; + for (x = 0, cnt = 0; l && x < cols; x++, l = eina_list_next(l)) + { + slot = eina_list_data_get(l); + if (slot->it) cnt++; + } + + if (cnt < cols) + start = (w * (cols - cnt))/2.0; + else + start = spacing/2.0; + + for (x = 0; ll && x < cnt; ll = eina_list_next(ll)) + { + slot = eina_list_data_get(ll); + if (!slot->it) continue; + + slot->x = start + x * w; + slot->y = y * h; + slot->w = w; + slot->h = h; + x++; + } + } + + EINA_LIST_FOREACH(slots, l, slot) + { + if (slot->it) + { + it = slot->it; + + if (it->w > slot->w - spacing) + { + it->w = slot->w - spacing; + it->h = it->w * (double)it->bd->h / (double)it->bd->w; + } + if (it->h > slot->h - spacing) + { + it->h = slot->h - spacing; + it->w = it->h * (double)it->bd->w / (double)it->bd->h; + } + it->x = slot->x + (slot->w - it->w)/2.0; + it->y = slot->y + (slot->h - it->h)/2.0; + + DBG("place: %d:%d %dx%d -> %d:%d %dx%d\n", + (int)it->bd_x, (int)it->bd_y, (int)it->bd->w, (int)it->bd->h, + (int)it->x, (int)it->y, (int)it->w, (int)it->h); + } + + EINA_LIST_FREE(slot->items, it); + E_FREE(slot); + } + + return 1; +} + + +static int +_cb_sort_center(const void *d1, const void *d2) +{ + const Item *it1 = d1; + const Item *it2 = d2; + + double dx1 = ((it1->x + it1->w/2.0) - (double)(max_width/2)); + double dy1 = ((it1->y + it1->h/2.0) - (double)(max_height/2)); + + double dx2 = ((it2->x + it2->w/2.0) - (double)(max_width/2)); + double dy2 = ((it2->y + it2->h/2.0) - (double)(max_height/2)); + + return (sqrt(dx1*dx1 + dy1*dy1) > sqrt(dx2*dx2 + dy2*dy2)) ? -1 : 1; +} + +static void +_scale_place_natural() +{ + Eina_List *l; + int offset, i = 0; + Item *it; + + max_width = zone->w; + max_height = zone->h; + + if (show_all_desks) + { + max_width = zone->h * zone->desk_x_count; + max_height = zone->w * zone->desk_y_count; + } + + items = eina_list_sort(items, eina_list_count(items), _cb_sort_center); + + offset = spacing; + + if (scale_conf->grow && (spacing < OFFSET)) + offset = OFFSET; + if (scale_conf->tight && (spacing < OFFSET)) + offset = OFFSET; + + step_count = 0; + + while ((i++ < PLACE_RUNS) && + (_scale_place(offset) || + (min_x < use_x) || + (min_y < use_y) || + (max_x > use_w) || + (max_y > use_h))) + { + /* shrink region to visible region */ + if (min_x < use_x) min_x += 2; + if (min_y < use_y) min_y += 2; + if (min_x > use_x) min_x = use_x; + if (min_y > use_y) min_y = use_y; + + if (max_x > use_w) max_x -= 2; + if (max_y > use_h) max_y -= 2; + if (max_x < use_w) max_x = use_w; + if (max_y < use_h) max_y = use_h; + + if (!show_all_desks) + continue; + + /* move other desks windows into visible region */ + EINA_LIST_FOREACH(items, l, it) + { + if ((min_x < use_x) && (it->dx < 0) && it->x < 0) it->x += 4.0; + if ((min_y < use_y) && (it->dy < 0) && it->y < 0) it->y += 4.0; + + if ((max_x > use_w) && (it->dx > 0) && it->x > zone->w) it->x -= 4.0; + if ((max_y > use_h) && (it->dy > 0) && it->y > zone->h) it->y -= 4.0; + } + } +} + + + +static void +_scale_run(E_Manager *man) +{ + Eina_List *l; + E_Manager_Comp_Source *src; + Evas *e; + int i; + Item *it; + + e = e_manager_comp_evas_get(man); + if (!e) return; + + zone = e_util_zone_current_get(e_manager_current_get()); + current_desk = e_desk_current_get(zone); + + start_time = ecore_time_get(); + + input_win = ecore_x_window_input_new(zone->container->win, 0, 0, 1, 1); + ecore_x_window_show(input_win); + if (!e_grabinput_get(input_win, 0, input_win)) + { + ecore_x_window_free(input_win); + input_win = 0; + return; + } + + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_BUTTON_DOWN, _scale_cb_mouse_down, e)); + + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_BUTTON_UP, _scale_cb_mouse_up, e)); + + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_MOVE, _scale_cb_mouse_move, e)); + + EINA_LIST_FOREACH((Eina_List *)e_manager_comp_src_list(man), l, src) + { + _scale_win_new(e, man, src, current_desk); + } + + if ((eina_list_count(items) < 2) && (!show_all_desks)) + { + _scale_finish(); + return; + } + + if (show_all_desks) + spacing = scale_conf->desks_spacing; + else + spacing = scale_conf->spacing; + + if (!scale_conf->fade_popups) + { + e_zone_useful_geometry_get(zone, &use_x, &use_y, &use_w, &use_h); + use_w += use_x - spacing*2; + use_h += use_y - spacing*2; + use_x += spacing; + use_y += spacing; + } + else + { + use_w = zone->w - spacing; + use_h = zone->h - spacing; + use_x = use_y = spacing; + } + + min_x = -zone->w * zone->desk_x_current; + min_y = -zone->h * zone->desk_y_current; + max_x = zone->w + zone->w * ((zone->desk_x_count - 1) - zone->desk_x_current); + max_y = zone->h + zone->h * ((zone->desk_y_count - 1) - zone->desk_y_current); + + /* scale all windows down to be next to each other on one zone */ + if (show_all_desks) + { + if (scale_conf->desks_layout_mode) + _scale_place_slotted(); + else + _scale_place_natural(); + } + else + { + if (scale_conf->layout_mode) + _scale_place_slotted(); + else + _scale_place_natural(); + } + + min_x = use_x; + min_y = use_y; + max_x = use_w; + max_y = use_h; + + if ((scale_conf->grow && !show_all_desks) || + (scale_conf->desks_grow && show_all_desks)) + { + i = 0; + while (i++ < GROW_RUNS && _scale_grow()); + DBG("grow %d", i); + } + + if ((scale_conf->tight && !show_all_desks) || + (scale_conf->desks_tight && show_all_desks)) + { + items = eina_list_sort(items, eina_list_count(items), _cb_sort_center); + i = 0; + while (i++ < SHRINK_RUNS && _scale_shrink()); + DBG("shrunk %d", i); + + /* if (scale_conf->grow) + * { + * i = 0; + * while (i++ < GROW_RUNS && _scale_grow()); + * DBG("grow %d", i); + * } */ + } + + if (show_all_desks) + { + /* center and move windows near visible desk + * to make the sliding smoother */ + + min_x = zone->w; + min_y = zone->h; + max_x = 0; + max_y = 0; + + EINA_LIST_FOREACH(items, l, it) + { + if (it->x < min_x) min_x = it->x; + if (it->y < min_y) min_y = it->y; + if (it->x + it->w > max_x) max_x = it->x + it->w; + if (it->y + it->h > max_y) max_y = it->y + it->h; + } + + EINA_LIST_FOREACH(items, l, it) + { + it->x = (it->x - min_x) + use_x + ((use_w - use_x) - (max_x - min_x))/2.0; + it->y = (it->y - min_y) + use_y + ((use_h - use_y) - (max_y - min_y))/2.0; + + if (it->dx > 0) it->bd_x = zone->w + it->bd->x/4; + if (it->dy > 0) it->bd_y = zone->h + it->bd->y/4; + if (it->dx < 0) it->bd_x = -(zone->w - it->bd->x)/4; + if (it->dy < 0) it->bd_y = -(zone->h + it->bd->y)/4; + } + } + + DBG("time: %f\n", ecore_time_get() - start_time); + + evas_event_feed_mouse_in(e, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_move(e, -1000000, -1000000, + ecore_x_current_time_get(), NULL); + + _scale_in(); +} + + +static Eina_Bool +_scale_cb_mouse_move(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Move *ev = event; + + evas_event_feed_mouse_move((Evas *) data, ev->x, ev->y, ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_scale_cb_mouse_down(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + Eina_List *l; + Item *it; + + EINA_LIST_FOREACH(items, l, it) + if (E_INTERSECTS(ev->x, ev->y, 1, 1, it->x, it->y, it->w, it->h)) + break; + + if (!it) + { + _scale_out(); + return ECORE_CALLBACK_PASS_ON; + } + + if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; + if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; + evas_event_feed_mouse_down((Evas *)data, ev->buttons, flags, ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_scale_cb_mouse_up(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev = event; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + + evas_event_feed_mouse_up((Evas *)data, ev->buttons, flags, ev->timestamp, NULL); + + return ECORE_CALLBACK_PASS_ON; +} + +/* static Eina_Bool + * _scale_cb_mouse_down(void *data, int type, void *event) + * { + * Ecore_Event_Mouse_Button *ev = event; + * Item *it, *ot; + * Eina_List *l; + * + * if (ev->window != input_win) + * return ECORE_CALLBACK_PASS_ON; + * + * if (!scale_state) + * return ECORE_CALLBACK_PASS_ON; + * + * EINA_LIST_FOREACH(items, l, it) + * if (E_INTERSECTS(ev->x, ev->y, 1, 1, it->x, it->y, it->w, it->h)) + * break; + * + * if (!it) + * { + * _scale_out(); + * return ECORE_CALLBACK_PASS_ON; + * } + * + * e_border_raise(it->bd); + * + * + * if (it->bd->desk != e_desk_current_get(it->bd->zone)) + * { + * if (ev->buttons == 1) + * { + * selected_item = it; + * current_desk = it->bd->desk; + * + * EINA_LIST_FOREACH(items, l, ot) + * { + * if (ot->bd->desk == it->bd->desk) + * { + * ot->bd_x = ot->bd->x; + * ot->bd_y = ot->bd->y; + * } + * else + * { + * if (ot->dx > it->dx) + * ot->bd_x = ot->bd->x + zone->w; + * else if (ot->dx < it->dx) + * ot->bd_x = ot->bd->x - zone->w; + * + * if (ot->dy > it->dy) + * ot->bd_y = ot->bd->y + zone->h; + * else if (ot->dy < it->dy) + * ot->bd_y = ot->bd->y - zone->h; + * } + * } + * } + * else if (ev->buttons == 3) + * { + * send_to_desk = EINA_TRUE; + * selected_item = it; + * it->bd_x = it->bd->x; + * it->bd_y = it->bd->y; + * } + * } + * + * _scale_out(); + * + * return ECORE_CALLBACK_PASS_ON; + * } */ + +static void +_scale_handler(void *data, const char *name, const char *info, int val, + E_Object *obj, void *msgdata) +{ + E_Manager *man = (E_Manager *)obj; + E_Manager_Comp_Source *src = (E_Manager_Comp_Source *)msgdata; + Evas *e; + + /* DBG("handler... '%s' '%s'\n", name, info); */ + if (strcmp(name, "comp.manager")) return; + + e = e_manager_comp_evas_get(man); + if (!strcmp(info, "change.comp")) + { + if (!e) DBG("TTT: No comp manager\n"); + else DBG("TTT: comp canvas = %p\n", e); + } + else if (!strcmp(info, "resize.comp")) + { + DBG("%s: %p | %p\n", info, man, src); + } + else if (!strcmp(info, "add.src")) + { + /* DBG("%s: %p | %p\n", info, man, src); */ + _scale_win_new(e, man, src, e_desk_current_get(e_util_zone_current_get(man))); + + } + else if (!strcmp(info, "del.src")) + { + DBG("%s: %p | %p\n", info, man, src); + } + else if (!strcmp(info, "config.src")) + { + + DBG("%s: %p | %p\n", info, man, src); + } + /* else if (!strcmp(info, "visible.src")) + * { + * DBG("%s: %p | %p\n", info, man, src); + * } */ +} + +void +scale_run(const char *params) +{ + Eina_List *l; + E_Manager *man; + + msg_handler = e_msg_handler_add(_scale_handler, NULL); + + if (!strcmp(params, "go_scale_all")) + show_all_desks = EINA_TRUE; + else + show_all_desks = EINA_FALSE; + + EINA_LIST_FOREACH(e_manager_list(), l, man) + { + Evas *e = e_manager_comp_evas_get(man); + if (e) _scale_run(man); + } +} +