Enlightenment CVS committal

Author  : moom
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        Etk.h Makefile.am etk_combobox.c etk_scrolled_view.c 
        etk_table.c etk_toplevel.c etk_toplevel.h etk_tree.c 
        etk_tree2.c etk_tree2.h etk_types.h 
Added Files:
        etk_fixed.c etk_fixed.h 


Log Message:
Lib:
----
* [Etk_Fixed] A new container that allows you to position widgets at fixed
      coords (see the test app of the scrolled view in etk_test for an example)
* [Etk_Tree2] More work on Etk_Tree2: deletion and selection has been 
implemented

Misc:
-----
* [Theme] The sliders now look like those of e17
* [Theme] The theme of the rows have been improved (better colors imho)
* [Autofoo] make dist is fixed



===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/Etk.h,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -3 -r1.45 -r1.46
--- Etk.h       28 Nov 2006 21:40:07 -0000      1.45
+++ Etk.h       9 Dec 2006 09:56:32 -0000       1.46
@@ -40,6 +40,7 @@
 #include "etk_entry.h"
 #include "etk_event.h"
 #include "etk_filechooser_widget.h"
+#include "etk_fixed.h"
 #include "etk_frame.h"
 #include "etk_iconbox.h"
 #include "etk_image.h"
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/Makefile.am,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -3 -r1.49 -r1.50
--- Makefile.am 28 Nov 2006 21:40:07 -0000      1.49
+++ Makefile.am 9 Dec 2006 09:56:32 -0000       1.50
@@ -38,6 +38,7 @@
 etk_entry.h \
 etk_event.h \
 etk_filechooser_widget.h \
+etk_fixed.h \
 etk_frame.h \
 etk_iconbox.h \
 etk_image.h \
@@ -111,6 +112,7 @@
 etk_entry.c \
 etk_event.c \
 etk_filechooser_widget.c \
+etk_fixed.c \
 etk_frame.c \
 etk_iconbox.c \
 etk_image.c \
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_combobox.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -3 -r1.31 -r1.32
--- etk_combobox.c      6 Oct 2006 17:04:14 -0000       1.31
+++ etk_combobox.c      9 Dec 2006 09:56:32 -0000       1.32
@@ -1301,7 +1301,7 @@
  * @code
  * Etk_Combobox *combobox;
  *
- * combobox = etk_combobox_new();
+ * combobox = ETK_COMBOBOX(etk_combobox_new());
  * etk_combobox_column_add(combobox, ETK_COMBOBOX_IMAGE, 24, ETK_FALSE, 
ETK_FALSE, ETK_FALSE, 0.0, 0.5);
  * etk_combobox_column_add(combobox, ETK_COMBOBOX_LABEL, 75, ETK_TRUE, 
ETK_FALSE, ETK_FALSE, 0.0, 0.5);
  * etk_combobox_build(combobox);
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_scrolled_view.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -3 -r1.24 -r1.25
--- etk_scrolled_view.c 20 Oct 2006 17:51:44 -0000      1.24
+++ etk_scrolled_view.c 9 Dec 2006 09:56:33 -0000       1.25
@@ -182,13 +182,13 @@
    scrolled_view->hpolicy = ETK_POLICY_AUTO;
    scrolled_view->vpolicy = ETK_POLICY_AUTO;
 
-   scrolled_view->hscrollbar = etk_hscrollbar_new(0.0, 0.0, 0.0, 6.0, 40.0, 
0.0);
+   scrolled_view->hscrollbar = etk_hscrollbar_new(0.0, 0.0, 0.0, 12.0, 50.0, 
0.0);
    etk_widget_theme_parent_set(scrolled_view->hscrollbar, 
ETK_WIDGET(scrolled_view));
    etk_widget_parent_set(scrolled_view->hscrollbar, ETK_WIDGET(scrolled_view));
    etk_widget_internal_set(scrolled_view->hscrollbar, ETK_TRUE);
    etk_widget_show(scrolled_view->hscrollbar);
    
-   scrolled_view->vscrollbar = etk_vscrollbar_new(0.0, 0.0, 0.0, 6.0, 40.0, 
0.0);
+   scrolled_view->vscrollbar = etk_vscrollbar_new(0.0, 0.0, 0.0, 12.0, 50.0, 
0.0);
    etk_widget_theme_parent_set(scrolled_view->vscrollbar, 
ETK_WIDGET(scrolled_view));
    etk_widget_parent_set(scrolled_view->vscrollbar, ETK_WIDGET(scrolled_view));
    etk_widget_internal_set(scrolled_view->vscrollbar, ETK_TRUE);
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_table.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- etk_table.c 6 Oct 2006 17:04:15 -0000       1.19
+++ etk_table.c 9 Dec 2006 09:56:33 -0000       1.20
@@ -39,7 +39,7 @@
 /**
  * @internal
  * @brief Gets the type of an Etk_Table
- * @return Returns the type on an Etk_Table
+ * @return Returns the type of an Etk_Table
  */
 Etk_Type *etk_table_type_get()
 {
@@ -47,11 +47,15 @@
 
    if (!table_type)
    {
-      table_type = etk_type_new("Etk_Table", ETK_CONTAINER_TYPE, 
sizeof(Etk_Table), ETK_CONSTRUCTOR(_etk_table_constructor), 
ETK_DESTRUCTOR(_etk_table_destructor));
+      table_type = etk_type_new("Etk_Table", ETK_CONTAINER_TYPE, 
sizeof(Etk_Table),
+         ETK_CONSTRUCTOR(_etk_table_constructor), 
ETK_DESTRUCTOR(_etk_table_destructor));
    
-      etk_type_property_add(table_type, "num_cols", 
ETK_TABLE_NUM_COLS_PROPERTY, ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_int(0));
-      etk_type_property_add(table_type, "num_rows", 
ETK_TABLE_NUM_ROWS_PROPERTY, ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_int(0));
-      etk_type_property_add(table_type, "homogeneous", 
ETK_TABLE_HOMOGENEOUS_PROPERTY, ETK_PROPERTY_BOOL, 
ETK_PROPERTY_READABLE_WRITABLE,  etk_property_value_bool(ETK_FALSE));
+      etk_type_property_add(table_type, "num_cols", 
ETK_TABLE_NUM_COLS_PROPERTY,
+         ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_int(0));
+      etk_type_property_add(table_type, "num_rows", 
ETK_TABLE_NUM_ROWS_PROPERTY,
+         ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_int(0));
+      etk_type_property_add(table_type, "homogeneous", 
ETK_TABLE_HOMOGENEOUS_PROPERTY,
+         ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_bool(ETK_FALSE));
       
       table_type->property_set = _etk_table_property_set;
       table_type->property_get = _etk_table_property_get;
@@ -65,18 +69,12 @@
  * @param num_cols the number of columns of the new table
  * @param num_rows the number of rows of the new table
  * @param homogeneous if homogeneous != 0, all the cells will have the same 
size
+ * @return Returns the new table
  */
 Etk_Widget *etk_table_new(int num_cols, int num_rows, Etk_Bool homogeneous)
 {
-   Etk_Widget *new_widget;
-   Etk_Table *new_table;
-
-   new_widget = etk_widget_new(ETK_TABLE_TYPE, NULL);
-   new_table = ETK_TABLE(new_widget);
-   etk_table_resize(new_table, num_cols, num_rows);
-   etk_table_homogeneous_set(new_table, homogeneous);
-
-   return new_widget;
+   return etk_widget_new(ETK_TABLE_TYPE, "homogeneous", homogeneous,
+      "num_cols", num_cols, "num_rows", num_rows, NULL);
 }
 
 /**
@@ -696,12 +694,6 @@
    }
 }
 
-/**************************
- *
- * Callbacks and handlers
- *
- **************************/
-
 /* Adds a child to the table */
 static void _etk_table_child_add(Etk_Container *container, Etk_Widget *widget)
 {
@@ -726,10 +718,15 @@
 static Evas_List *_etk_table_children_get(Etk_Container *container)
 {
    Etk_Table *table;
+   Evas_List *children, *l;
    
    if (!(table = ETK_TABLE(container)))
       return NULL;
-   return table->children;
+   
+   children = NULL;
+   for (l = table->children; l; l = l->next)
+      children = evas_list_append(children, l->data);
+   return children;
 }
 
 /** @} */
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_toplevel.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -3 -r1.2 -r1.3
--- etk_toplevel.c      20 Oct 2006 17:51:44 -0000      1.2
+++ etk_toplevel.c      9 Dec 2006 09:56:33 -0000       1.3
@@ -260,7 +260,7 @@
             toplevel->pointer_set(toplevel, *current_pointer_ptr);
       }
       else
-         toplevel->pointer_set(toplevel, ETK_POINTER_DEFAULT);
+         toplevel->pointer_set(toplevel, ETK_POINTER_NONE);
    }
 }
 
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_toplevel.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -3 -r1.2 -r1.3
--- etk_toplevel.h      20 Oct 2006 17:51:44 -0000      1.2
+++ etk_toplevel.h      9 Dec 2006 09:56:33 -0000       1.3
@@ -22,6 +22,7 @@
 /** @brief The different types of mouse pointer */
 typedef enum Etk_Pointer_Type
 {
+   ETK_POINTER_NONE,
    ETK_POINTER_DEFAULT,
    ETK_POINTER_MOVE,
    ETK_POINTER_H_DOUBLE_ARROW,
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_tree.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -3 -r1.79 -r1.80
--- etk_tree.c  29 Oct 2006 11:39:54 -0000      1.79
+++ etk_tree.c  9 Dec 2006 09:56:33 -0000       1.80
@@ -2247,14 +2247,6 @@
       etk_tree_row_expand(tree->last_selected);
    else if (strcmp(event->keyname, "Left") == 0 && tree->last_selected && 
tree->last_selected->selected)
       etk_tree_row_collapse(tree->last_selected);
-   else if (strcmp(event->keyname, "Home") == 0)
-      etk_range_value_set(vscrollbar_range, vscrollbar_range->lower);
-   else if (strcmp(event->keyname, "End") == 0)
-      etk_range_value_set(vscrollbar_range, vscrollbar_range->upper);
-   else if (strcmp(event->keyname, "Next") == 0)
-      etk_range_value_set(vscrollbar_range, vscrollbar_range->value + 
vscrollbar_range->page_increment);
-   else if (strcmp(event->keyname, "Prior") == 0)
-      etk_range_value_set(vscrollbar_range, vscrollbar_range->value - 
vscrollbar_range->page_increment);
    else if (strcmp(event->keyname, "space") == 0)
    {
       if (tree->last_selected)
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_tree2.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- etk_tree2.c 28 Nov 2006 21:40:07 -0000      1.1
+++ etk_tree2.c 9 Dec 2006 09:56:33 -0000       1.2
@@ -62,7 +62,7 @@
    ETK_TREE2_MODE_PROPERTY,
    ETK_TREE2_MULTIPLE_SELECT_PROPERTY,
    ETK_TREE2_HEADERS_VISIBLE_PROPERTY,
-   ETK_TREE2_ROW_HEIGHT_PROPERTY
+   ETK_TREE2_ROWS_HEIGHT_PROPERTY
 };
 
 enum Etk_Tree2_Col_Signal_Id
@@ -106,6 +106,7 @@
 static void _etk_tree2_realize_cb(Etk_Object *object, void *data);
 static void _etk_tree2_focus_cb(Etk_Object *object, void *event, void *data);
 static void _etk_tree2_unfocus_cb(Etk_Object *object, void *event, void *data);
+static void _etk_tree2_key_down_cb(Etk_Object *object, Etk_Event_Key_Down 
*event, void *data);
 static void _etk_tree2_scroll_content_realize_cb(Etk_Object *object, void 
*data);
 static void _etk_tree2_scroll_content_unrealize_cb(Etk_Object *object, void 
*data);
 static void _etk_tree2_grid_realize_cb(Etk_Object *object, void *data);
@@ -121,11 +122,18 @@
 static void _etk_tree2_row_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, 
void *event_info);
 static void _etk_tree2_row_expander_mouse_up_cb(void *data, Evas *e, 
Evas_Object *obj, void *event_info);
 
