Enlightenment CVS committal Author : dj2 Project : e17 Module : libs/ewl
Dir : e17/libs/ewl/src/lib Modified Files: ewl_filelist.c ewl_filelist.h ewl_filelist_icon.c ewl_filelist_icon.h ewl_filelist_list.c ewl_filelist_list.h Log Message: - SHIFT handling for the icon view of the file list. - there are a couple of issues. shift select a region, then shift select in the other direction from the first click and you lose the item of the first click. shift select a region then shift select to about the middle of that region and you'll get the clicked item twice. - still need to handle the tree view =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- ewl_filelist.c 14 Apr 2006 19:31:46 -0000 1.3 +++ ewl_filelist.c 15 Apr 2006 05:14:31 -0000 1.4 @@ -3,6 +3,11 @@ #include "ewl_macros.h" #include "ewl_private.h" +static void ewl_filelist_signal_between(Ewl_Filelist *fl, Ewl_Container *c, + int add, const char *signal, + int a_idx, Ewl_Widget *a, + int b_idx, Ewl_Widget *b); + /** * @param fl: The filelist to initialize * @return Returns TRUE on success or FALSE on failure @@ -463,7 +468,6 @@ const char *select_state, const char *unselect_state) { - Ewl_Widget *last; int multi = FALSE; DENTER_FUNCTION(DLEVEL_STABLE); @@ -482,10 +486,6 @@ || (ev->modifiers & EWL_KEY_MODIFIER_CTRL)) multi = TRUE; - /* store and update the last selected widget */ - last = fl->last_selected; - fl->last_selected = w; - /* we are not in multiselect mode, or the multiselect keys aren't * pressed */ if (!ewl_filelist_multiselect_get(fl) || (!multi)) @@ -499,6 +499,9 @@ ecore_list_append(fl->selected, w); ewl_filelist_selected_files_change_notify(fl); + fl->select.base = w; + fl->select.last = NULL; + DRETURN(DLEVEL_STABLE); } @@ -507,25 +510,45 @@ if (ev->modifiers & EWL_KEY_MODIFIER_SHIFT) { - /* XXX Write me .. */ + /* we have no base selected so this is the first click with + * the shift. set base and set the clicked as selected */ + if (!fl->select.base) + { + fl->select.base = w; + fl->select.last = NULL; + + if (fl->selected_unselect) fl->selected_unselect(fl); + ecore_list_clear(fl->selected); + } + else + { + if (fl->shift_handle) fl->shift_handle(fl, w); + fl->select.last = w; + } + + if (select_state) ewl_widget_state_set(w, select_state); + ecore_list_append(fl->selected, w); + + ewl_filelist_selected_files_change_notify(fl); } else { void *item; + fl->select.base = w; + fl->select.last = NULL; + item = ecore_list_goto(fl->selected, w); if (item) { if (unselect_state) ewl_widget_state_set(w, unselect_state); - ecore_list_remove(fl->selected); } else { if (select_state) ewl_widget_state_set(w, select_state); - ecore_list_append(fl->selected, w); } } @@ -533,6 +556,149 @@ DLEAVE_FUNCTION(DLEVEL_STABLE); } +/** + * @param fl: The filelist to work with + * @param c: The container to select/unselect from + * @param clicked: The clicked widget + * @param select_signal: The signal to send on select + * @param unselect_signal: The signal to send on unselect + * @return Returns no value + * @brief Handles the select/deselect of widgets in the given container @a c + */ +void +ewl_filelist_container_shift_handle(Ewl_Filelist *fl, + Ewl_Container *c, Ewl_Widget *clicked, + const char *select_signal, + const char *unselect_signal) +{ + int base_idx, last_idx = -1, cur_idx; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("fl", fl); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("clicked", clicked); + DCHECK_PARAM_PTR("select_signal", select_signal); + DCHECK_PARAM_PTR("unselect_signal", unselect_signal); + DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); + DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE); + DCHECK_TYPE("clicked", clicked, EWL_WIDGET_TYPE); + + ecore_list_goto(c->children, fl->select.base); + base_idx = ecore_list_index(c->children); + + ecore_list_goto(c->children, clicked); + cur_idx = ecore_list_index(c->children); + + if (fl->select.last) + { + ecore_list_goto(c->children, fl->select.last); + last_idx = ecore_list_index(c->children); + } + + if (last_idx < 0) + { + ewl_filelist_signal_between(fl, c, TRUE, select_signal, base_idx, + fl->select.base, cur_idx, clicked); + } + else + { + /* user selected more, just tag on whats between the last + * click and the current click */ + if (((cur_idx < last_idx) && (last_idx < base_idx)) + || ((base_idx < last_idx) + && (last_idx < cur_idx))) + { + ewl_filelist_signal_between(fl, c, TRUE, select_signal, + last_idx, fl->select.last, + cur_idx, clicked); + } + else + { + /* unselect stuff between last and our current index */ + ewl_filelist_signal_between(fl, c, FALSE, + unselect_signal, last_idx, + fl->select.last, cur_idx, clicked); + + /* make sure the last selected is removed */ + ewl_widget_state_set(fl->select.last, unselect_signal); + ecore_list_goto(fl->selected, fl->select.last); + ecore_list_remove(fl->selected); + + /* if we moved over the base point we need to + * reseelct some stuff */ + if (!((last_idx < base_idx) && (cur_idx < base_idx)) + && !((last_idx > base_idx) + && (cur_idx > base_idx))) + { + ewl_filelist_signal_between(fl, c, TRUE, + select_signal, base_idx, + fl->select.base, cur_idx, + clicked); + } + } + } + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +static void +ewl_filelist_signal_between(Ewl_Filelist *fl, Ewl_Container *c, int add, + const char *signal, + int a_idx, Ewl_Widget *a, + int b_idx, Ewl_Widget *b) +{ + Ewl_Widget *start, *end, *cur; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("fl", fl); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("signal", signal); + DCHECK_PARAM_PTR("a", a); + DCHECK_PARAM_PTR("b", b); + DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); + DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE); + DCHECK_TYPE("a", a, EWL_WIDGET_TYPE); + DCHECK_TYPE("b", b, EWL_WIDGET_TYPE); + + if (a_idx < b_idx) + { + start = a; + end = b; + } + else + { + start = b; + end = a; + } + + /* select all the widgets between the base and clicked + * point, excluding the start/end points */ + ecore_list_goto(c->children, start); + ecore_list_next(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (cur == end) break; + + if (add) + { + ewl_widget_state_set(cur, signal); + ecore_list_append(fl->selected, cur); + } + else + { + /* don't remove the base selected widget */ + if (cur != fl->select.base) + { + ecore_list_goto(fl->selected, cur); + ecore_list_remove(fl->selected); + ewl_widget_state_set(cur, signal); + } + } + } + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + void ewl_filelist_cb_destroy(Ewl_Widget *w, void *ev, void *data) { @@ -555,6 +721,7 @@ fl->selected_file_add = NULL; fl->file_name_get = NULL; fl->selected_unselect = NULL; + fl->shift_handle = NULL; DLEAVE_FUNCTION(DLEVEL_STABLE); } =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- ewl_filelist.h 14 Apr 2006 19:31:46 -0000 1.3 +++ ewl_filelist.h 15 Apr 2006 05:14:31 -0000 1.4 @@ -39,8 +39,11 @@ unsigned char multiselect:1; /**< Allow multiple file selctions */ unsigned char show_dot_files:1; /**< Show . files */ - Ewl_Widget *last_selected; /**< The last selected icon */ - Ewl_Widget *base_selected; /**< First select in SHIFT select */ + struct + { + Ewl_Widget *base; /**< First select in SHIFT select */ + Ewl_Widget *last; /**< Last selected in SHIFT select */ + } select; /**< Data used in SHIFT select */ void (*dir_change)(Ewl_Filelist *fl); /**< Callback to notify of directory change */ @@ -62,6 +65,9 @@ const char *(*file_name_get)(Ewl_Filelist *fl, void *file); /**< Callback to get the selected filename */ + void (*shift_handle)(Ewl_Filelist *fl, Ewl_Widget *clicked); /**< + Callback to handle + SHIFT clicks */ }; int ewl_filelist_init(Ewl_Filelist *fl); @@ -103,6 +109,10 @@ Ewl_Event_Mouse_Up *ev, const char *select_state, const char *unselect_state); +void ewl_filelist_container_shift_handle(Ewl_Filelist *fl, + Ewl_Container *c, Ewl_Widget *clicked, + const char *select_signal, + const char *unselect_signal); /* * Internally used functions, override at your own risk =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist_icon.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- ewl_filelist_icon.c 14 Apr 2006 19:31:46 -0000 1.3 +++ ewl_filelist_icon.c 15 Apr 2006 05:14:31 -0000 1.4 @@ -81,6 +81,7 @@ list->selected_file_add = ewl_filelist_icon_selected_file_add; list->file_name_get = ewl_filelist_icon_filename_get; list->selected_unselect = ewl_filelist_icon_selected_unselect; + list->shift_handle = ewl_filelist_icon_shift_handle; fl->freebox = ewl_vfreebox_new(); ewl_container_child_append(EWL_CONTAINER(fl), fl->freebox); @@ -159,6 +160,31 @@ DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); ewl_filelist_selected_signal_all(fl, "icon,unselect"); + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +/** + * @param fl: The filelist to deal with + * @param clicked: The currently clicked item + * @return Returns no value + * @brief Select the appropriate widgets to deal with a shift click + */ +void +ewl_filelist_icon_shift_handle(Ewl_Filelist *fl, Ewl_Widget *clicked) +{ + Ewl_Filelist_Icon *list; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("fl", fl); + DCHECK_PARAM_PTR("clicked", clicked); + DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); + DCHECK_TYPE("clicked", clicked, EWL_WIDGET_TYPE); + + list = EWL_FILELIST_ICON(fl); + ewl_filelist_container_shift_handle(fl, + EWL_CONTAINER(list->freebox), clicked, + "icon,select", "icon,unselect"); DLEAVE_FUNCTION(DLEVEL_STABLE); } =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist_icon.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- ewl_filelist_icon.h 14 Apr 2006 19:31:46 -0000 1.3 +++ ewl_filelist_icon.h 15 Apr 2006 05:14:31 -0000 1.4 @@ -45,6 +45,8 @@ const char *ewl_filelist_icon_filename_get(Ewl_Filelist *fl, void *item); void ewl_filelist_icon_selected_unselect(Ewl_Filelist *fl); +void ewl_filelist_icon_shift_handle(Ewl_Filelist *fl, + Ewl_Widget *clicked); /** * @} =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist_list.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- ewl_filelist_list.c 14 Apr 2006 19:31:46 -0000 1.2 +++ ewl_filelist_list.c 15 Apr 2006 05:14:31 -0000 1.3 @@ -85,6 +85,7 @@ list->selected_file_add = ewl_filelist_list_selected_file_add; list->file_name_get = ewl_filelist_list_filename_get; list->selected_unselect = ewl_filelist_list_selected_unselect; + list->shift_handle = ewl_filelist_list_shift_handle; fl->tree = ewl_tree_new(6); ewl_tree_headers_set(EWL_TREE(fl->tree), headers); @@ -164,6 +165,26 @@ DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); ewl_filelist_selected_signal_all(fl, "row,unselect"); + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +/** + * @param fl: The filelist to deal with + * @param clicked: The currently clicked item + * @return Returns no value + * @brief Select the appropriate widgets to deal with a shift click + */ +void +ewl_filelist_list_shift_handle(Ewl_Filelist *fl, Ewl_Widget *clicked) +{ + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("fl", fl); + DCHECK_PARAM_PTR("clicked", clicked); + DCHECK_TYPE("fl", fl, EWL_FILELIST_TYPE); + DCHECK_TYPE("clicked", clicked, EWL_WIDGET_TYPE); + + /* XXX fix me */ DLEAVE_FUNCTION(DLEVEL_STABLE); } =================================================================== RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_filelist_list.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- ewl_filelist_list.h 14 Apr 2006 19:31:47 -0000 1.3 +++ ewl_filelist_list.h 15 Apr 2006 05:14:31 -0000 1.4 @@ -45,6 +45,8 @@ const char *ewl_filelist_list_filename_get(Ewl_Filelist *fl, void *item); void ewl_filelist_list_selected_unselect(Ewl_Filelist *fl); +void ewl_filelist_list_shift_handle(Ewl_Filelist *fl, + Ewl_Widget *clicked); /** * @} ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs