From 38e3969e72c88c4cf438c7537c37a72cae7344a4 Mon Sep 17 00:00:00 2001 From: Yossi Kantor Date: Tue, 17 Sep 2013 08:58:05 +0200 Subject: [PATCH] e_fm custom and regular mode icon selection --- src/bin/e_fm.c | 386 ++++++++++++++++++++----------------------------- 1 file changed, 153 insertions(+), 233 deletions(-) diff --git a/src/bin/e_fm.c b/src/bin/e_fm.c index 2a2c2db12..cf9cac625 100644 --- a/src/bin/e_fm.c +++ b/src/bin/e_fm.c @@ -88,6 +88,7 @@ struct _E_Fm2_Smart_Data } new_file; E_Fm2_Icon *last_selected; + E_Fm2_Icon *range_selected; Eina_List *selected_icons; Eina_List *icons_place; Eina_List *queue; @@ -310,6 +311,7 @@ static void _e_fm2_icon_sel_prev(Evas_Object *obj, Eina_Bool add); static void _e_fm2_icon_sel_next(Evas_Object *obj, Eina_Bool add); static void _e_fm2_icon_sel_down(Evas_Object *obj, Eina_Bool add); static void _e_fm2_icon_sel_up(Evas_Object *obj, Eina_Bool add); +static void _e_fm2_icon_range_select(E_Fm2_Icon *ic); static void _e_fm2_typebuf_show(Evas_Object *obj); static void _e_fm2_typebuf_hide(Evas_Object *obj); @@ -5034,6 +5036,7 @@ _e_fm2_icon_select(E_Fm2_Icon *ic) prev = eina_list_last_data_get(ic->sd->selected_icons); if (prev) prev->last_selected = EINA_FALSE; ic->selected = EINA_TRUE; + ic->sd->range_selected = NULL; ic->sd->last_selected = ic; ic->sd->selected_icons = eina_list_append(ic->sd->selected_icons, ic); ic->last_selected = EINA_TRUE; @@ -5061,6 +5064,7 @@ _e_fm2_icon_deselect(E_Fm2_Icon *ic) if (!ic->selected) return; ic->selected = EINA_FALSE; ic->last_selected = EINA_FALSE; + ic->sd->range_selected = NULL; if (ic->sd->last_selected == ic) ic->sd->last_selected = NULL; ic->sd->selected_icons = eina_list_remove(ic->sd->selected_icons, ic); ic->selected_time = 0.0; @@ -5414,10 +5418,10 @@ _e_fm2_icon_next_find(Evas_Object *obj, int next, int (*match_func)(E_Fm2_Icon * { E_Fm2_Smart_Data *sd; Eina_List *l; - E_Fm2_Icon *ic, *ic_next; + E_Fm2_Icon *ic, *ic_next, *ic_vert, *ic_horz; char view_mode; int x = 0, y = 0, custom = 0; - int dist, min = 65535; + int dist = 0, min_horz = 65535, min_vert = 65535; sd = evas_object_smart_data_get(obj); if (!sd) return NULL; @@ -5428,106 +5432,64 @@ _e_fm2_icon_next_find(Evas_Object *obj, int next, int (*match_func)(E_Fm2_Icon * (view_mode == E_FM2_VIEW_MODE_CUSTOM_GRID_ICONS) || (view_mode == E_FM2_VIEW_MODE_CUSTOM_ICONS)) custom = 1; - + + l = eina_list_data_find_list(sd->icons, (sd->range_selected) ? + sd->range_selected : + sd->last_selected); + + if (!l) return eina_list_data_get(sd->icons); + + if (!next) return eina_list_data_get(l); + ic_next = NULL; - /* find selected item / current position */ - EINA_LIST_FOREACH(sd->icons, l, ic) + ic_vert = NULL; + ic_horz = NULL; + + if (custom || match_func) { - if (ic->selected) + ic = eina_list_data_get(l); + x = ic->x; + y = ic->y; + + EINA_LIST_FOREACH(sd->icons, l, ic) { - if (!custom && !match_func) + if (match_func && !match_func(ic, data)) continue; + + int dx = (ic->x - x); + int dy = (ic->y - y); + int sgnx = (dx) ? dx / abs(dx) : 0; + int sgny = (dy) ? dy / abs(dy) : 0; + + if ((next == sgnx) && (abs(dx) >= abs(dy)) && ((sgny*sgnx) >= 0)) { - ic_next = ic; + dist = abs(dy) + abs(dx); + if (dist < min_horz) + { + min_horz = dist; + ic_horz = ic; + } } - else + + if (!ic_horz && (next == sgny)) { - x = ic->x; - y = ic->y; + dist = abs(dy) + ic->x * next; + if (dist < min_vert) + { + min_vert = dist; + ic_vert = ic; + } } - break; } + ic_next = (ic_horz) ? ic_horz : ic_vert; } - if (next && (custom || match_func)) - { - /* find next item in custom grid, or list/grid when match - func is given */ - if (next == 1) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if ((ic->x > x) && - (custom ? (ic->y >= y) : (ic->y == y)) && - (!match_func || match_func(ic, data))) - { - dist = 2 * (ic->y - y) + (ic->x - x); - if (dist < min) - { - min = dist; - ic_next = ic; - } - } - } - /* no next item was found in row go down and begin */ - if (!ic_next) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if ((ic->y > y) && (!match_func || match_func(ic, data))) - { - dist = 2 * (abs(ic->y - y)) + ic->x; - if (dist < min) - { - min = dist; - ic_next = ic; - } - } - } - } - } - /* find previous item */ - else if (next == -1) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if ((ic->x < x) && - (custom ? (ic->y <= y) : (ic->y == y)) && - (!match_func || match_func(ic, data))) - { - dist = 2 * (y - ic->y) + (x - ic->x); - if (dist < min) - { - min = dist; - ic_next = ic; - } - } - } - /* no prev item was found in row go to end and up */ - if (!ic_next) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if ((ic->y < y) && (!match_func || match_func(ic, data))) - { - dist = 2 * (abs(ic->y - y)) - ic->x; - if (dist < min) - { - min = dist; - ic_next = ic; - } - } - } - } - } - } - /* not custom, items are arranged in list order */ - else if (ic_next) + else { if (next == 1) { if (!eina_list_next(l)) return NULL; ic_next = eina_list_data_get(eina_list_next(l)); } - if (next == -1) + else if (next == -1) { if (!eina_list_prev(l)) return NULL; ic_next = eina_list_data_get(eina_list_prev(l)); @@ -5544,16 +5506,19 @@ _e_fm2_icon_sel_prev(Evas_Object *obj, Eina_Bool add) ic_prev = _e_fm2_icon_next_find(obj, -1, NULL, NULL); - if (!ic_prev) - { - /* FIXME this is not the bottomright item for custom grid */ - _e_fm2_icon_sel_last(obj, add); - return; - } + if (!ic_prev) return; + if ((!add) || ic_prev->sd->config->selection.single) - _e_fm2_icon_desel_any(obj); - _e_fm2_icon_select(ic_prev); - evas_object_smart_callback_call(obj, "selection_change", NULL); /*XXX sd->obj*/ + { + _e_fm2_icon_desel_any(obj); + _e_fm2_icon_select(ic_prev); + } + else + { + _e_fm2_icon_range_select(ic_prev); + } + + evas_object_smart_callback_call(obj, "selection_change", NULL); _e_fm2_icon_make_visible(ic_prev); } @@ -5563,15 +5528,18 @@ _e_fm2_icon_sel_next(Evas_Object *obj, Eina_Bool add) E_Fm2_Icon *ic_next; ic_next = _e_fm2_icon_next_find(obj, 1, NULL, NULL); - if (!ic_next) - { - /* FIXME this is not the topleft item for custom grid */ - _e_fm2_icon_sel_first(obj, add); - return; - } + + if (!ic_next) return; + if ((!add) || ic_next->sd->config->selection.single) - _e_fm2_icon_desel_any(obj); - _e_fm2_icon_select(ic_next); + { + _e_fm2_icon_desel_any(obj); + _e_fm2_icon_select(ic_next); + } + else + { + _e_fm2_icon_range_select(ic_next); + } evas_object_smart_callback_call(obj, "selection_change", NULL); _e_fm2_icon_make_visible(ic_next); } @@ -5581,72 +5549,41 @@ _e_fm2_icon_sel_down(Evas_Object *obj, Eina_Bool add) { E_Fm2_Smart_Data *sd; Eina_List *l; - E_Fm2_Icon *ic, *ic_down; - int found, x = -1, y = -1, custom = 0; + E_Fm2_Icon *ic, *ic2, *ic_down; int dist, min = 65535; - char view_mode; sd = evas_object_smart_data_get(obj); if (!sd) return; if (!sd->icons) return; - view_mode = _e_fm2_view_mode_get(sd); - if ((view_mode == E_FM2_VIEW_MODE_CUSTOM_SMART_GRID_ICONS) || - (view_mode == E_FM2_VIEW_MODE_CUSTOM_GRID_ICONS) || - (view_mode == E_FM2_VIEW_MODE_CUSTOM_ICONS)) - custom = 1; + ic = (sd->range_selected) ? sd->range_selected : sd->last_selected; + if (!ic) ic = eina_list_data_get(sd->icons); - ic_down = NULL; - found = 0; + ic_down = ic; - EINA_LIST_FOREACH(sd->icons, l, ic) + EINA_LIST_FOREACH(sd->icons, l, ic2) { - if (!found) + if (ic2->y > ic->y) { - if (ic->selected) - { - found = 1; - x = ic->x; - y = ic->y; - if (custom) break; - } - } - else if (ic->y > y) - { - dist = (abs(ic->x - x)) + (ic->y - y) * 2; + dist = (abs(ic2->x - ic->x)) + (ic2->y - ic->y) * 2; if (dist < min) { min = dist; - ic_down = ic; - } - else break; - } - } - - if (custom) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if (ic->y > y) - { - dist = (abs(ic->x - x)) + (ic->y - y) * 2; - if (dist < min) - { - min = dist; - ic_down = ic; - } + ic_down = ic2; } } } - if (!ic_down) - { - if (!custom) _e_fm2_icon_sel_next(obj, add); - return; - } if ((!add) || ic_down->sd->config->selection.single) - _e_fm2_icon_desel_any(obj); - _e_fm2_icon_select(ic_down); + { + _e_fm2_icon_desel_any(obj); + _e_fm2_icon_select(ic_down); + } + else + { + _e_fm2_icon_range_select(ic_down); + } + evas_object_smart_callback_call(sd->obj, "selection_change", NULL); _e_fm2_icon_make_visible(ic_down); } @@ -5656,74 +5593,89 @@ _e_fm2_icon_sel_up(Evas_Object *obj, Eina_Bool add) { E_Fm2_Smart_Data *sd; Eina_List *l; - E_Fm2_Icon *ic, *ic_up; - int found = 0, x = 0, y = 0, custom = 0; + E_Fm2_Icon *ic, *ic2, *ic_down; int dist, min = 65535; - char view_mode; sd = evas_object_smart_data_get(obj); if (!sd) return; if (!sd->icons) return; - view_mode = _e_fm2_view_mode_get(sd); + ic = (sd->range_selected) ? sd->range_selected : sd->last_selected; + if (!ic) ic = eina_list_data_get(sd->icons); - if ((view_mode == E_FM2_VIEW_MODE_CUSTOM_SMART_GRID_ICONS) || - (view_mode == E_FM2_VIEW_MODE_CUSTOM_GRID_ICONS) || - (view_mode == E_FM2_VIEW_MODE_CUSTOM_ICONS)) - custom = 1; + ic_down = ic; - ic_up = NULL; - - EINA_LIST_REVERSE_FOREACH(sd->icons, l, ic) + EINA_LIST_FOREACH(sd->icons, l, ic2) { - if (!found) + if (ic2->y < ic->y) { - if (ic->selected) - { - found = 1; - x = ic->x; - y = ic->y; - if (custom) break; - } - } - else if (ic->y < y) - { - dist = (abs(ic->x - x)) + (y - ic->y) * 2; + dist = (abs(ic2->x - ic->x)) + (ic->y - ic2->y) * 2; if (dist < min) { min = dist; - ic_up = ic; - } - else break; - } - } - - if (custom && found) - { - EINA_LIST_FOREACH(sd->icons, l, ic) - { - if (!ic->selected && ic->y < y) - { - dist = (abs(ic->x - x)) + (y - ic->y) * 2; - if (dist < min) - { - min = dist; - ic_up = ic; - } + ic_down = ic2; } } } - if (!ic_up) + if ((!add) || ic_down->sd->config->selection.single) { - if (!custom) _e_fm2_icon_sel_prev(obj, add); - return; + _e_fm2_icon_desel_any(obj); + _e_fm2_icon_select(ic_down); } - if ((!add) || ic_up->sd->config->selection.single) - _e_fm2_icon_desel_any(obj); - _e_fm2_icon_select(ic_up); + else + { + _e_fm2_icon_range_select(ic_down); + } + evas_object_smart_callback_call(sd->obj, "selection_change", NULL); - _e_fm2_icon_make_visible(ic_up); + _e_fm2_icon_make_visible(ic_down); +} + +static void +_e_fm2_icon_range_select(E_Fm2_Icon *ic) +{ + const Eina_List *l; + E_Fm2_Icon *ic2; + + char view_mode = _e_fm2_view_mode_get(ic->sd); + E_Fm2_Icon *last = ic->sd->last_selected; + + _e_fm2_icon_desel_any(ic->sd->obj); + + if ((!last) || (last == ic)) + { + last = ic; + } + else if ((view_mode == E_FM2_VIEW_MODE_CUSTOM_SMART_GRID_ICONS) || + (view_mode == E_FM2_VIEW_MODE_CUSTOM_GRID_ICONS) || + (view_mode == E_FM2_VIEW_MODE_CUSTOM_ICONS)) + { + int topx = (ic->x <= last->x) ? ic->x : last->x; + int boundx = (ic->x < last->x) ? (last->x + last->w) : (ic->x + ic->w); + int topy = (ic->y <= last->y) ? ic->y : last->y; + int boundy = (ic->y < last->y) ? (last->y + last->h) : (ic->y + ic->h); + + EINA_LIST_FOREACH(ic->sd->icons, l, ic2) + { + if ((ic2 != last) && + (ic2->x >= topx) && (ic2->x < boundx) && + (ic2->y >= topy) && (ic2->y < boundy)) + _e_fm2_icon_select(ic2); + } + } + else + { + int trig = 2; + EINA_LIST_FOREACH(ic->sd->icons, l, ic2) + { + if ((ic2 == last) || (ic2 == ic)) trig--; + if ((trig < 2) && (ic2 != last)) _e_fm2_icon_select(ic2); + if (!trig) break; + } + } + _e_fm2_icon_select(last); + ic->sd->range_selected = ic; } /* FIXME: prototype */ @@ -7240,39 +7192,7 @@ _e_fm2_mouse_1_handler(E_Fm2_Icon *ic, int up, void *evas_event) if (range_sel) { - const Eina_List *l, *l2; - E_Fm2_Icon *ic2; - Eina_Bool seen = 0; - /* find last selected - if any, and select all icons between */ - EINA_LIST_FOREACH(ic->sd->icons, l, ic2) - { - if (ic2 == ic) seen = 1; - if (ic2->last_selected) - { - ic2->last_selected = 0; - if (seen) - { - for (l2 = l, ic2 = l2->data; l2; l2 = l2->prev, ic2 = l2->data) - { - if (ic == ic2) break; - if (!ic2->selected) sel_change = 1; - _e_fm2_icon_select(ic2); - ic2->last_selected = 0; - } - } - else - { - EINA_LIST_FOREACH(l, l2, ic2) - { - if (ic == ic2) break; - if (!ic2->selected) sel_change = 1; - _e_fm2_icon_select(ic2); - ic2->last_selected = 0; - } - } - break; - } - } + if (!up) _e_fm2_icon_range_select(ic); } else if ((!multi_sel) && ((up) || ((!up) && (!ic->selected)))) {