+static void _etk_tree2_purge_job(void *data);
+static void _etk_tree2_purge(Etk_Tree2 *tree);
+static void _etk_tree2_row_move_to_purge_pool(Etk_Tree2_Row *row);
+
+/* TODO: static void _etk_tree2_sort(Etk_Tree2 *tree); */
+
 static void _etk_tree2_col_realize(Etk_Tree2 *tree, int col_nth);
 static Etk_Tree2_Col *etk_tree2_col_to_resize_get(Etk_Tree2_Col *col, int x);
 
-static void _etk_tree2_row_fields_set_valist_full(Etk_Tree2_Row *row, va_list 
args, Etk_Bool emit_signal);
+static Etk_Tree2_Row *_etk_tree2_row_next_get_full(Etk_Tree2_Row *row, 
Etk_Bool only_visible);
 static Etk_Tree2_Row *_etk_tree2_row_next_to_render_get(Etk_Tree2_Row *row, 
int *depth);
+static void _etk_tree2_row_fields_set_valist_full(Etk_Tree2_Row *row, va_list 
args, Etk_Bool emit_signal);
 static Etk_Tree2_Row_Object *_etk_tree2_row_object_create(Etk_Tree2 *tree);
 static void _etk_tree2_row_object_destroy(Etk_Tree2 *tree, 
Etk_Tree2_Row_Object *row_object);
 
@@ -135,6 +143,8 @@
 static Etk_Signal *_etk_tree2_signals[ETK_TREE2_NUM_SIGNALS];
 static Etk_Signal *_etk_tree2_col_signals[ETK_TREE2_COL_NUM_SIGNALS];
 
+/* TODO: better doc of row_next_get()... (with a note about deleted rows...) */
+
 
 /**************************
  *
@@ -183,7 +193,7 @@
          ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_bool(ETK_TRUE));
       etk_type_property_add(tree2_type, "headers_visible", 
ETK_TREE2_HEADERS_VISIBLE_PROPERTY,
          ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_bool(ETK_TRUE));
-      etk_type_property_add(tree2_type, "row_height", 
ETK_TREE2_ROW_HEIGHT_PROPERTY,
+      etk_type_property_add(tree2_type, "rows_height", 
ETK_TREE2_ROWS_HEIGHT_PROPERTY,
          ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE, 
etk_property_value_int(DEFAULT_ROW_HEIGHT));
       
       tree2_type->property_set = _etk_tree2_property_set;
@@ -283,9 +293,8 @@
    if (!tree || tree->multiple_select == multiple_select)
       return;
 
-   /* TODO: */
-   /*if (!multiple_select)
-      etk_tree2_unselect_all(tree);*/
+   if (!multiple_select)
+      etk_tree2_unselect_all(tree);
    tree->multiple_select = multiple_select;
    etk_object_notify(ETK_OBJECT(tree), "multiple_select");
 }
