Enlightenment CVS committal

Author  : dj2
Project : e17
Module  : libs/ewl

Dir     : e17/libs/ewl/src/lib


Modified Files:
        ewl_model.c ewl_model.h ewl_tree2.c ewl_tree2.h 


Log Message:
- Working on expansion points. You can now expand and contract nodes and
  specify in code if they should expand and collapse.

- Need to figure out how to deal with selections and expansion points.


===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_model.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -3 -r1.11 -r1.12
--- ewl_model.c 4 Jan 2007 05:09:47 -0000       1.11
+++ ewl_model.c 8 Jan 2007 13:02:35 -0000       1.12
@@ -93,65 +93,66 @@
 }
 
 /**
- * @param m: The Ewl_Model to set the subfetch callback into
- * @param get: The Ewl_Model_Subfetch callback for subrows
- * @return Returns no value.
- * @brief Sets the subfetch callback into the model
+ * @param m: The model to set the callback on
+ * @param exp: The expandable callback
+ * @return Returns no value
+ * @brief Sets the expandable callback on the given model
  */
 void
-ewl_model_subfetch_set(Ewl_Model *m, Ewl_Model_Subfetch get)
+ewl_model_expandable_set(Ewl_Model *m, Ewl_Model_Expandable exp)
 {
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("m", m);
 
-       m->subfetch = get;
+       m->expandable = exp;
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
 /**
- * @param m: The Ewl_Model to get the subfetch callback from
- * @return Returns the Ewl_Model_Subfetch for the subfetch callback
- * @brief Gets the subfetch callback from the model
+ * @param m: The model to get the expandable callback from
+ * @return Returns the expandable callback set on the model
+ * @brief Retrieves the expandable callback set on the model
  */
-Ewl_Model_Subfetch
-ewl_model_subfetch_get(Ewl_Model *m)
+Ewl_Model_Expandable
+ewl_model_expandable_get(Ewl_Model *m)
 {
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("m", m, NULL);
 
-       DRETURN_INT(m->subfetch, DLEVEL_STABLE);
+       DRETURN_PTR(m->expandable, DLEVEL_STABLE);
 }
 
 /**
- * @param m: The model to set the callback on
- * @param exp: The expandable callback
- * @return Returns no value
- * @brief Sets the expandable callback on the given model
+ * @param m: The Ewl_Model to set the expansion_data callback into
+ * @param get: The Ewl_Model_Expansion_Data_Fetch callback for subrows
+ * @return Returns no value.
+ * @brief Sets the subfetch callback into the model
  */
 void
-ewl_model_expandable_set(Ewl_Model *m, Ewl_Model_Expandable exp)
+ewl_model_expansion_data_fetch_set(Ewl_Model *m, 
+                               Ewl_Model_Expansion_Data_Fetch get)
 {
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("m", m);
 
-       m->expandable = exp;
+       m->expansion_data = get;
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
 /**
- * @param m: The model to get the expandable callback from
- * @return Returns the expandable callback set on the model
- * @brief Retrieves the expandable callback set on the model
+ * @param m: The Ewl_Model to get the expansion_data callback from
+ * @return Returns the Ewl_Model_Expansion_Data_Fetch for the model
+ * @brief Gets the expansion_data callback from the model
  */
-Ewl_Model_Expandable
-ewl_model_expandable_get(Ewl_Model *m)
+Ewl_Model_Expansion_Data_Fetch
+ewl_model_expansion_data_fetch_get(Ewl_Model *m)
 {
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("m", m, NULL);
 
-       DRETURN_PTR(m->expandable, DLEVEL_STABLE);
+       DRETURN_INT(m->expansion_data, DLEVEL_STABLE);
 }
 
 /**
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_model.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -3 -r1.14 -r1.15
--- ewl_model.h 4 Jan 2007 05:09:47 -0000       1.14
+++ ewl_model.h 8 Jan 2007 13:02:35 -0000       1.15
@@ -24,20 +24,6 @@
                                                unsigned int column);
 
 /**
- * @def EWL_MODEL_DATA_SUBFETCH(f)
- * Model callback to handle fetching the data for a given parent at a 
- * given row/column
- */
-#define EWL_MODEL_DATA_SUBFETCH(f) ((Ewl_Model_Subfetch)f)
-
-/**
- * A typedef to shorten the definition of the model_subfetch callbacks. 
- */
-typedef void *(*Ewl_Model_Subfetch)(void *data, unsigned int parent,
-                               unsigned int row, unsigned int column);
-
-
-/**
  * @def EWL_MODEL_DATA_EXPANDABLE(f)
  * Model callback to handle fetching the expandable flag for a given row of
  * the tree
@@ -50,6 +36,17 @@
 typedef int (*Ewl_Model_Expandable)(void *data, unsigned int row);
 
 /**
+ * @def EWL_MODEL_EXPANSION_DATA_FETCH(f)
+ * Model callback to get the expansion data for a specific row
+ */
+#define EWL_MODEL_EXPANSION_DATA_FETCH(f) ((Ewl_Model_Expansion_Data_Fetch)f)
+
+/**
+ * A typedef to shorten the definition of the model_expansion_data callback
+ */
+typedef void *(*Ewl_Model_Expansion_Data_Fetch)(void *data, unsigned int row);
+
+/**
  * @def EWL_MODEL_DATA_SORT(f)
  * Model callback to inform the program to sort it's data in the given
  * column
@@ -91,7 +88,7 @@
 {
        Ewl_Model_Fetch fetch;    /**< Retrieve data for a cell */
        Ewl_Model_Expandable expandable; /**< Is the row expandable */
-       Ewl_Model_Subfetch subfetch; /**< Check for subdata */
+       Ewl_Model_Expansion_Data_Fetch expansion_data; /**< Get expansion data 
*/
        Ewl_Model_Sort sort;      /**< Trigger sort on column */
        Ewl_Model_Count count;    /**< Count of data items */
 };
@@ -107,9 +104,9 @@
 void            ewl_model_expandable_set(Ewl_Model *m, Ewl_Model_Expandable 
exp);
 Ewl_Model_Expandable ewl_model_expandable_get(Ewl_Model *m);
 
-void            ewl_model_subfetch_set(Ewl_Model *m, 
-                                               Ewl_Model_Subfetch get);
-Ewl_Model_Subfetch ewl_model_subfetch_get(Ewl_Model *m);
+void            ewl_model_expansion_data_fetch_set(Ewl_Model *m, 
+                                       Ewl_Model_Expansion_Data_Fetch get);
+Ewl_Model_Expansion_Data_Fetch ewl_model_expansion_data_fetch_get(Ewl_Model 
*m);
 
 void            ewl_model_sort_set(Ewl_Model *m, Ewl_Model_Sort sort);
 Ewl_Model_Sort   ewl_model_sort_get(Ewl_Model *m);
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_tree2.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -3 -r1.45 -r1.46
--- ewl_tree2.c 8 Jan 2007 02:47:15 -0000       1.45
+++ ewl_tree2.c 8 Jan 2007 13:02:35 -0000       1.46
@@ -7,16 +7,16 @@
 typedef struct Ewl_Tree2_Branch_Cache Ewl_Tree2_Branch_Cache;
 struct Ewl_Tree2_Branch_Cache
 {
-       int relative_row;
        int row_count;
-       int absolute_row;
        void *data;
-       Ewl_Tree2_Branch_Cache *parent;
-       Ecore_DList *branches;
 };
 
 static void ewl_tree2_cb_view_change(Ewl_MVC *mvc);
 static void ewl_tree2_build_tree(Ewl_Tree2 *tree);
+static void ewl_tree2_build_tree_rows(Ewl_Tree2 *tree, 
+                       Ewl_Tree2_Branch_Cache *curbranch, 
+                       int colour, Ewl_Widget *parent, 
+                       int hidden);
 static void ewl_tree2_cb_column_free(void *data);
 static void ewl_tree2_cb_header_changed(Ewl_Widget *w, void *ev, 
                                                        void *data);
@@ -26,6 +26,8 @@
 static void ewl_tree2_cb_selected_change(Ewl_MVC *mvc);
 static Ewl_Widget *ewl_tree2_widget_at(Ewl_MVC *mvc, int row, int column);
 
+static void ewl_tree2_create_expansions_hash(Ewl_Tree2 *tree);
+
 /**
  * @return Returns NULL on failure, a new tree widget on success.
  * @brief Allocate and initialize a new tree widget
@@ -371,6 +373,134 @@
 }
 
 /**
+ * @param tree: The tree to set the expansion into
+ * @param data: The data that contains the expansion
+ * @param row: The row to expand
+ * @return Returns no value
+ * @brief When the tree displays the data in @a data it will expand the give
+ * @a row. This @a data is the parent of the expansion row.
+ */
+void
+ewl_tree2_row_expand(Ewl_Tree2 *tree, void *data, unsigned int row)
+{
+       Ecore_List *exp;
+       int i;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("tree", tree);
+       DCHECK_PARAM_PTR("data", data);
+       DCHECK_TYPE("tree", tree, EWL_TREE2_TYPE);
+
+       /* nothing to do if already expanded */
+       if (ewl_tree2_row_expanded_is(tree, data, row)) DRETURN(DLEVEL_STABLE);
+
+       if (!tree->expansions)
+       {
+               ewl_tree2_create_expansions_hash(tree);
+               exp = ecore_list_new();
+       }
+       else
+       {
+               exp = ecore_hash_get(tree->expansions, data);
+               if (!exp) exp = ecore_list_new();
+       }
+
+       ecore_list_goto_first(exp);
+       while ((i = (int)ecore_list_next(exp)))
+       {
+               if (i > row) break;
+       }
+
+       ecore_list_insert(exp, (void *)row);
+       ecore_hash_set(tree->expansions, data, exp);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param tree: The tree to collapse the row of
+ * @param data: The data that contains the collapsed row
+ * @param row: The row to collapse
+ * @return Returns no value
+ * @brief Sets the given @a row to collapsed for the given @a data in @a
+ * tree
+ */
+void
+ewl_tree2_row_collapse(Ewl_Tree2 *tree, void *data, unsigned int row)
+{
+       Ecore_List *exp;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("tree", tree);
+       DCHECK_PARAM_PTR("data", data);
+       DCHECK_TYPE("tree", tree, EWL_TREE2_TYPE);
+
+       /* if this tree has no expansions we're done */
+       if (!tree->expansions) DRETURN(DLEVEL_STABLE);
+
+       exp = ecore_hash_get(tree->expansions, data);
+
+       /* if no expansion points for this data we're done */
+       if (!exp) DRETURN(DLEVEL_STABLE);
+
+       /* nothing to do if the row isn't expanded */
+       if (!ewl_tree2_row_expanded_is(tree, data, row)) DRETURN(DLEVEL_STABLE);
+
+       /* we found the item so we can remove it */
+       ecore_list_remove(exp);
+
+       /* no expansions left we can remove this data from the hash */
+       if (ecore_list_is_empty(exp))
+       {
+               ecore_hash_remove(tree->expansions, data);
+               ecore_list_destroy(exp);
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param tree: The tree to work with
+ * @param data: The set of data to work with
+ * @param row: The row to check
+ * @return Returns TRUE if the given row is expanded, FALSE otherwise
+ * @brief Checks if @a row is expanded in @a data of @a tree
+ */
+unsigned int
+ewl_tree2_row_expanded_is(Ewl_Tree2 *tree, void *data, unsigned int row)
+{
+       Ecore_List *exp;
+       int i, expanded = FALSE;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("tree", tree, FALSE);
+       DCHECK_PARAM_PTR_RET("data", data, FALSE);
+       DCHECK_TYPE_RET("tree", tree, EWL_TREE2_TYPE, FALSE);
+
+       /* no expansions in the tree */
+       if (!tree->expansions) DRETURN_INT(FALSE, DLEVEL_STABLE);
+
+       exp = ecore_hash_get(tree->expansions, data);
+
+       /* no expansions in this data we're done */
+       if (!exp) DRETURN_INT(FALSE, DLEVEL_STABLE);
+
+       /* search for this row in the expansions */
+       ecore_list_goto_first(exp);
+       while ((i = (int)ecore_list_current(exp)))
+       {
+               if (i == row)
+               {
+                       expanded = TRUE;
+                       break;
+               }
+               ecore_list_next(exp);
+       }
+       
+       DRETURN_INT(expanded, DLEVEL_STABLE);
+}
+
+/**
  * @internal
  * @param w: The widget to work with
  * @param ev: UNUSED
@@ -390,6 +520,7 @@
        t = EWL_TREE2(w);
 
        ecore_list_destroy(t->columns);
+       if (t->expansions) ecore_hash_destroy(t->expansions);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
@@ -598,9 +729,9 @@
 ewl_tree2_build_tree(Ewl_Tree2 *tree)
 {
        Ewl_Tree2_Column *col;
-       int column = 0, rows = 0, i, subi;
+       int column = 0, rows = 0;
        void *mvc_data;
-       Ewl_Tree2_Branch_Cache *curbranch, *head;
+       Ewl_Tree2_Branch_Cache *head;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("tree", tree);
@@ -621,62 +752,106 @@
                column ++;
        }
 
-       head = curbranch = NEW(Ewl_Tree2_Branch_Cache, 1);
+       head = NEW(Ewl_Tree2_Branch_Cache, 1);
        head->row_count = rows;
+       head->data = mvc_data;
 
        ewl_container_reset(EWL_CONTAINER(tree->rows));
-       i = subi = 0;
+       ewl_tree2_build_tree_rows(tree, head, 0, tree->rows, FALSE);
+       FREE(head);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+static void
+ewl_tree2_build_tree_rows(Ewl_Tree2 *tree, Ewl_Tree2_Branch_Cache *curbranch, 
+                               int colour, Ewl_Widget *parent, int hidden)
+{
+       Ewl_Tree2_Column *col;
+       int i = 0, column;
+
+       DCHECK_PARAM_PTR("tree", tree);
+       DCHECK_PARAM_PTR("curbranch", curbranch);
+       DCHECK_PARAM_PTR("parent", parent);
+
        while (curbranch)
        {
-               Ewl_Widget *row;
-               Ewl_Widget *p;
+               Ewl_Widget *row, *node;
 
-               p = tree->rows;
+               node = ewl_tree2_node_new();
+               EWL_TREE2_NODE(node)->tree = EWL_WIDGET(tree);
+               EWL_TREE2_NODE(node)->row_num = i;
+
+               ewl_container_child_append(EWL_CONTAINER(parent), node);
+               if (!hidden)
+                       ewl_widget_show(node);
 
                row = ewl_row_new();
                ewl_row_header_set(EWL_ROW(row), EWL_ROW(tree->header));
+               ewl_container_child_append(EWL_CONTAINER(node), row);
                ewl_attach_widget_association_set(row, tree);
                ewl_callback_append(row, EWL_CALLBACK_CLICKED,  
                                        ewl_tree2_cb_row_clicked, NULL);
+               EWL_TREE2_NODE(node)->row = row;
                ewl_widget_show(row);
 
-               if (i % 2)
+               if (colour)
                        ewl_widget_state_set(row, "odd", EWL_STATE_PERSISTENT);
                else
                        ewl_widget_state_set(row, "even", EWL_STATE_PERSISTENT);
+               colour = (colour + 1) % 2;
+
+               /* do the current branch */
+               column = 0;
+               ecore_list_goto_first(tree->columns);
+               while((col = ecore_list_next(tree->columns)))
+               {
+                       ewl_tree2_column_build(EWL_ROW(row), col, 
curbranch->data, i, column);
+                       column ++;
+               }
 
+               /* check if this is an expansion point */
                col = ecore_list_goto_first(tree->columns);
                if (col && col->model->expandable &&
-                               col->model->expandable(mvc_data, i) && 0 /* 
check if row is expanded */) {
+                               col->model->expandable(curbranch->data, i))
+               {
                        Ewl_Tree2_Branch_Cache *tmp;
+                       int hidden = TRUE;
 
                        tmp = NEW(Ewl_Tree2_Branch_Cache, 1);
-                       tmp->parent = curbranch;
+                       tmp->data = col->model->expansion_data(curbranch->data, 
i);
+                       tmp->row_count = 0;
 
-                       curbranch = tmp;
-                       printf("Expandable row %d found\n", i);
-               }
+                       ewl_tree2_node_expandable_set(EWL_TREE2_NODE(node), 
curbranch->data);
 
-               column = 0;
-               while((col = ecore_list_next(tree->columns)))
-               {
-                       ewl_tree2_column_build(EWL_ROW(row), col, mvc_data, i, 
column);
-                       column ++;
-               }
+                       if (col->model->expansion_data &&
+                               ewl_tree2_row_expanded_is(tree, 
curbranch->data, i))
+                       {
+                               ewl_tree2_node_expand(EWL_TREE2_NODE(node));
+                               hidden = FALSE;
+                       }
+
+                       /* XXX probably need a better way to do this? */
+                       ecore_list_goto_first(tree->columns);
+                       while ((col = ecore_list_next(tree->columns)))
+                       {
+                               int r;
+                               r = col->model->count(tmp->data);
+                               if (r > tmp->row_count) tmp->row_count = r;
 
-               ewl_container_child_append(EWL_CONTAINER(p), row);
-               i++;
+                               column ++;
+                       }
 
-               subi++;
+                       ewl_tree2_build_tree_rows(tree, tmp, colour, node, 
hidden);
+                       FREE(tmp);
+               }
+               i++;
 
                /*
                 * Finished the rows at this level? Jump back up a level.
                 */
-               if (subi >= curbranch->row_count) {
-                       curbranch = curbranch->parent;
-                       if (curbranch)
-                               subi = curbranch->relative_row;
-               }
+               if (i >= curbranch->row_count) 
+                       break;
        }
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -976,4 +1151,386 @@
 
        DRETURN_INT(c->sort, DLEVEL_STABLE);
 }
+
+Ewl_Widget *
+ewl_tree2_node_new(void)
+{
+       Ewl_Widget *w;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       w = NEW(Ewl_Tree2_Node, 1);
+       if (!w)
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+
+       if (!ewl_tree2_node_init(EWL_TREE2_NODE(w)))
+       {
+               ewl_widget_destroy(w);
+               w = NULL;
+       }
+
+       DRETURN_PTR(w, DLEVEL_STABLE);
+}
+
+int
+ewl_tree2_node_init(Ewl_Tree2_Node *node)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("node", node, FALSE);
+
+       if (!ewl_container_init(EWL_CONTAINER(node)))
+               DRETURN_INT(FALSE, DLEVEL_STABLE);
+
+       ewl_widget_appearance_set(EWL_WIDGET(node), EWL_TREE2_NODE_TYPE);
+       ewl_widget_inherit(EWL_WIDGET(node), EWL_TREE2_NODE_TYPE);
+
+       ewl_container_show_notify_set(EWL_CONTAINER(node),
+                               ewl_tree2_cb_node_child_show);
+       ewl_container_hide_notify_set(EWL_CONTAINER(node),
+                               ewl_tree2_cb_node_child_hide);
+       ewl_container_resize_notify_set(EWL_CONTAINER(node),
+                               ewl_tree2_cb_node_resize);
+       ewl_container_add_notify_set(EWL_CONTAINER(node),
+                               ewl_tree2_cb_node_child_add);
+       ewl_container_remove_notify_set(EWL_CONTAINER(node),
+                               ewl_tree2_cb_node_child_del);
+
+       ewl_object_fill_policy_set(EWL_OBJECT(node), 
+                               EWL_FLAG_FILL_HFILL | EWL_FLAG_FILL_HSHRINK);
+
+       ewl_callback_append(EWL_WIDGET(node), EWL_CALLBACK_CONFIGURE,
+                                       ewl_tree2_cb_node_configure, NULL);
+
+       node->expanded = EWL_TREE_NODE_COLLAPSED;
+       ewl_widget_focusable_set(EWL_WIDGET(node), FALSE);
+
+       DRETURN_INT(TRUE, DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_node_expandable_set(Ewl_Tree2_Node *node, void *data)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("node", node);
+
+       if (node->data == data)
+               DRETURN(DLEVEL_STABLE);
+
+       node->data = data;
+       if (data)
+       {
+               node->handle = ewl_check_new();
+               ewl_object_fill_policy_set(EWL_OBJECT(node->handle),
+                                               EWL_FLAG_FILL_NONE);
+               ewl_object_alignment_set(EWL_OBJECT(node->handle),
+                                               EWL_FLAG_ALIGN_TOP);
+               ewl_container_child_prepend(EWL_CONTAINER(node), node->handle);
+               ewl_callback_append(node->handle, EWL_CALLBACK_VALUE_CHANGED,
+                                               ewl_tree2_cb_node_toggle, node);
+               ewl_widget_show(node->handle);
+       }
+       else if (node->handle)
+       {
+               ewl_widget_destroy(node->handle);
+               node->handle = NULL;
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+unsigned int
+ewl_tree2_node_expandable_get(Ewl_Tree2_Node *node)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("node", node, FALSE);
+
+       DRETURN_INT((node->data ? TRUE : FALSE), DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_node_expand(Ewl_Tree2_Node *node)
+
+{
+       Ewl_Widget *child;
+       Ecore_List *tmp;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       if (node->expanded == EWL_TREE_NODE_EXPANDED)
+               DRETURN(DLEVEL_STABLE);
+
+       /*
+        * Queue the parent tree for configure, this handles the issue of
+        * redrawing the alternating colors on expand and doing it early
+        * avoids duplicate or long list walks for queueing child widgets.
+        */
+       ewl_widget_configure(node->tree);
+
+       tmp = ecore_list_new();
+
+       ecore_dlist_goto_first(EWL_CONTAINER(node)->children);
+       while ((child = ecore_dlist_next(EWL_CONTAINER(node)->children)))
+       {
+               if ((child != node->handle) && (child != node->row))
+                       ecore_list_append(tmp, child);
+       }
+
+       while ((child = ecore_list_remove_first(tmp)))
+               ewl_widget_show(child);
+
+       ecore_list_destroy(tmp);
+
+       ewl_tree2_row_expand(EWL_TREE2(node->tree), node->data, node->row_num);
+
+       node->expanded = EWL_TREE_NODE_EXPANDED;
+       ewl_check_checked_set(EWL_CHECK(node->handle), TRUE);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_node_collapse(Ewl_Tree2_Node *node)
+{
+       Ewl_Widget *child;
+       Ecore_List *tmp;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       if (node->expanded == EWL_TREE_NODE_COLLAPSED)
+               DRETURN(DLEVEL_STABLE);
+
+       /*
+        * Queue the parent tree for configure, this handles the issue of
+        * redrawing the alternating colors on expand and doing it early
+        * avoids duplicate or long list walks for queueing child widgets.
+        */
+       ewl_widget_configure(node->tree);
+
+       tmp = ecore_list_new();
+
+       ecore_dlist_goto_first(EWL_CONTAINER(node)->children);
+       while ((child = ecore_dlist_next(EWL_CONTAINER(node)->children)))
+       {
+               if ((child != node->handle) && (child != node->row))
+                       ecore_list_append(tmp, child);
+       }
+
+       while ((child = ecore_list_remove_first(tmp)))
+               ewl_widget_hide(child);
+
+       ecore_list_destroy(tmp);
+
+       ewl_tree2_row_collapse(EWL_TREE2(node->tree), node->data, 
node->row_num);
+
+       node->expanded = EWL_TREE_NODE_COLLAPSED;
+       ewl_check_checked_set(EWL_CHECK(node->handle), FALSE);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+unsigned int
+ewl_tree2_node_expanded_is(Ewl_Tree2_Node *node)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("node", node, FALSE);
+
+       DRETURN_INT(((node->expanded == EWL_TREE_NODE_EXPANDED) ? TRUE : 
FALSE), DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_configure(Ewl_Widget *w, void *ev_data __UNUSED__, void 
*user_data __UNUSED__)
+{
+       Ewl_Tree2_Node *node;
+       Ewl_Container *c;
+       Ewl_Object *child;
+       int x, y, hw = 0;
+
+       DENTER_FUNCTION(DLEVEL_STABLE); 
+       DCHECK_PARAM_PTR("w", w);       
+       DCHECK_TYPE("w", w, EWL_WIDGET_TYPE);
+       
+       node = EWL_TREE2_NODE(w);
+       if (!node->tree)
+               DRETURN(DLEVEL_STABLE);
+       
+       c = EWL_CONTAINER(w);
+       if (!c->children)
+               DRETURN(DLEVEL_STABLE);
+
+       ecore_dlist_goto_first(c->children);
+       x = CURRENT_X(w);
+       y = CURRENT_Y(w);
+
+       if (node->handle) 
+       {
+               ewl_object_geometry_request(EWL_OBJECT(node->handle),
+                               CURRENT_X(w), CURRENT_Y(w), CURRENT_W(w),
+                               CURRENT_H(w));
+               hw = ewl_object_current_w_get(EWL_OBJECT(node->handle));
+               x += hw;
+       }
+
+       /*
+        * All subsequent children are lower nodes and rows.
+        */
+       while ((child = ecore_dlist_next(c->children))) 
+       {
+               if (VISIBLE(child) && EWL_WIDGET(child) != node->handle) 
+               {
+                       ewl_object_geometry_request(child, x, y, CURRENT_W(w) - 
hw,
+                                                   
ewl_object_preferred_h_get(child));
+                       y += ewl_object_current_h_get(child);
+               }
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_toggle(Ewl_Widget *w __UNUSED__, void *ev_data __UNUSED__, 
+                                                       void *data)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("w", w);
+       DCHECK_TYPE("w", w, EWL_WIDGET_TYPE);
+
+       if (ewl_tree2_node_expandable_get(EWL_TREE2_NODE(data)))
+       {
+               if (ewl_tree2_node_expanded_is(EWL_TREE2_NODE(data)))
+                       ewl_tree2_node_collapse(EWL_TREE2_NODE(data));
+               else
+                       ewl_tree2_node_expand(EWL_TREE2_NODE(data));
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_child_show(Ewl_Container *c, Ewl_Widget *w __UNUSED__)
+{
+       Ewl_Tree2_Node *node;
+       
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+
+       node = EWL_TREE2_NODE(c);
+       if (node->handle && node->expanded) {
+               ewl_container_sum_prefer(c, EWL_ORIENTATION_VERTICAL);
+               if (REALIZED(node->handle) && VISIBLE(node->handle))
+                       ewl_object_preferred_inner_h_set(EWL_OBJECT(c),
+                                       PREFERRED_H(c) - 
+                                       
ewl_object_preferred_h_get(EWL_OBJECT(node->handle)));
+       }
+       else 
+               ewl_object_preferred_inner_h_set(EWL_OBJECT(c),
+                                          
ewl_object_preferred_h_get(EWL_OBJECT(node->row)));
+               
+       ewl_container_largest_prefer(c, EWL_ORIENTATION_HORIZONTAL);
+       if (node->handle && REALIZED(node->handle) && VISIBLE(node->handle))
+               ewl_object_preferred_inner_w_set(EWL_OBJECT(c), PREFERRED_W(c) +
+                       ewl_object_preferred_w_get(EWL_OBJECT(node->handle)));
+
+       if (!node->expanded && node->handle)
+               ewl_widget_hide(node->handle);
+
+       ewl_widget_configure(node->tree);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_child_hide(Ewl_Container *c, Ewl_Widget *w)
+{
+       int width;
+       Ewl_Tree2_Node *node;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_PARAM_PTR("w", w);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+       DCHECK_TYPE("w", w, EWL_WIDGET_TYPE);
+
+       node = EWL_TREE2_NODE(c);
+       if (w == node->handle)
+               DRETURN(DLEVEL_STABLE);
+
+       if (ecore_dlist_nodes(c->children) < 3)
+       {
+               if (node->handle && VISIBLE(node->handle))
+                       ewl_widget_hide(node->handle);
+       }
+
+       ewl_object_preferred_inner_h_set(EWL_OBJECT(c), 
+               PREFERRED_H(c) - ewl_object_preferred_h_get(EWL_OBJECT(w)));
+
+       width = ewl_object_preferred_w_get(EWL_OBJECT(w));
+       if (PREFERRED_W(c) >= width)
+               ewl_container_largest_prefer(c, EWL_ORIENTATION_HORIZONTAL);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_resize(Ewl_Container *c, Ewl_Widget *w, int size __UNUSED__,
+                                                    Ewl_Orientation o 
__UNUSED__)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_PARAM_PTR("w", w);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+       DCHECK_TYPE("w", w, EWL_WIDGET_TYPE);
+
+       ewl_tree2_cb_node_child_show(c, w);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_child_add(Ewl_Container *c, Ewl_Widget *w __UNUSED__)
+{
+       Ewl_Tree2_Node *node;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+
+       node = EWL_TREE2_NODE(c);
+       
+       if (ecore_list_nodes(c->children) > 2)
+       {
+               /* XXX what do we do if !node->handle? */
+               if (node->handle && HIDDEN(node->handle))
+                       ewl_widget_show(node->handle);
+       }
+       else if (node->handle && VISIBLE(node->handle))
+               ewl_widget_hide(node->handle);
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void
+ewl_tree2_cb_node_child_del(Ewl_Container *c, Ewl_Widget *w, int idx 
__UNUSED__)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+
+       ewl_tree2_cb_node_child_add(c, w);
+}
+
+static void
+ewl_tree2_create_expansions_hash(Ewl_Tree2 *tree)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("tree", tree);
+       DCHECK_TYPE("tree", tree, EWL_TREE2_TYPE);
+
+       tree->expansions = ecore_hash_new(NULL, NULL);
+       ecore_hash_set_free_value(tree->expansions, 
+                       ECORE_FREE_CB(ecore_list_destroy));
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
 
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_tree2.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -3 -r1.37 -r1.38
--- ewl_tree2.h 4 Jan 2007 05:09:48 -0000       1.37
+++ ewl_tree2.h 8 Jan 2007 13:02:35 -0000       1.38
@@ -96,6 +96,8 @@
 
        Ewl_Tree_Selection_Type type;    /**< The selection type of the tree */
 
+       Ecore_Hash *expansions; /**< Hash of expanded rows */
+
        unsigned char fixed:1;    /**< Rows are fixed height */
        unsigned char headers_visible:1; /**< Are the headers visible? */
 };
@@ -151,6 +153,14 @@
 
 Ewl_Widget     *ewl_tree2_view_widget_get(Ewl_Tree2 *tree);
 
+void            ewl_tree2_row_expand(Ewl_Tree2 *tree, void *data, 
+                                               unsigned int row);
+void            ewl_tree2_row_collapse(Ewl_Tree2 *tree, void *data, 
+                                               unsigned int row);
+
+unsigned int    ewl_tree2_row_expanded_is(Ewl_Tree2 *tree, void *data,
+                                               unsigned int row);
+
 /*
  * Internal stuff.
  */
@@ -176,6 +186,49 @@
 void                    ewl_tree2_column_sort_direction_set(Ewl_Tree2_Column 
*c, 
                                                                
Ewl_Sort_Direction sort);
 Ewl_Sort_Direction      ewl_tree2_column_sort_direction_get(Ewl_Tree2_Column 
*c);
+
+/*
+ * Ewl_Tree2_Node stuff
+ */
+#define EWL_TREE2_NODE_TYPE "node"
+#define EWL_TREE2_NODE(n) ((Ewl_Tree2_Node *)n)
+typedef struct Ewl_Tree2_Node Ewl_Tree2_Node;
+struct Ewl_Tree2_Node
+{
+       Ewl_Container container;
+
+       Ewl_Widget *tree;               /**< The parent tree */
+       Ewl_Widget *row;                /**< The row this node is for */
+       Ewl_Widget *handle;             /**< the expansion handle */
+
+       void *data;                     /**< The data that this nodes row comes 
from */
+       unsigned int row_num;           /**< The row number of this row */
+       Ewl_Tree_Node_Flags expanded;
+};
+
+Ewl_Widget     *ewl_tree2_node_new(void);
+int             ewl_tree2_node_init(Ewl_Tree2_Node *node);
+
+void            ewl_tree2_node_expandable_set(Ewl_Tree2_Node *node, void 
*data);
+unsigned int    ewl_tree2_node_expandable_get(Ewl_Tree2_Node *node);
+
+void            ewl_tree2_node_expand(Ewl_Tree2_Node *node);
+void            ewl_tree2_node_collapse(Ewl_Tree2_Node *node);
+
+unsigned int    ewl_tree2_node_expanded_is(Ewl_Tree2_Node *node);
+
+void ewl_tree2_cb_node_configure(Ewl_Widget *w, void *ev_data, void 
*user_data);
+void ewl_tree2_cb_node_realize(Ewl_Widget *w, void *ev, void *data);
+void ewl_tree2_cb_node_toggle(Ewl_Widget *w, void *ev_data, void *user_data);
+
+void ewl_tree2_cb_node_child_show(Ewl_Container *c, Ewl_Widget *w);
+void ewl_tree2_cb_node_child_hide(Ewl_Container *c, Ewl_Widget *w);
+void ewl_tree2_cb_node_resize(Ewl_Container *c, Ewl_Widget *w, int size,
+                                                     Ewl_Orientation o);
+void ewl_tree2_cb_node_child_add(Ewl_Container *c, Ewl_Widget *w);
+void ewl_tree2_cb_node_child_del(Ewl_Container *c, Ewl_Widget *w, int idx);
+
+
 
 /**
  * @}



-------------------------------------------------------------------------
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