@@ -320,7 +329,7 @@
 /**
  * @brief Gets whether or not the column-headers are visible
  * @param tree a tree
- * @return Returns ETK_TRUE if the column headers are visible, ETK_FALSE 
otherwise
+ * @return Returns ETK_TRUE if the column-headers are visible, ETK_FALSE 
otherwise
  */
 Etk_Bool etk_tree2_headers_visible_get(Etk_Tree2 *tree)
 {
@@ -332,18 +341,18 @@
 /**
  * @brief Sets the height of the rows of the tree
  * @param tree a tree
- * @param row_height the row height to set. The minimum value is 12
+ * @param rows_height the rows height to set. The minimum value is 12
  */
-void etk_tree2_rows_height_set(Etk_Tree2 *tree, int row_height)
+void etk_tree2_rows_height_set(Etk_Tree2 *tree, int rows_height)
 {
    if (!tree)
       return;
    
-   row_height = ETK_MAX(row_height, MIN_ROW_HEIGHT);
-   if (tree->row_height != row_height)
+   rows_height = ETK_MAX(rows_height, MIN_ROW_HEIGHT);
+   if (tree->rows_height != rows_height)
    {
-      tree->row_height = row_height;
-      etk_object_notify(ETK_OBJECT(tree), "row_height");
+      tree->rows_height = rows_height;
+      etk_object_notify(ETK_OBJECT(tree), "rows_height");
       etk_signal_emit_by_name("scroll_size_changed", 
ETK_OBJECT(tree->scroll_content), NULL);
       etk_widget_redraw_queue(ETK_WIDGET(tree));
    }
@@ -358,7 +367,7 @@
 {
    if (!tree)
       return DEFAULT_ROW_HEIGHT;
-   return tree->row_height;
+   return tree->rows_height;
 }
 
 /**
@@ -854,10 +863,11 @@
       parent = after->parent;
    if (!parent)
       parent = &tree->root;
-
+   
    new_row = malloc(sizeof(Etk_Tree2_Row));
    new_row->data = NULL;
    new_row->data_free_cb = NULL;
+   new_row->delete_me = ETK_FALSE;
    new_row->selected = ETK_FALSE;
    new_row->unfolded = ETK_FALSE;
    
@@ -910,21 +920,46 @@
    if (!tree->frozen)
    {
       etk_signal_emit_by_name("scroll_size_changed", 
ETK_OBJECT(tree->scroll_content), NULL);
-      etk_widget_redraw_queue(ETK_WIDGET(tree->grid));
+      etk_widget_redraw_queue(ETK_WIDGET(tree));
    }
    return new_row;
 }
 
-/* TODOC */
-void etk_tree2_row_del(Etk_Tree2_Row *row)
+/**
+ * @brief Deletes an existing row and all its children. Note that the row will 
just be marked as deleted.
+ * It will be effectively deleted only during the next iteration of Ecore's 
main loop. Thus, you can still manipulate
+ * safely a row marked as deleted.
+ * @param row the row to delete
+ */
+void etk_tree2_row_delete(Etk_Tree2_Row *row)
 {
-   /* TODO: */
+   if (!row || row->delete_me)
+      return;
+   
+   _etk_tree2_row_move_to_purge_pool(row);
+   
+   if (!row->tree->frozen)
+   {
+      etk_signal_emit_by_name("scroll_size_changed", 
ETK_OBJECT(row->tree->scroll_content), NULL);
+      etk_widget_redraw_queue(ETK_WIDGET(row->tree));
+   }
 }
 
-/* TODOC */
+/**
+ * @brief Deletes all the rows of the tree. Note that the rows will just be 
marked as deleted. They will be effectively
+ * deleted during the next iteration of Ecore's main loop. Thus, you can still 
manipulate safely the rows immediately
+ * after a clear.
+ */
 void etk_tree2_clear(Etk_Tree2 *tree)
 {
-   /* TODO: */
+   if (!tree)
+      return;
+   
+   while (tree->root.first_child)
+   _etk_tree2_row_move_to_purge_pool(tree->root.first_child);
+   
+   etk_signal_emit_by_name("scroll_size_changed", 
ETK_OBJECT(tree->scroll_content), NULL);
+   etk_widget_redraw_queue(ETK_WIDGET(tree));
 }
 
 /**
@@ -1008,6 +1043,48 @@
 }
 
 /**
+ * @brief Sets the user data associated to the row. The data could be 
retrieved later with etk_tree2_row_data_get()
+ * @param row a row of the tree
+ * @param data the data to associate to the row
+ * @note This is equivalent to etk_tree2_row_data_set_full(row, data, NULL);
+ */
+void  etk_tree2_row_data_set(Etk_Tree2_Row *row, void *data)
+{
+   etk_tree2_row_data_set_full(row, data, NULL);
+}
+
+/**
+ * @brief Sets the user data associated to the row. The data could be 
retrieved later with etk_tree2_row_data_get().
+ * You can also set a function to call to free automatically the data when the 
row is deleted
+ * @param row a row of the tree
+ * @param data the data to associate to the row
+ * @param free_cb a function to call to free the data automatically when the 
row is deleted
+ */
+void  etk_tree2_row_data_set_full(Etk_Tree2_Row *row, void *data, void 
(*free_cb)(void *data))
+{
+   if (!row)
+      return;
+   
+   if (row->data && row->data_free_cb)
+      row->data_free_cb(row->data);
+   
+   row->data = data;
+   row->data_free_cb = free_cb;
+}
+
+/**
+ * @brief Gets the user data associated to the row (previously set with 
etk_tree2_row_data_set()).
+ * @param row a row of the tree
+ * @return Returns the user data associated to the row
+ */
+void *etk_tree2_row_data_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   return row->data;
+}
+
+/**
  * @brief Selects all the rows of the tree
  * @param tree a tree
  * @note When you call etk_tree2_select_all(), for performance reasons, the 
signal "row_selected" is not emitted for
@@ -1020,27 +1097,11 @@
    if (!tree)
       return;
    
-   for (row = tree->root.first_child; row; )
-   {
+   for (row = tree->root.first_child; row; row = 
_etk_tree2_row_next_get_full(row, ETK_FALSE))
       row->selected = ETK_TRUE;
-      
-      if (row->first_child)
-         row = row->first_child;
-      else
-      {
-         for (row = row; row; row = row->parent)
-         {
-            if (row->next)
-            {
-               row = row->next;
-               break;
-            }
-         }
-      }
-   }
    
-   etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ALL_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL);
-   etk_widget_redraw_queue(ETK_WIDGET(row->tree));
+   etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ALL_SELECTED_SIGNAL], 
ETK_OBJECT(tree), NULL);
+   etk_widget_redraw_queue(ETK_WIDGET(tree));
 }
 
 /**
@@ -1056,27 +1117,11 @@
    if (!tree)
       return;
    
-   for (row = tree->root.first_child; row; )
-   {
+   for (row = tree->root.first_child; row; row = 
_etk_tree2_row_next_get_full(row, ETK_FALSE))
       row->selected = ETK_FALSE;
-      
-      if (row->first_child)
-         row = row->first_child;
-      else
-      {
-         for (row = row; row; row = row->parent)
-         {
-            if (row->next)
-            {
-               row = row->next;
-               break;
-            }
-         }
-      }
-   }
    
-   etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ALL_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL);
-   etk_widget_redraw_queue(ETK_WIDGET(row->tree));
+   etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ALL_SELECTED_SIGNAL], 
ETK_OBJECT(tree), NULL);
+   etk_widget_redraw_queue(ETK_WIDGET(tree));
 }
 
 /**
@@ -1087,11 +1132,7 @@
 {
    if (!row || row->selected)
       return;
-   
-   row->selected = ETK_TRUE;
-   etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL, row);
-   if (!row->tree->frozen)
-      etk_widget_redraw_queue(ETK_WIDGET(row->tree));
+   _etk_tree2_row_select(row->tree, row, ETK_MODIFIER_NONE);
 }
 
 /**
@@ -1182,6 +1223,100 @@
    return !row->unfolded;
 }
 
+/**
+ * @brief Gets the first row of the tree
+ * @param tree a tree
+ * @return Returns the first row of the tree, or NULL if the tree is empty
+ */
+Etk_Tree2_Row *etk_tree2_first_row_get(Etk_Tree2 *tree)
+{
+   if (!tree)
+      return NULL;
+   return tree->root.first_child;
+}
+
+/**
+ * @brief Gets the last row of the tree
+ * @param tree a tree
+ * @return Returns the last row of the tree, or NULL if the tree is empty
+ */
+Etk_Tree2_Row *etk_tree2_last_row_get(Etk_Tree2 *tree)
+{
+   if (!tree)
+      return NULL;
+   return tree->root.last_child;
+}
+
+/**
+ * @brief Gets the previous row before the specified row
+ * @param row a row
+ * @return Returns the previous row before the specified row, or NULL if the 
row is the first row of its parent
+ * @note This function does not return the previous visible row, but only the 
previous row that is on the same
+ * level as the specified row. So if some rows of the tree have children, 
you'll have to use etk_tree2_row_parent_get(),
+ * etk_tree2_row_first_child_get(), ... if you want to walk through all the 
rows of the tree. See the examples at
+ * the top of this page.
+ */
+Etk_Tree2_Row *etk_tree2_row_prev_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   return row->prev;
+}
+
+/**
+ * @brief Gets the next row after the specified row
+ * @param row a row
+ * @return Returns the next row after the specified row, or NULL if the row is 
the last row of its parent
+ * @note This function does not return the next visible row, but only the next 
row that is on the same
+ * level as the specified row. So if some rows of the tree have children, 
you'll have to use etk_tree2_row_parent_get(),
+ * etk_tree2_row_first_child_get(), ... if you want to walk through all the 
rows of the tree. See the examples at
+ * the top of this page.
+ */
+Etk_Tree2_Row *etk_tree2_row_next_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   return row->next;
+}
+
+/**
+ * @brief Gets the parent row of the specified row
+ * @param row a row
+ * @return Returns the parent row of the specified row, or NULL if the row is 
at the tree's root
+ */
+Etk_Tree2_Row *etk_tree2_row_parent_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   if (!row->parent || row->parent == &row->tree->root)
+      return NULL;
+   return row->parent;
+}
+
+/**
+ * @brief Gets the first child of the specified row
+ * @param row a row
+ * @return Returns the first child of the row
+ */
+Etk_Tree2_Row *etk_tree2_row_first_child_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   return row->first_child;
+}
+
+/**
+ * @brief Gets the last child of the specified row
+ * @param row a row
+ * @return Returns the last child of the row
+ */
+Etk_Tree2_Row *etk_tree2_row_last_child_get(Etk_Tree2_Row *row)
+{
+   if (!row)
+      return NULL;
+   return row->last_child;
+}
+
 /**************************
  *
  * Etk specific functions
@@ -1235,6 +1370,7 @@
    tree->grid_clip = NULL;
    
    tree->root.tree = tree;
+   tree->root.delete_me = ETK_FALSE;
    tree->root.selected = ETK_FALSE;
    tree->root.unfolded = ETK_TRUE;
    tree->root.data = NULL;
@@ -1250,12 +1386,15 @@
    tree->root.num_visible_children = 0;
    
    tree->total_rows = 0;
+   tree->last_selected_row = NULL;
+   tree->purge_pool = NULL;
    tree->row_objects = NULL;
-   tree->row_height = DEFAULT_ROW_HEIGHT;
    
+   tree->rows_height = DEFAULT_ROW_HEIGHT;
    tree->scroll_x = 0;
    tree->scroll_y = 0;
    
+   tree->purge_job = NULL;
    tree->mode = ETK_TREE2_MODE_LIST;
    tree->multiple_select = ETK_FALSE;
    tree->tree_contains_headers = ETK_TRUE;
@@ -1263,7 +1402,6 @@
    tree->frozen = ETK_FALSE;
    tree->built = ETK_FALSE;
    
-   
    ETK_WIDGET(tree)->size_request = _etk_tree2_size_request;
    ETK_WIDGET(tree)->size_allocate = _etk_tree2_size_allocate;
    
@@ -1271,15 +1409,24 @@
    etk_signal_connect("unrealize", ETK_OBJECT(tree), 
ETK_CALLBACK(_etk_tree2_unrealize_cb), NULL);
    etk_signal_connect("focus", ETK_OBJECT(tree), 
ETK_CALLBACK(_etk_tree2_focus_cb), NULL);
    etk_signal_connect("unfocus", ETK_OBJECT(tree), 
ETK_CALLBACK(_etk_tree2_unfocus_cb), NULL);
+   etk_signal_connect("key_down", ETK_OBJECT(tree), 
ETK_CALLBACK(_etk_tree2_key_down_cb), NULL);
 }
 
+/* TODO: last selected when deleted... */
+
 /* Destroys the tree */
 static void _etk_tree2_destructor(Etk_Tree2 *tree)
 {
    if (!tree)
       return;
-   
+
+   /* TODO: more efficient cleaning?? */
    etk_tree2_clear(tree);
+   _etk_tree2_purge(tree);
+   
+   if (tree->purge_job)
+      ecore_job_del(tree->purge_job);
+
    free(tree->columns);
 }
 
@@ -1374,7 +1521,7 @@
       {
          for (i = 0; i < tree->num_cols; i++)
          {
-            etk_widget_size_request(tree->columns[i]->header, &header_size);
+            etk_widget_size_request_full(tree->columns[i]->header, 
&header_size, ETK_FALSE);
             if (header_size.h > max_header_height)
                max_header_height = header_size.h;
          }
@@ -1642,7 +1789,7 @@
    scroll_size->w = 0;
    for (i = 0; i < tree->num_cols; i++)
       scroll_size->w += tree->columns[i]->width;
-   scroll_size->h = tree->root.num_visible_children * tree->row_height;
+   scroll_size->h = tree->root.num_visible_children * tree->rows_height;
 }
 
 /**************************
@@ -1789,7 +1936,14 @@
    if (!tree->built)
       return;
    
-   /* Save the rows currently rendered so we can emit the "row_shown/hidden" 
signals */
+   /* Remove the rows marked as "deleted" */
+   if (tree->purge_job)
+   {
+      _etk_tree2_purge(tree);
+      tree->purge_job = NULL;
+   }
+   
+   /* Save the rows currently rendered so we could emit the "row_shown/hidden" 
signals later */
    prev_visible_rows = NULL;
    new_visible_rows = NULL;
    for (l = tree->row_objects; l; l = l->next)
@@ -1806,7 +1960,7 @@
       int num_visible_rows;
       int current_num_rows;
       
-      num_visible_rows = (geometry.h / tree->row_height) + 2;
+      num_visible_rows = (geometry.h / tree->rows_height) + 2;
       current_num_rows = evas_list_count(tree->row_objects);
       
       if (current_num_rows < num_visible_rows)
@@ -1848,15 +2002,11 @@
       int depth;
       
       depth = 0;
-      row_id = tree->scroll_y / tree->row_height;
-      row_y = -(tree->scroll_y % tree->row_height);
+      row_id = tree->scroll_y / tree->rows_height;
+      row_y = -(tree->scroll_y % tree->rows_height);
       for (row = tree->root.first_child, i = 0; i < row_id && row; i++)
          row = _etk_tree2_row_next_to_render_get(row, &depth);
       show_expanders = (tree->total_rows > tree->root.num_children && 
first_visible_col);
-      /*if (tree->total_rows > tree->root.num_children && first_visible_col)
-         first_col_xoffset = 18 + CELL_HMARGINS;
-      else
-         first_col_xoffset = 0;*/
       
       for (l = tree->row_objects; l; l = l->next)
       {
@@ -1866,7 +2016,7 @@
          {
             /* If there is still a row to render, we render the content of the 
row */
             evas_object_move(row_object->background, geometry.x, geometry.y + 
row_y);
-            evas_object_resize(row_object->background, geometry.w, 
tree->row_height);
+            evas_object_resize(row_object->background, geometry.w, 
tree->rows_height);
             evas_object_show(row_object->background);
             
             edje_object_signal_emit(row_object->background,
@@ -1899,7 +2049,7 @@
                   cell_geometry.x = geometry.x + col->xoffset + CELL_HMARGINS;
                   cell_geometry.y = geometry.y + row_y + CELL_VMARGINS;
                   cell_geometry.w = col->width - (2 * CELL_HMARGINS);
-                  cell_geometry.h = tree->row_height - (2 * CELL_VMARGINS);
+                  cell_geometry.h = tree->rows_height - (2 * CELL_VMARGINS);
                   
                   /* Render the expander of the row */
                   if (col == first_visible_col && show_expanders)
@@ -1942,7 +2092,7 @@
          }
          
          row = _etk_tree2_row_next_to_render_get(row, &depth);
-         row_y += tree->row_height;
+         row_y += tree->rows_height;
          row_id++;
       }
    }
@@ -2061,6 +2211,28 @@
    etk_widget_theme_signal_emit(tree->grid, "etk,state,unfocused", ETK_FALSE);
 }
 
+/* Called when a key is pressed while the tree is focused */
+static void _etk_tree2_key_down_cb(Etk_Object *object, Etk_Event_Key_Down 
*event, void *data)
+{
+   Etk_Tree2 *tree;
+   
+   if (!(tree = ETK_TREE2(object)))
+      return;
+   
+   if (event->modifiers == ETK_MODIFIER_NONE)
+   {
+   }
+   else if (event->modifiers & ETK_MODIFIER_CTRL)
+   {
+      /* CTRL + A: Select all the rows */
+      if (strcmp(event->keyname, "a") == 0)
+      {
+         etk_tree2_select_all(tree);
+         etk_signal_stop();
+      }
+   }
+}
+
 /**************************
  * Tree Scroll Content
  **************************/
@@ -2255,20 +2427,30 @@
 {
    Etk_Tree2_Row_Object *row_object;
    Etk_Event_Mouse_Down event;
-   //Evas_Coord x, y, w, h;
    
    if (!(row_object = data) || !row_object->row)
       return;
    
    etk_event_mouse_down_wrap(ETK_WIDGET(row_object->row->tree), event_info, 
&event);
    
-   /* Selects the corresponding row(s) */
-   _etk_tree2_row_select(row_object->row->tree, row_object->row, 
event.modifiers);
+   /* We do not select a row on the "key-down" event if the row is already 
selected
+    * to allow the user to drag and drop several rows. The selection will be 
done on "key-up" */
+   if (!row_object->row->selected || event.modifiers != ETK_MODIFIER_NONE)
+      _etk_tree2_row_select(row_object->row->tree, row_object->row, 
event.modifiers);
 }
 
 /* Called when the background of a row is released by the mouse */
 static void _etk_tree2_row_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, 
void *event_info)
 {
+   Etk_Tree2_Row_Object *row_object;
+   Etk_Event_Mouse_Up event;
+   
+   if (!(row_object = data) || !row_object->row)
+      return;
+   
+   etk_event_mouse_up_wrap(ETK_WIDGET(row_object->row->tree), event_info, 
&event);
+   if (row_object->row->selected && event.modifiers == ETK_MODIFIER_NONE)
+      _etk_tree2_row_select(row_object->row->tree, row_object->row, 
ETK_MODIFIER_NONE);
 }
 
 /* Called when the expander of a row is released by the mouse */
@@ -2297,6 +2479,133 @@
  *
  **************************/
 
+/* A job called when rows need to be deleted */
+static void _etk_tree2_purge_job(void *data)
+{
+   Etk_Tree2 *tree;
+   
+   if (!(tree = ETK_TREE2(data)))
+      return;
+   
+   _etk_tree2_purge(tree);
+   tree->purge_job = NULL;
+}
+
+/* Deletes effectively all the rows marked as deleted */
+static void _etk_tree2_purge(Etk_Tree2 *tree)
+{
+   Evas_List *l;
+   Etk_Tree2_Row *row, *r, *next;
+   int i;
+   
+   if (!tree)
+      return;
+   
+   /* First we dissociate the row objects from the rows that will be deleted */
+   for (l = tree->row_objects; l; l = l->next)
+   {
+      Etk_Tree2_Row_Object *row_object;
+      
+      row_object = l->data;
+      if (row_object->row && row_object->row->delete_me)
+      {
+         etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_HIDDEN_SIGNAL], 
ETK_OBJECT(tree), NULL, row_object->row);
+         row_object->row = NULL;
+      }
+   }
+   
+   /* Then we delete all the rows of the purge pool */
+   while (tree->purge_pool)
+   {
+      row = tree->purge_pool->data;
+      row->next = NULL;
+      for (r = row; r; r = next)
+      {
+         /* Get the next row to free after this one */
+         if (r->first_child)
+         {
+            r->last_child->next = r->next;
+            r->next = r->first_child;
+         }
+         next = r->next;
+         
+         /* Free the row */
+         if (r->cells_data)
+         {
+            for (i = 0; i < tree->num_cols; i++)
+            {
+               if (tree->columns[i]->model->cell_data_free)
+                  
tree->columns[i]->model->cell_data_free(tree->columns[i]->model, 
r->cells_data[i]);
+               free(r->cells_data[i]);
+            }
+            free(r->cells_data);
+         }
+         
+         if (r->data && r->data_free_cb)
+            r->data_free_cb(r->data);
+         
+         free(r);
+      }
+      tree->purge_pool = evas_list_remove_list(tree->purge_pool, 
tree->purge_pool);
+   }
+}
+
+/* Moves a row of the tree to the list of rows to delete during the next 
iteration */
+static void _etk_tree2_row_move_to_purge_pool(Etk_Tree2_Row *row)
+{
+   Etk_Tree2 *tree;
+   Etk_Tree2_Row *r;
+   
+   if (!row || row->delete_me)
+      return;
+   
+   tree = row->tree;
+   
+   /* Mark the row and all its children as deleted */
+   row->delete_me = ETK_TRUE;
+   tree->total_rows--;
+   for (r = row->first_child; r; )
+   {
+      r->delete_me = ETK_TRUE;
+      tree->total_rows--;
+      
+      if (r->first_child)
+         r = r->first_child;
+      else
+      {
+         while (r && !r->next)
+         {
+            if (r->parent == row)
+               r = NULL;
+            else
+               r = r->parent;
+         }
+         r = r ? r->next : NULL;
+      }
+   }
+   
+   /* Move the row to the purge_pool */
+   if (row->prev)
+      row->prev->next = row->next;
+   if (row->next)
+      row->next->prev = row->prev;
+   if (row->parent)
+   {
+      if (row->parent->first_child == row)
+         row->parent->first_child = row->next;
+      if (row->parent->last_child == row)
+         row->parent->last_child = row->prev;
+      row->parent->num_children--;
+   }
+   for (r = row->parent; r && r->unfolded; r = r->parent)
+      r->num_visible_children -= row->num_visible_children + 1;
+   
+   tree->purge_pool = evas_list_append(tree->purge_pool, row);
+   
+   if (!tree->purge_job)
+      tree->purge_job = ecore_job_add(_etk_tree2_purge_job, tree);
+}
+
 /* Creates the Evas objects of the corresponding column */
 static void _etk_tree2_col_realize(Etk_Tree2 *tree, int col_nth)
 {
@@ -2347,29 +2656,21 @@
    return NULL;
 }
 
-/* Sets the fields of a row */
-static void _etk_tree2_row_fields_set_valist_full(Etk_Tree2_Row *row, va_list 
args, Etk_Bool emit_signal)
+/* Gets the next row after the specified row */
+/* TODO: make it public?? */
+static Etk_Tree2_Row *_etk_tree2_row_next_get_full(Etk_Tree2_Row *row, 
Etk_Bool only_visible)
 {
-   Etk_Tree2_Col *col;
-   va_list args2;
-   
    if (!row)
-      return;
+      return NULL;
    
-   va_copy(args2, args);
-   while ((col = va_arg(args2, Etk_Tree2_Col *)))
+   if (row->first_child && (row->unfolded || !only_visible))
+      return row->first_child;
+   else
    {
-      if (col->model->cell_data_set)
-      {
-         col->model->cell_data_set(col->model, row->cells_data[col->id], 
&args2);
-         if (emit_signal)
-            
etk_signal_emit(_etk_tree2_col_signals[ETK_TREE2_COL_CELL_VALUE_CHANGED], 
ETK_OBJECT(col), NULL, row);
-      }
+      while (row && !row->next)
+         row = row->parent;
+      return row ? row->next : NULL;
    }
-   va_end(args2);
-   
-   if (!row->tree->frozen)
-      etk_widget_redraw_queue(ETK_WIDGET(row->tree));
 }
 
 /* Gets the next row to render */
@@ -2396,6 +2697,31 @@
    }
 }
 
+/* Sets the fields of a row */
+static void _etk_tree2_row_fields_set_valist_full(Etk_Tree2_Row *row, va_list 
args, Etk_Bool emit_signal)
+{
+   Etk_Tree2_Col *col;
+   va_list args2;
+   
+   if (!row)
+      return;
+   
+   va_copy(args2, args);
+   while ((col = va_arg(args2, Etk_Tree2_Col *)))
+   {
+      if (col->model->cell_data_set)
+      {
+         col->model->cell_data_set(col->model, row->cells_data[col->id], 
&args2);
+         if (emit_signal)
+            
etk_signal_emit(_etk_tree2_col_signals[ETK_TREE2_COL_CELL_VALUE_CHANGED], 
ETK_OBJECT(col), NULL, row);
+      }
+   }
+   va_end(args2);
+   
+   if (!row->tree->frozen)
+      etk_widget_redraw_queue(ETK_WIDGET(row->tree));
+}
+
 /* Creates a new row object and its subobjects */
 static Etk_Tree2_Row_Object *_etk_tree2_row_object_create(Etk_Tree2 *tree)
 {
@@ -2484,10 +2810,77 @@
    if (!tree || !row)
       return;
    
-   if (!(modifiers & ETK_MODIFIER_CTRL) || !row->selected)
-      etk_tree2_row_select(row);
+   if (!tree->multiple_select)
+   {
+      if (row->selected)
+      {
+         /* Unselect the row */
+         if (modifiers & ETK_MODIFIER_CTRL)
+            etk_tree2_row_unselect(row);
+      }
+      else
+      {
+         /* Unselect the selected row and select only the given row */
+         if (tree->last_selected_row && tree->last_selected_row->selected)
+            etk_tree2_row_unselect(tree->last_selected_row);
+         else
+            etk_tree2_unselect_all(tree);
+         
+         row->selected = ETK_TRUE;
+         row->tree->last_selected_row = row;
+         etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL, row);
+      }
+   }
    else
-      etk_tree2_row_unselect(row);
+   {
+      if ((modifiers & ETK_MODIFIER_SHIFT) && tree->last_selected_row)
+      {
+         Etk_Tree2_Row *r;
+         int cnt = 0;
+         
+         etk_tree2_unselect_all(tree);
+         
+         /* Walk through all the rows of the tree and select the rows
+          * between the last selected row and the given row */
+         for (r = tree->root.first_child; r; r = 
_etk_tree2_row_next_get_full(r, ETK_FALSE))
+         {
+            if (r == tree->last_selected_row)
+               cnt++;
+            if (r == row)
+               cnt++;
+            
+            if (cnt >= 1)
+               r->selected = ETK_TRUE;
+            if (cnt >= 2)
+               break;
+         }
+         
+         etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL, row);
+      }
+      /* Invert the selected state of the given row */
+      else if (modifiers & ETK_MODIFIER_CTRL)
+      {
+         if (row->selected)
+            etk_tree2_row_unselect(row);
+         else
+         {
+            row->selected = ETK_TRUE;
+            row->tree->last_selected_row = row;
+            etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL, row);
+         }
+      }
+      else
+      {
+         /* Unselect all the rows and select only the given row */
+         etk_tree2_unselect_all(tree);
+         row->selected = ETK_TRUE;
+         row->tree->last_selected_row = row;
+         etk_signal_emit(_etk_tree2_signals[ETK_TREE2_ROW_SELECTED_SIGNAL], 
ETK_OBJECT(row->tree), NULL, row);
+      }
+   }
+   
+   if (!row->tree->frozen)
+      etk_widget_redraw_queue(ETK_WIDGET(row->tree));
 }
 
 /** @} */
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_tree2.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- etk_tree2.h 28 Nov 2006 21:40:07 -0000      1.1
+++ etk_tree2.h 9 Dec 2006 09:56:33 -0000       1.2
@@ -5,6 +5,7 @@
 #include "etk_widget.h"
 #include <stdarg.h>
 #include <Evas.h>
+#include <Ecore_Job.h>
 #include "etk_types.h"
 
 /**
@@ -88,13 +89,12 @@
    int num_visible_children;
    
    void **cells_data;
-   //~ void *row_objects;
-   
    void *data;
    void (*data_free_cb)(void *data);
    
-   Etk_Bool unfolded;
-   Etk_Bool selected;
+   unsigned int delete_me : 1;
+   unsigned int unfolded : 1;
+   unsigned int selected : 1;
 };
 
 /**
@@ -121,14 +121,17 @@
    Evas_Object *headers_clip;
    Evas_Object *grid_clip;
    
-   Etk_Tree2_Row root;
    int total_rows;
+   Etk_Tree2_Row root;
+   Etk_Tree2_Row *last_selected_row;
+   Evas_List *purge_pool;
    Evas_List *row_objects;
-   int row_height;
    
+   int rows_height;
    int scroll_x;
    int scroll_y;
    
+   Ecore_Job *purge_job;
    Etk_Color separator_color;
    Etk_Bool tree_contains_headers;
    Etk_Tree2_Mode mode;
@@ -182,7 +185,7 @@
 Etk_Tree2_Row *etk_tree2_row_insert(Etk_Tree2 *tree, Etk_Tree2_Row *parent, 
Etk_Tree2_Row *after, ...);
 Etk_Tree2_Row *etk_tree2_row_insert_valist(Etk_Tree2 *tree, Etk_Tree2_Row 
*parent, Etk_Tree2_Row *after, va_list args);
 /* TODO: Etk_Tree2_Row *etk_tree2_row_insert_sorted(Etk_Tree2 *tree, 
Etk_Tree2_Row *parent, ...); */
-void           etk_tree2_row_del(Etk_Tree2_Row *row);
+void           etk_tree2_row_delete(Etk_Tree2_Row *row);
 void           etk_tree2_clear(Etk_Tree2 *tree);
 
 void etk_tree2_row_fields_set(Etk_Tree2_Row *row, ...);
@@ -190,6 +193,10 @@
 void etk_tree2_row_fields_get(Etk_Tree2_Row *row, ...);
 void etk_tree2_row_fields_get_valist(Etk_Tree2_Row *row, va_list args);
 
+void  etk_tree2_row_data_set(Etk_Tree2_Row *row, void *data);
+void  etk_tree2_row_data_set_full(Etk_Tree2_Row *row, void *data, void 
(*free_cb)(void *data));
+void *etk_tree2_row_data_get(Etk_Tree2_Row *row);
+
 void     etk_tree2_select_all(Etk_Tree2 *tree);
 void     etk_tree2_unselect_all(Etk_Tree2 *tree);
 void     etk_tree2_row_select(Etk_Tree2_Row *row);
@@ -199,6 +206,14 @@
 void     etk_tree2_row_fold(Etk_Tree2_Row *row);
 void     etk_tree2_row_unfold(Etk_Tree2_Row *row);
 Etk_Bool etk_tree2_row_is_folded(Etk_Tree2_Row *row);
+
+Etk_Tree2_Row *etk_tree2_first_row_get(Etk_Tree2 *tree);
+Etk_Tree2_Row *etk_tree2_last_row_get(Etk_Tree2 *tree);
+Etk_Tree2_Row *etk_tree2_row_prev_get(Etk_Tree2_Row *row);
+Etk_Tree2_Row *etk_tree2_row_next_get(Etk_Tree2_Row *row);
+Etk_Tree2_Row *etk_tree2_row_parent_get(Etk_Tree2_Row *row);
+Etk_Tree2_Row *etk_tree2_row_first_child_get(Etk_Tree2_Row *row);
+Etk_Tree2_Row *etk_tree2_row_last_child_get(Etk_Tree2_Row *row);
 
 /** @} */
 
===================================================================
RCS file: /cvs/e/e17/proto/etk/src/lib/etk_types.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -3 -r1.58 -r1.59
--- etk_types.h 28 Nov 2006 21:40:07 -0000      1.58
+++ etk_types.h 9 Dec 2006 09:56:33 -0000       1.59
@@ -57,8 +57,9 @@
 typedef struct Etk_Event_Mouse_Up Etk_Event_Mouse_Up;
 typedef struct Etk_Event_Mouse_Wheel Etk_Event_Mouse_Wheel;
 typedef struct _Etk_Event_Selection_Request Etk_Event_Selection_Request;
-typedef struct Etk_Frame Etk_Frame;
 typedef struct _Etk_Filechooser_Widget Etk_Filechooser_Widget;
+typedef struct Etk_Fixed Etk_Fixed;
+typedef struct Etk_Frame Etk_Frame;
 typedef struct Etk_Iconbox Etk_Iconbox;
 typedef struct Etk_Iconbox_Icon Etk_Iconbox_Icon;
 typedef struct Etk_Iconbox_Model Etk_Iconbox_Model;



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to