Download

Support

Ewl_Tree: A Widget for List or Tree Layout


Detailed Description

Defines a widget for laying out other widgets in a tree or list like manner. This also fulfills the functionality often seen in a table widget.

Model: Defines communication callbacks for views and controllers. Query row/column data, indicate expansion points, notify views and controllers of changes, trigger sorting on a row/column combination.

Data: Provides a wrapper to the data which allows for observer registration and a reference to a model for data access.

View: Defines the callbacks for setting up the widgets based on the data returned from the Model. Create widgets, set data on widgets, calculate sizing, minimize number of widgets.

Controller: The tree defines the entire controller and registers with the model. Provides controls to sort columns, expand/collapse branching points, reacts to changes from data model.

Simple case: Widgets packed using standard container functions. This should result in a simple list of packed widgets.

Features: * Default data provider, so standard container functions are supported. * MVC pattern of data access for more powerful layouts. * Packing of arbitrary widget types in cells. * Theming based on repeating row counts. * Number of columns dependant on number of providers, not a fixed number. * When using data providers, can reap widgets to save memory and decrease layout time.

Issues: * How do we support click callbacks on full rows? Special notifier necessary? Proposal: Tree value change callback on row selection. Passes event structure with array of selected row numbers. Simple case handled by callback on packed widgets. * Column or row layout? Column allows for redirecting to a container to handle the case of container functions used to add widgets and to use a fixed number of rows in display region. It would also allow for skipping configure of an entire off-screen column, rows would lay out the cells off-screen. How do we implement column layout? Proposal: Row height cache, easy for fixed height rows, more complex for variable height.

Remarks:
Inherits from Ewl_MVC.

Tutorial

Finding the Tree in the Forest (originally at http://everburning.com/news/finding-the-tree-in-the-forest) We've been doing a bunch of work on Ewl_Tree lately. Its been shaping up nicely at the moment. To that end, I thought Id do a quick write up on how it works and what you can do with it.

Ewl_Tree is built based on an MVC (model/view/controller) framework. This makes it a lot easier for developers to keep their data up to date without having to go through all kinds of contortions using the tree nodes and widgets as they do with the current Ewl_Tree widget.

There are three basic items youll need to become familiar with in order to use Ewl_Tree. They are, Ewl_Tree, of course, Ewl_Model and Ewl_View. These three will allow you to setup your columns and the tree.

The best way to show something is through an example, so thats what Ill do. This is basically the tree test case from ewl_test ported to run in a window. The case is pretty simple. We store an array of data, this array contains nodes that specify the text and an image to be displayed.

We then create a three column tree. The first column will show the text as an Ewl_Label widget. The second column will display an Ewl_Image. The third will be an Ewl_Button. The third column doesnt use the ewl_button code directly as we want to set two pieces of information so we write our own methods to handle the creating and assignment functions.

I'll be putting the code into tree_test.c and using the following to compile the code as I go.

 oni:~/dev/tree_test$ gcc -o tree_test tree_test.c `ewl-config --cflags --libs`

With that out of the way, on with the show. Im going to start by listing all of the code and then Ill go through it piece by piece.

 #include <Ewl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 #define DATA_ELEMENTS 5

 typedef struct Test_Row_Data Test_Row_Data;
 struct Test_Row_Data
 {
     char *image;
     char *text;
 };

 typedef struct Test_Data Test_Data;
 struct Test_Data
 {
     unsigned int count;
     Test_Row_Data **rows;
 };

 static void *test_data_setup(void);

 static Ewl_Widget *test_custom_new(void);
 static void test_custom_assign_set(Ewl_Widget *w, void *data);

 static Ewl_Widget *test_data_header_fetch(void *data, unsigned int column);
 static void *test_data_fetch(void *data, unsigned int row, unsigned int column);
 static void test_data_sort(void *data, unsigned int column, Ewl_Sort_Direction sort);
 static unsigned int test_data_count_get(void *data);

 static void cb_delete_window(Ewl_Widget *w, void *ev, void *data);
 static void cb_scroll_headers(Ewl_Widget *w, void *ev, void *data);
 static void cb_scroll_visible(Ewl_Widget *w, void *ev, void *data);

 int
 main(int argc, char ** argv)
 {
     Ewl_Widget *tree, *box, *o, *o2;
     Ewl_Model *model;
     Ewl_View *view;
     void *data;

      // make sure we can setup ewl
      if (!ewl_init(&argc, argv))
      {
          fprintf(stderr, "Unable to init ewl.n");
          return 1;
      }

      // create the window
      o = ewl_window_new();
      ewl_window_title_set(EWL_WINDOW(o), "tree example");
      ewl_window_class_set(EWL_WINDOW(o), "tree_example");
      ewl_window_name_set(EWL_WINDOW(o), "tree_example");
      ewl_object_size_request(EWL_OBJECT(o), 640, 480);
      ewl_callback_append(o, EWL_CALLBACK_DELETE_WINDOW, cb_delete_window, NULL);
      ewl_widget_show(o);

      box = ewl_vbox_new();
      ewl_container_child_append(EWL_CONTAINER(o), box);
      ewl_widget_show(box);

      o2 = ewl_hbox_new();
      ewl_container_child_append(EWL_CONTAINER(box), o2);
      ewl_object_fill_policy_set(EWL_OBJECT(o2),
                  EWL_FLAG_FILL_VSHRINK | EWL_FLAG_FILL_HFILL);
      ewl_widget_show(o2);

      // create our data
      data = test_data_setup();

      // create the model that'll be used for the first two columns
      model = ewl_model_new();
      ewl_model_data_fetch_set(model, test_data_fetch);
      ewl_model_data_sort_set(model, test_data_sort);
      ewl_model_data_count_set(model, test_data_count_get);

      tree = ewl_tree_new();
      ewl_container_child_append(EWL_CONTAINER(box), tree);
      ewl_object_fill_policy_set(EWL_OBJECT(tree), EWL_FLAG_FILL_ALL);
      ewl_tree_data_set(EWL_TREE(tree), data);
      ewl_widget_show(tree);

      // create a view for the first column that just has an ewl label
      view = ewl_view_new();
      ewl_view_constructor_set(view, ewl_label_new);
      ewl_view_assign_set(view, EWL_VIEW_ASSIGN(ewl_label_text_set));
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

      // create a view for the second column that just has an ewl image
      view = ewl_view_new();
      ewl_view_constructor_set(view, ewl_image_new);
      ewl_view_assign_set(view, EWL_VIEW_ASSIGN(ewl_image_file_path_set));
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

      // we don't want this one sortable
      model = ewl_model_new();
      ewl_model_data_fetch_set(model, test_data_fetch);
      ewl_model_data_count_set(model, test_data_count_get);

      // create a view for the third column that has a custom widget
      view = ewl_view_new();
      ewl_view_constructor_set(view, test_custom_new);
      ewl_view_assign_set(view, test_custom_assign_set);
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

      // create the checkbuttons for the top box
      o = ewl_checkbutton_new();
      ewl_button_label_set(EWL_BUTTON(o), "Scroll headers");
      ewl_container_child_append(EWL_CONTAINER(o2), o);
      ewl_callback_append(o, EWL_CALLBACK_CLICKED,
                  cb_scroll_headers, tree);
      ewl_widget_show(o);

      o = ewl_checkbutton_new();
      ewl_button_label_set(EWL_BUTTON(o), "Scroll visible");
      ewl_container_child_append(EWL_CONTAINER(o2), o);
      ewl_checkbutton_checked_set(EWL_CHECKBUTTON(o), TRUE);
      ewl_callback_append(o, EWL_CALLBACK_CLICKED,
                  cb_scroll_visible, tree);
      ewl_widget_show(o);

      ewl_main();
      return 0;
 }

 // setup our data
 static void *
 test_data_setup(void)
 {
      Test_Data *data;
      Test_Row_Data **dt;

      data = calloc(1, sizeof(Test_Data));
      dt = calloc(DATA_ELEMENTS, sizeof(Test_Row_Data *));

      dt[0] = calloc(1, sizeof(Test_Row_Data));
      dt[0]->image = strdup("/usr/local/share/ewl/images/e-logo.png");
      dt[0]->text = strdup("The E logo");

      dt[1] = calloc(1, sizeof(Test_Row_Data));
      dt[1]->image = strdup("/usr/local/share/ewl/images/elicit.png");
      dt[1]->text = strdup("The Elicit image");

      dt[2] = calloc(1, sizeof(Test_Row_Data));
      dt[2]->image = strdup("/usr/local/share/ewl/images/entrance.png");
      dt[2]->text = strdup("The Entrance image");

      dt[3] = calloc(1, sizeof(Test_Row_Data));
      dt[3]->image = strdup("/usr/local/share/ewl/images/End.png");
      dt[3]->text = strdup("Zebra");

      dt[4] = calloc(1, sizeof(Test_Row_Data));
      dt[4]->image = strdup("/usr/local/share/ewl/images/banner-top.png");
      dt[4]->text = strdup("Ant");

      data->rows = dt;
      data->count = DATA_ELEMENTS;

      return data;
 }

 static Ewl_Widget *
 test_custom_new(void)
 {
      Ewl_Widget *button;

      button = ewl_button_new();

      return button;
 }

 static void
 test_custom_assign_set(Ewl_Widget *w, void *data)
 {
      Test_Row_Data *d;

      d = data;
      ewl_button_label_set(EWL_BUTTON(w), d->text);
      ewl_button_image_set(EWL_BUTTON(w), d->image, NULL);
 }

 static Ewl_Widget *
 test_data_header_fetch(void *data , unsigned int column)
 {
      Ewl_Widget *l;

      l = ewl_label_new();
      if (column == 0)
          ewl_label_text_set(EWL_LABEL(l), "Title");
      else if (column == 1)
          ewl_label_text_set(EWL_LABEL(l), "Image");
      else
          ewl_label_text_set(EWL_LABEL(l), "Button");
      ewl_widget_show(l);

      return l;
 }

 static void *
 test_data_fetch(void *data, unsigned int row, unsigned int column)
 {
      Test_Data *d;
      void *val = NULL;

      d = data;

      if (column == 0)
          val = d->rows[row]->text;

      else if (column == 1)
          val = d->rows[row]->image;

      else if (column == 2)
          val = d->rows[row];

      return val;
 }

 static void
 test_data_sort(void *data, unsigned int column, Ewl_Sort_Direction sort)
 {
      Test_Data *d;
      int i;

      // just leave it if we're in sort none.
      if (sort == EWL_SORT_DIRECTION_NONE)
          return;

      d = data;

      for (i = (DATA_ELEMENTS - 1); i >= 0; i--)
      {
          int j;

          for (j = 1; j <= i; j++)
          {
              char *a, *b;

              if (column == 0)
              {
                  a = d->rows[j - 1]->text;
                  b = d->rows[j]->text;
              }
              else
              {
                  a = d->rows[j - 1]->image;
                  b = d->rows[j]->image;
              }

              if (((sort == EWL_SORT_DIRECTION_ASCENDING) && strcmp(a, b) > 0)
                      || ((sort == EWL_SORT_DIRECTION_DESCENDING)
                          && strcmp(a, b) < 0))
              {
                  char *temp;

                  temp = d->rows[j - 1]->text;
                  d->rows[j - 1]->text = d->rows[j]->text;
                  d->rows[j]->text = temp;

                  temp = d->rows[j - 1]->image;
                  d->rows[j - 1]->image = d->rows[j]->image;
                  d->rows[j]->image = temp;
              }
          }
      }
 }

 static unsigned int
 test_data_count_get(void *data)
 {
      Test_Data *d;

      d = data;

      return d->count;
 }

 static void
 cb_delete_window(Ewl_Widget *w, void *ev, void *data)
 {
      ewl_widget_destroy(w);
      ewl_main_quit();
 }

 static void
 cb_scroll_headers(Ewl_Widget *w, void *ev , void *data)
 {
      Ewl_Tree *tree;

      tree = data;
      ewl_tree_scroll_headers_set(tree,
              ewl_checkbutton_is_checked(EWL_CHECKBUTTON(w)));
 }

 static void
 cb_scroll_visible(Ewl_Widget *w, void *ev , void *data)
 {
      Ewl_Tree *tree;

      tree = data;
      ewl_tree_scroll_visible_set(tree,
              ewl_checkbutton_is_checked(EWL_CHECKBUTTON(w)));
 }

Simple enough, eh? Ok, maybe I should go through it then.

 #include <Ewl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

We start off with the standard set of includes. Ewl.h is obviously required to do any EWL programming. The others are needed as well be using functions they define throughout the application.

 #define DATA_ELEMENTS 5

 typedef struct Test_Row_Data Test_Row_Data;
 struct Test_Row_Data
 {
      char *image;
      char *text;
 };

 typedef struct Test_Data Test_Data;
 struct Test_Data
 {
      unsigned int count;
      Test_Row_Data **rows;
 };

I'm not planning on doing anything fancy with my data. Just keeping an array with five elements. Im using a define DATA_ELEMENTS to store the number of elements as Ill be using this in a few places. The data will be stored in a Test_Data structure. This struct will store the number of items in the array and an array of Test_Row_Data pointers. Test_Row_Data structs just store the text and image strings for each of our rows.

 static void *test_data_setup(void);

 static Ewl_Widget *test_custom_new(void);
 static void test_custom_assign_set(Ewl_Widget *w, void *data);

 static Ewl_Widget *test_data_header_fetch(void *data, unsigned int column);
 static void *test_data_fetch(void *data, unsigned int row, unsigned int column);
 static void test_data_sort(void *data, unsigned int column, Ewl_Sort_Direction sort);
 static unsigned int test_data_count_get(void *data);

 static void cb_delete_window(Ewl_Widget *w, void *ev, void *data);
 static void cb_scroll_headers(Ewl_Widget *w, void *ev, void *data);
 static void cb_scroll_visible(Ewl_Widget *w, void *ev, void *data);

As you can see, a bunch of pre-declarations next. Well be seeing, and getting the explanation for these as we go along.

 int
 main(int argc, char ** argv)
 {
      Ewl_Widget *tree, *box, *o, *o2;
      Ewl_Model *model;
      Ewl_View *view;
      void *data;

      // make sure we can setup ewl
      if (!ewl_init(&argc, argv))
      {
          fprintf(stderr, "Unable to init ewl.n");
          return 1;
      }

The first step in any EWL application is to initialize EWL itself. This is done with a call to ewl_init(). ewl_init() accepts two parameters, the argc and argv arguments that were passed to your application. ewl_init() will return TRUE if EWL was successfully initialized or FALSE otherwise. The reason to pass the args to ewl_init() is so that EWL can parse out any EWL specific arguments. Things like setting the rendering engine or printing the EWL help documentation. These parameters can both be safely set to NULL if desired.

With EWL setup we can get down the the fun bit of creating the UI.

      // create the window
      o = ewl_window_new();
      ewl_window_title_set(EWL_WINDOW(o), "tree example");
      ewl_window_class_set(EWL_WINDOW(o), "tree_example");
      ewl_window_name_set(EWL_WINDOW(o), "tree_example");
      ewl_object_size_request(EWL_OBJECT(o), 640, 480);
      ewl_callback_append(o, EWL_CALLBACK_DELETE_WINDOW, cb_delete_window, NULL);
      ewl_widget_show(o);

      box = ewl_vbox_new();
      ewl_container_child_append(EWL_CONTAINER(o), box);
      ewl_widget_show(box);

      o2 = ewl_hbox_new();
      ewl_container_child_append(EWL_CONTAINER(box), o2);
      ewl_object_fill_policy_set(EWL_OBJECT(o2), EWL_FLAG_FILL_VSHRINK | EWL_FLAG_FILL_HFILL);
      ewl_widget_show(o2);

This little chunks sets up our base UI. We create the Ewl_Window first using ewl_window_new(). We set the title, class and name for the window and then give it a default size of 640x480. Once this is done we set a callback for when the window is destroyed. This is done with ewl_callback_append() call. We want to get notified when the window receives the EWL_CALLBACK_DELETE_WINDOW callback by having the cb_delete_window() function executed.

With the main window setup we create an Ewl_Box inside of it. An Ewl_Window by default has no layout policy so if you pack several widgets into it theyll all be sitting on top of each other. You have to pack a box, or something, in there to handle the layout of the contents. Youll see we use ewl_container_child_append() to add the box to the window. Youll be seeing this a lot as we pack the UI together. There are also ewl_container_child_prepend() and ewl_container_child_insert() calls that can be used.

We also create a second Ewl_Box to hold some checkbuttons that well create later. Were creating the box here just because I like to keep things order. Its the first item in the window so I create and pack it first. We could also use ewl_container_child_prepend() later to add it to the box if we wished. Were setting a custom fill policy on this box with ewl_object_fill_policy_set(). The policy were setting is EWL_FLAG_FILL_VSHIRNK | EWL_FLAG_FILL_HFILL. Were telling the widget that we want it to be as small as possible vertically but take up as much space as possible horizontally. The fill policy is just a bit mask so were bit wise oring the values together.

I guess a quick note about EWL inheritance is necessary at some point. EWL uses an object oriented approach to its widgets. All widgets inherit from Ewl_Widget. Ewl_Widget inherits from Ewl_Object. So any ewl_widget_* or ewl_object_* call can be called on any widgets. You just need to cast to the correct type first. The casts are done with the EWL_WIDGET() or EWL_OBJECT() macros. All widgets in EWL have an EWL_WIDGET_NAME() macro. Theres a lot of inheritance going on in EWL. The Ewl_Box code inherits from the Ewl_Container code. So any ewl_container_* call will work on an Ewl_Box, you just have to wrap the box variable with an EWL_CONTAINER() call. Take a look at the EWL docs for a complete listing of the inheritance. (Or if youre looking at the header files the inheritance is always the first item in the struct.)

      // create our data
      data = test_data_setup();

This is just a convenience function to create our data array. I like to keep stuff separated out whenever possible. Well see what this does later.

      // create the model that'll be used for the first two columns
      model = ewl_model_new();
      ewl_model_data_fetch_set(model, test_data_fetch);
      ewl_model_data_sort_set(model, test_data_sort);
      ewl_model_data_count_set(model, test_data_count_get);

Our first two columns in the tree will actually use the same data model. I dont want the third column to be sortable so we need to use a slightly different model (although its almost the same). We need to set at a of minimum two pieces of data into the Ewl_Model. These are, the function to fetch the model data, set with ewl_model_data_fetch_set(), and the function to get a count of the number of rows of data, set with ewl_model_data_count_set(). I'm using the third ewl_model_data_sort_set() to set a sort function for the first two columns. Each of these calls takes the model and a function pointer. You can see the function signature at the top of the file. Well take a closer look at these functions a bit later.

      tree = ewl_tree_new();
      ewl_container_child_append(EWL_CONTAINER(box), tree);
      ewl_object_fill_policy_set(EWL_OBJECT(tree), EWL_FLAG_FILL_ALL);
      ewl_tree_data_set(EWL_TREE(tree), data);
      ewl_widget_show(tree);

Next we create the tree itself. The tree is packed into the box we created earlier. We set the box with a fill policy of EWL_FLAG_FILL_ALL so it will take as much, or as little space as necesary. We then set the data we created into the tree with ewl_tree_data_set() function. This data will be passed around to our various functions as the tree does its work.

      // create a view for the first column that just has an ewl label
      view = ewl_view_new();
      ewl_view_constructor_set(view, ewl_label_new);
      ewl_view_assign_set(view, EWL_VIEW_ASSIGN(ewl_label_text_set));
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

Ok, with our tree created we can start to add columns. Weve already created the Ewl_Model for the first two columns so we just need to create the views.

As I mentioned before the first column is using Ewl_Label to display the text of the data item. So, we create a new Ewl_View with ewl_view_new(). We then set the constructor for this column with ewl_view_constructor_set(). This will be used to create a new widget for the item in the column. Then we use ewl_view_assign_set() to set the function that will be used to assign data into our widget for a given cell. Tree columns need a header. Well set a third callback function to get the header data for the tree. We use ewl_view_header_fetch_set() to set this function.

Once our view is created we call ewl_tree_column_append() to create a new column in the tree using our model and view.

      // create a view for the second column that just has an ewl image view =
      ewl_view_new();
      ewl_view_constructor_set(view, ewl_image_new);
      ewl_view_assign_set(view, EWL_VIEW_ASSIGN(ewl_image_file_path_set));
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

The second column in the tree is created the same as the first except we use the Ewl_Image functions instead of the Ewl_Label functions. You can use any widget within EWL to setup a view. This gives the tree the flexibility of being able to display any desired widget, even custom designed widgets.

      // we don't want this one sortable
      model = ewl_model_new();
      ewl_model_data_fetch_set(model, test_data_fetch);
      ewl_model_data_count_set(model, test_data_count_get);

      // create a view for the third column that has a custom widget
      view = ewl_view_new();
      ewl_view_constructor_set(view, test_custom_new);
      ewl_view_assign_set(view, test_custom_assign_set);
      ewl_view_header_fetch_set(view, test_data_header_fetch);
      ewl_tree_column_append(EWL_TREE(tree), model, view);

The third column in the tree is similar to the first two except we dont want it sortable. So, we create a new Ewl_Model and set the fetch and count functions as before but skip the sort function. We then create the view and use our custom constructor and assignment functions instead of a standard EWL set. With the model and view created we append the column into the tree.

      // create the checkbuttons for the top box
      o = ewl_checkbutton_new();
      ewl_button_label_set(EWL_BUTTON(o), "Scroll headers");
      ewl_container_child_append(EWL_CONTAINER(o2), o);
      ewl_callback_append(o, EWL_CALLBACK_CLICKED, cb_scroll_headers, tree);
      ewl_widget_show(o);

      o = ewl_checkbutton_new();
      ewl_button_label_set(EWL_BUTTON(o), "Scroll visible");
      ewl_container_child_append(EWL_CONTAINER(o2), o);
      ewl_checkbutton_checked_set(EWL_CHECKBUTTON(o), TRUE);
      ewl_callback_append(o, EWL_CALLBACK_CLICKED, cb_scroll_visible, tree);
      ewl_widget_show(o);

The final piece of the UI to be added are the two checkbuttons. These will be used to change some settings of the tree so we can see some of the different options. The both respond to EWL_CALLBACK_CLICKED callbacks the first calling the cb_scroll_headers() function and the second calling cb_scroll_visible() function.

      ewl_main();
      return 0;
 }

Finally we call ewl_main() to kick off the main EWL event loop. When ewl_main() is done then were finished so just return. ewl_main_quit() will actually call ewl_shutdown() for us so we dont have to worry about it.

Ok, with our UI out of the way all we need to deal with are all the functions weve referenced. First up is creating our data. For this example were just using an array but the thing to keep in mind is you can use anything to store your data. EWL never accesses this data directly it always does it through the calls you specified. So, if you want to use an Evas_List or an Ecore_List or a tree or some other structure its up to you. EWL doesnt care.

 // setup our data
 static void *
 test_data_setup(void)
 {
          Test_Data *data;
          Test_Row_Data **dt;

          data = calloc(1, sizeof(Test_Data));
          dt = calloc(DATA_ELEMENTS, sizeof(Test_Row_Data *));

          dt[0] = calloc(1, sizeof(Test_Row_Data));
          dt[0]->image = strdup("/usr/local/share/ewl/images/e-logo.png");
          dt[0]->text = strdup("The E logo");

          dt[1] = calloc(1, sizeof(Test_Row_Data));
          dt[1]->image = strdup("/usr/local/share/ewl/images/elicit.png");
          dt[1]->text = strdup("The Elicit image");

          dt[2] = calloc(1, sizeof(Test_Row_Data));
          dt[2]->image = strdup("/usr/local/share/ewl/images/entrance.png");
          dt[2]->text = strdup("The Entrance image");

          dt[3] = calloc(1, sizeof(Test_Row_Data));
          dt[3]->image = strdup("/usr/local/share/ewl/images/End.png");
          dt[3]->text = strdup("Zebra");

          dt[4] = calloc(1, sizeof(Test_Row_Data));
          dt[4]->image = strdup("/usr/local/share/ewl/images/banner-top.png");
          dt[4]->text = strdup("Ant");

          data->rows = dt;
          data->count = DATA_ELEMENTS;

          return data;
 }

Nothing fancy in there so Im not going to bother explaining it.

 static Ewl_Widget *
 test_custom_new(void)
 {
      Ewl_Widget *button;
      button = ewl_button_new();
      return button;
 }

As I mentioned for our third column were using a custom constructor and assignment calls. The reason for this, since we just want a simple button, is that we want to set two pieces of data into the widget instead of just one. We could actually just use ewl_button_new() in the view and have a custom assignment function, but this makes for a better example. For the constructor all we do is create our widget and return it. Its as simple as that.

 static void
 test_custom_assign_set(Ewl_Widget *w, void *data)
 {
      Test_Row_Data *d;

      d = data;
      ewl_button_label_set(EWL_BUTTON(w), d->text);
      ewl_button_image_set(EWL_BUTTON(w), d->image, NULL);
 }

For the assignment part of the custom widget EWL will provide the widget created with the view, w, and the piece of data that the rows model returned for the current cell in the tree, data. Using these we can setup the widget however we see fit. In this case were setting the label and image of the button.

 static Ewl_Widget *
 test_data_header_fetch(void *data , int column)
 {
      Ewl_Widget *l;

      l = ewl_label_new();
      if (column == 0)
          ewl_label_text_set(EWL_LABEL(l), "Title");
      else if (column == 1)
          ewl_label_text_set(EWL_LABEL(l), "Image");
      else
          ewl_label_text_set(EWL_LABEL(l), "Button");

      ewl_widget_show(l);

      return l;
 }

The last view function we need to worry about is test_data_header_fetch(). EWL will call this function for each column to get the widget to display in the header. The data pointer is the data set on the tree itself and the column is the column number to return the header for (column numbers start at 0).

In this case were just creating an Ewl_Label and setting and appropriate bit of text to describe the column.

Not too bad so far, right?

With the view code out of the way lets move on to model code. We start with the fetch function. This is called whenever EWL needs to know what information to pass to the views assign function.

 static void *
 test_data_fetch(void *data, unsigned int row, unsigned int column)
 {
      Test_Data *d;
      void *val = NULL;

      d = data;

      if (column == 0)
          val = d->rows[row]->text;
      else if (column == 1)
          val = d->rows[row]->image;
      else if (column == 2)
          val = d->rows[row];

      return val;
 }

The fetch function returns a void * as EWL is making no assumptions about what type of data youll need to pass into your assign function. In this case we return a char * for the first two columns and a Tree_Row_Data * struct for the third column. The fetch function is passed the data set into the tree, the row and the column that we are interested in.

If youve set a sort function into your model then the tree headers become clickable. When the user clicks a header the sort function is called for the given column. With this app Im just using a simple bubble sort. Youll possibly want to use something a bit better for a real application.

 static void
 test_data_sort(void *data, unsigned int column, Ewl_Sort_Direction sort)
 {
      Test_Data *d;
      int i;

      // just leave it if we're in sort none.
      if (sort == EWL_SORT_DIRECTION_NONE)
          return;

      d = data;

      for (i = (DATA_ELEMENTS - 1); i >= 0; i--)
      {
          int j;

          for (j = 1; j <= i; j++)
          {
              char *a, *b;

              if (column == 0)
              {
                  a = d->rows[j - 1]->text;
                  b = d->rows[j]->text;
              }
              else
              {
                  a = d->rows[j - 1]->image;
                  b = d->rows[j]->image;
              }

              if (((sort == EWL_SORT_DIRECTION_ASCENDING) && strcmp(a, b) > 0)
                      || ((sort == EWL_SORT_DIRECTION_DESCENDING)
                          && strcmp(a, b) < 0))
              {
                  char *temp;

                  temp = d->rows[j - 1]->text;
                  d->rows[j - 1]->text = d->rows[j]->text;
                  d->rows[j]->text = temp;

                  temp = d->rows[j - 1]->image;
                  d->rows[j - 1]->image = d->rows[j]->image;
                  d->rows[j]->image = temp;
              }
          }
      }
 }

The sort call has three parameters. The the data we set on the tree, the column number that we are sorting and the direction of the sort. The three possible sort directions are EWL_SORT_DIRECTION_NONE, EWL_SORT_DIRECTION_ASCENDING and EWL_SORT_DIRECTION_DESCENDING. In this case, we dont bother doing anything if we are set to a sort of EWL_SORT_DIRECTION_NONE. We then sort the data as needed in either ascending or descending order based on the sort parameter.

 static unsigned int
 test_data_count_get(void *data)
 {
      Test_Data *d;

      d = data;

      return d->count;
 }

The last model function we need to implement is the count function. This is just a way for your application to tell EWL how many rows are in your data. In this case we just return the count parameter.

Thats it for the model code. All thats left are the three callbacks we defined for the UI.

 static void
 cb_delete_window(Ewl_Widget *w, void *ev, void *data)
 {
      ewl_widget_destroy(w);
      ewl_main_quit();
 }

cb_delete_window() will be called when the window is deleted. All we do is destroy the window with a call to ewl_widget_destroy() and quit the application with ewl_main_quit(). Because we attached this callback to the Ewl_Window widget the first parameter *w is our window. You dont technically need to ewl_widget_destroy() the window but its nice to clean up after yourself.

 static void
 cb_scroll_headers(Ewl_Widget *w, void *ev , void *data)
 {
      Ewl_Tree *tree;

      tree = data;
      ewl_tree_scroll_headers_set(tree, ewl_checkbutton_is_checked(EWL_CHECKBUTTON(w)));
 }

The cb_scroll_headers() function toggles if the headers in the tree should be scrolled. This is done by calling ewl_tree_scroll_headers_set() and passing either TRUE or FALSE depending on if we want the headers scrolled. This is conveniently the same as the return of ewl_checkbutton_is_checked().

 static void
 cb_scroll_visible(Ewl_Widget *w, void *ev , void *data)
 {
      Ewl_Tree *tree;

      tree = data;
      ewl_tree_scroll_visible_set(tree, ewl_checkbutton_is_checked(EWL_CHECKBUTTON(w)));
 }

The cb_scroll_visible() function works in the same way as the cb_scroll_headers() function except that it either enables or disables the display of the scrollbars in the tree.

With that, were at the end of our code. If you use the compilation line given above everything should work out and when you run the app you should seeing something similar too:

Hopefully that wasnt too painful and you can see how easily it is to work with the new Ewl_Tree code.

Oh, before I forget. If you're updating your model and you want EWL to redraw the tree you just need to call ewl_tree_dirty_set() and pass TRUE as the second parameter. This will signal EWL that something has changed in the model and the tree will be redrawn.


Data Structures

struct  Ewl_Tree
 Inherits from Ewl_MVC and extends to provide a tree widget. More...
struct  Ewl_Tree_Node
 Inherits from Ewl_Container and extends to hold information on a row of the tree. More...

Defines

#define EWL_TREE(t)   ((Ewl_Tree *)t)
#define EWL_TREE_IS(w)   (ewl_widget_type_is(EWL_WIDGET(w), EWL_TREE_TYPE))
#define EWL_TREE_NODE(n)   ((Ewl_Tree_Node *)n)
#define EWL_TREE_NODE_IS(w)   (ewl_widget_type_is(EWL_WIDGET(w), EWL_TREE_NODE_TYPE))
#define EWL_TREE_NODE_TYPE   "node"
#define EWL_TREE_TYPE   "tree"

Typedefs

typedef Ewl_Tree Ewl_Tree
typedef Ewl_Tree_Node Ewl_Tree_Node

Functions

unsigned int ewl_tree_alternate_row_colors_get (Ewl_Tree *tree)
 Retrieve if the row colours are being alternated.
void ewl_tree_alternate_row_colors_set (Ewl_Tree *tree, unsigned char alternate)
 Toggle if the rows alternate in colour.
void ewl_tree_cb_column_sort (Ewl_Widget *w, void *ev, void *data)
void ewl_tree_cb_configure (Ewl_Widget *w, void *ev, void *data)
void ewl_tree_cb_destroy (Ewl_Widget *w, void *ev, void *data)
void ewl_tree_cb_node_child_add (Ewl_Container *c, Ewl_Widget *w)
void ewl_tree_cb_node_child_del (Ewl_Container *c, Ewl_Widget *w, int idx)
void ewl_tree_cb_node_child_hide (Ewl_Container *c, Ewl_Widget *w)
void ewl_tree_cb_node_child_show (Ewl_Container *c, Ewl_Widget *w)
void ewl_tree_cb_node_configure (Ewl_Widget *w, void *ev_data, void *user_data)
void ewl_tree_cb_node_data_unref (Ewl_Widget *w, void *ev_data, void *user_data)
void ewl_tree_cb_node_realize (Ewl_Widget *w, void *ev, void *data)
void ewl_tree_cb_node_resize (Ewl_Container *c, Ewl_Widget *w, int size, Ewl_Orientation o)
void ewl_tree_cb_node_toggle (Ewl_Widget *w, void *ev_data, void *user_data)
unsigned int ewl_tree_column_count_get (Ewl_Tree *tree)
 Retrives the number of columns in the tree.
void ewl_tree_column_count_set (Ewl_Tree *tree, unsigned int count)
 Sets the number of columns in the tree.
unsigned int ewl_tree_column_fixed_size_get (Ewl_Tree *tree, unsigned int col)
void ewl_tree_column_fixed_size_set (Ewl_Tree *tree, unsigned int col, unsigned int fixed)
 Set the fixed size flag of the give column.
int ewl_tree_column_initial_size_get (Ewl_Tree *tree, unsigned int col)
void ewl_tree_column_initial_size_set (Ewl_Tree *tree, unsigned int col, int size)
 Set the initial size of the give column.
const Ewl_Viewewl_tree_content_view_get (Ewl_Tree *tree)
 Retrives the view used to generate the tree content area.
void ewl_tree_content_view_set (Ewl_Tree *tree, const Ewl_View *view)
 Sets the view to use to generate the content area.
Ewl_Widgetewl_tree_content_widget_get (Ewl_Tree *tree)
 Retrieves the widget containing the tree rows.
unsigned int ewl_tree_fixed_rows_get (Ewl_Tree *tree)
 Retrieve the fixed row size of the tree.
void ewl_tree_fixed_rows_set (Ewl_Tree *tree, unsigned int fixed)
 Set the fixed row size of the tree.
unsigned int ewl_tree_headers_visible_get (Ewl_Tree *tree)
 Retrieve if the header is visible in the tree.
void ewl_tree_headers_visible_set (Ewl_Tree *tree, unsigned char visible)
 Toggle if the header is visible in the tree.
int ewl_tree_init (Ewl_Tree *tree)
 Initialize the contents of a tree widget.
double ewl_tree_kinetic_dampen_get (Ewl_Tree *tree)
 Gets the multiplier used to reduce the velocity of kinetic scrolling.
void ewl_tree_kinetic_dampen_set (Ewl_Tree *tree, double d)
 Sets the multiplier to reduce the velocity of kinetic scrolling.
int ewl_tree_kinetic_fps_get (Ewl_Tree *tree)
 Gets the number of times per second the tree scrolling is updated.
void ewl_tree_kinetic_fps_set (Ewl_Tree *tree, int fps)
 Sets the number of times per second the tree scrolling is updated.
double ewl_tree_kinetic_max_velocity_get (Ewl_Tree *tree)
 Gets the maximum velocity for kinetic scrolling.
void ewl_tree_kinetic_max_velocity_set (Ewl_Tree *tree, double v)
 Sets the maximum velocity for kinetic scrolling.
double ewl_tree_kinetic_min_velocity_get (Ewl_Tree *tree)
 Gets the minimum velocity for kinetic scrolling.
void ewl_tree_kinetic_min_velocity_set (Ewl_Tree *tree, double v)
 Sets the minimum velocity for kinetic scrolling.
Ewl_Kinetic_Scroll ewl_tree_kinetic_scrolling_get (Ewl_Tree *tree)
 Gets the type of kinetic scrolling used.
void ewl_tree_kinetic_scrolling_set (Ewl_Tree *tree, Ewl_Kinetic_Scroll type)
 Sets up the tree to use kinetic scrolling.
Ewl_Widgetewl_tree_new (void)
 Allocate and initialize a new tree widget.
void ewl_tree_node_collapse (Ewl_Tree_Node *node)
void ewl_tree_node_expand (Ewl_Tree_Node *node)
unsigned int ewl_tree_node_expandable_get (Ewl_Tree_Node *node)
void ewl_tree_node_expandable_set (Ewl_Tree_Node *node, unsigned int expandable)
unsigned int ewl_tree_node_expanded_is (Ewl_Tree_Node *node)
int ewl_tree_node_init (Ewl_Tree_Node *node)
Ewl_Widgetewl_tree_node_new (void)
void ewl_tree_node_row_set (Ewl_Tree_Node *node, Ewl_Row *row)
void ewl_tree_row_collapse (Ewl_Tree *tree, void *data, unsigned int row)
 Sets the given row to collapsed for the given data in tree.
void ewl_tree_row_expand (Ewl_Tree *tree, void *data, unsigned int row)
 When the tree displays the data in data it will expand the give row. This data is the parent of the expansion row.
unsigned int ewl_tree_row_expanded_is (Ewl_Tree *tree, void *data, unsigned int row)
 Checks if row is expanded in data of tree.
void ewl_tree_row_visible_ensure (Ewl_Tree *tree, void *data, unsigned int row)
 Ensures that the requested row is visible, if it is not the tree is scrolled, so that the row becomes visible.
Ewl_Tree_Selection_Type ewl_tree_selection_type_get (Ewl_Tree *tree)
 Get the selection type from the tree.
void ewl_tree_selection_type_set (Ewl_Tree *tree, Ewl_Tree_Selection_Type type)
 Set the mode of the tree.

Define Documentation

#define EWL_TREE (  )     ((Ewl_Tree *)t)

Typecasts a pointer to an Ewl_Tree pointer.

#define EWL_TREE_IS (  )     (ewl_widget_type_is(EWL_WIDGET(w), EWL_TREE_TYPE))

Returns TRUE if the widget is an Ewl_Tree, FALSE otherwise

#define EWL_TREE_NODE (  )     ((Ewl_Tree_Node *)n)

#define EWL_TREE_NODE_IS (  )     (ewl_widget_type_is(EWL_WIDGET(w), EWL_TREE_NODE_TYPE))

Returns TRUE if the widget is an Ewl_Tree_Node, FALSE otherwise

#define EWL_TREE_NODE_TYPE   "node"

#define EWL_TREE_TYPE   "tree"

The type name for the Ewl_ widget


Typedef Documentation

typedef struct Ewl_Tree Ewl_Tree

The Ewl_Tree widget

typedef struct Ewl_Tree_Node Ewl_Tree_Node


Function Documentation

unsigned int ewl_tree_alternate_row_colors_get ( Ewl_Tree tree  ) 

Retrieve if the row colours are being alternated.

Parameters:
tree,: The tree to work with
Returns:
Returns if the row colours are currently being alternated

void ewl_tree_alternate_row_colors_set ( Ewl_Tree tree,
unsigned char  alternate 
)

Toggle if the rows alternate in colour.

Parameters:
tree,: The tree to toggle the alternating row colour
alternate,: The boolean for alternating the row colour (TRUE == yes, FALSE == no)
Returns:
Returns no value

void ewl_tree_cb_column_sort ( Ewl_Widget w,
void *  ev,
void *  data 
)

void ewl_tree_cb_configure ( Ewl_Widget w,
void *  ev,
void *  data 
)

void ewl_tree_cb_destroy ( Ewl_Widget w,
void *  ev,
void *  data 
)

void ewl_tree_cb_node_child_add ( Ewl_Container c,
Ewl_Widget w 
)

void ewl_tree_cb_node_child_del ( Ewl_Container c,
Ewl_Widget w,
int  idx 
)

void ewl_tree_cb_node_child_hide ( Ewl_Container c,
Ewl_Widget w 
)

void ewl_tree_cb_node_child_show ( Ewl_Container c,
Ewl_Widget w 
)

void ewl_tree_cb_node_configure ( Ewl_Widget w,
void *  ev_data,
void *  user_data 
)

void ewl_tree_cb_node_data_unref ( Ewl_Widget w,
void *  ev_data,
void *  user_data 
)

void ewl_tree_cb_node_realize ( Ewl_Widget w,
void *  ev,
void *  data 
)

void ewl_tree_cb_node_resize ( Ewl_Container c,
Ewl_Widget w,
int  size,
Ewl_Orientation  o 
)

void ewl_tree_cb_node_toggle ( Ewl_Widget w,
void *  ev_data,
void *  user_data 
)

unsigned int ewl_tree_column_count_get ( Ewl_Tree tree  ) 

Retrives the number of columns in the tree.

Parameters:
tree,: The tree to work with
Returns:
Returns the number of columns in the tree

void ewl_tree_column_count_set ( Ewl_Tree tree,
unsigned int  count 
)

Sets the number of columns in the tree.

Parameters:
tree,: The tree to work with
count,: The number of columns in the tree
Returns:
Returns no value

unsigned int ewl_tree_column_fixed_size_get ( Ewl_Tree tree,
unsigned int  col 
)

Parameters:
tree,: The tree to work with
col,: the column to get the fixed size flag
Returns:
Retrieve fixed size flag of the given column

void ewl_tree_column_fixed_size_set ( Ewl_Tree tree,
unsigned int  col,
unsigned int  fixed 
)

Set the fixed size flag of the give column.

Parameters:
tree,: The tree to work with
col,: The number of the column to change the fixed size flag
fixed,: The fixed size flag to set
Returns:
Returns no value

int ewl_tree_column_initial_size_get ( Ewl_Tree tree,
unsigned int  col 
)

Parameters:
tree,: The tree to work with
col,: the column to get the initial size
Returns:
Retrieve initial size of the given column

void ewl_tree_column_initial_size_set ( Ewl_Tree tree,
unsigned int  col,
int  size 
)

Set the initial size of the give column.

Parameters:
tree,: The tree to work with
col,: The number of the column to change the initial size
size,: The initial column size to set
Returns:
Returns no value

const Ewl_View* ewl_tree_content_view_get ( Ewl_Tree tree  ) 

Retrives the view used to generate the tree content area.

Parameters:
tree,: The tree to work with
Returns:
Returns the view used to generate the content area

void ewl_tree_content_view_set ( Ewl_Tree tree,
const Ewl_View view 
)

Sets the view to use to generate the content area.

Parameters:
tree,: the tree to work with
view,: The view to set to generate the content area
Returns:
Returns no value

Ewl_Widget* ewl_tree_content_widget_get ( Ewl_Tree tree  ) 

Retrieves the widget containing the tree rows.

Parameters:
tree,: The tree to work with
Returns:
Returns the widget that contains the tree rows

unsigned int ewl_tree_fixed_rows_get ( Ewl_Tree tree  ) 

Retrieve the fixed row size of the tree.

Parameters:
tree,: The tree to get the fixed row flag from
Returns:
Returns the current fixed row flag of the tree

void ewl_tree_fixed_rows_set ( Ewl_Tree tree,
unsigned int  fixed 
)

Set the fixed row size of the tree.

Parameters:
tree,: The tree to set the fixed row flag into
fixed,: The fixed row flag to set into the tree
Returns:
Returns no value.

unsigned int ewl_tree_headers_visible_get ( Ewl_Tree tree  ) 

Retrieve if the header is visible in the tree.

Parameters:
tree,: The tree to get the header visiblity from
Returns:
Returns the current header visiblity of the tree

void ewl_tree_headers_visible_set ( Ewl_Tree tree,
unsigned char  visible 
)

Toggle if the header is visible in the tree.

Parameters:
tree,: The tree to toggle the header visibility
visible,: The visiblity to set the tree to (TRUE == on, FALSE == off)
Returns:
Returns no value

int ewl_tree_init ( Ewl_Tree tree  ) 

Initialize the contents of a tree widget.

Parameters:
tree,: the tree widget to be initialized
Returns:
Returns TRUE on success, FALSE on failure.
The contents of the tree widget tree are initialized to their defaults.

double ewl_tree_kinetic_dampen_get ( Ewl_Tree tree  ) 

Gets the multiplier used to reduce the velocity of kinetic scrolling.

Parameters:
tree,: The tree to work with
Returns:
Returns the multiplier used to dampen in kinetic scrolling

void ewl_tree_kinetic_dampen_set ( Ewl_Tree tree,
double  d 
)

Sets the multiplier to reduce the velocity of kinetic scrolling.

Parameters:
tree,: The tree to work with
d,: The multiplier to reduce velocity
Returns:
Returns no value

int ewl_tree_kinetic_fps_get ( Ewl_Tree tree  ) 

Gets the number of times per second the tree scrolling is updated.

Parameters:
tree,: The tree to work with
Returns:
Returns the number of frames per second

void ewl_tree_kinetic_fps_set ( Ewl_Tree tree,
int  fps 
)

Sets the number of times per second the tree scrolling is updated.

Parameters:
tree,: The tree to work with
fps,: The number of frames per second
Returns:
Returns no value

double ewl_tree_kinetic_max_velocity_get ( Ewl_Tree tree  ) 

Gets the maximum velocity for kinetic scrolling.

Parameters:
tree,: The tree to work with
Returns:
Returns the maximum velocity of kinetic scrolling

void ewl_tree_kinetic_max_velocity_set ( Ewl_Tree tree,
double  v 
)

Sets the maximum velocity for kinetic scrolling.

Parameters:
tree,: The tree to work with
v,: The maximum velocity
Returns:
Returns no value

double ewl_tree_kinetic_min_velocity_get ( Ewl_Tree tree  ) 

Gets the minimum velocity for kinetic scrolling.

Parameters:
tree,: The tree to work with
Returns:
Returns the minimum velocity of kinetic scrolling

void ewl_tree_kinetic_min_velocity_set ( Ewl_Tree tree,
double  v 
)

Sets the minimum velocity for kinetic scrolling.

Parameters:
tree,: The tree to work with
v,: The minimum velocity
Returns:
Returns no value

Ewl_Kinetic_Scroll ewl_tree_kinetic_scrolling_get ( Ewl_Tree tree  ) 

Gets the type of kinetic scrolling used.

Parameters:
tree,: The tree to use
Returns:
Returns the type of kinetic scrolling used

void ewl_tree_kinetic_scrolling_set ( Ewl_Tree tree,
Ewl_Kinetic_Scroll  type 
)

Sets up the tree to use kinetic scrolling.

Parameters:
tree,: The tree to set kinetic scrolling for
type,: The type of kinetic scrolling to use
Returns:
Returns no value

Ewl_Widget* ewl_tree_new ( void   ) 

Allocate and initialize a new tree widget.

Returns:
Returns NULL on failure, a new tree widget on success.

void ewl_tree_node_collapse ( Ewl_Tree_Node node  ) 

void ewl_tree_node_expand ( Ewl_Tree_Node node  ) 

unsigned int ewl_tree_node_expandable_get ( Ewl_Tree_Node node  ) 

void ewl_tree_node_expandable_set ( Ewl_Tree_Node node,
unsigned int  expandable 
)

unsigned int ewl_tree_node_expanded_is ( Ewl_Tree_Node node  ) 

int ewl_tree_node_init ( Ewl_Tree_Node node  ) 

Ewl_Widget* ewl_tree_node_new ( void   ) 

void ewl_tree_node_row_set ( Ewl_Tree_Node node,
Ewl_Row row 
)

void ewl_tree_row_collapse ( Ewl_Tree tree,
void *  data,
unsigned int  row 
)

Sets the given row to collapsed for the given data in tree.

Parameters:
tree,: The tree to collapse the row of
data,: The data that contains the collapsed row
row,: The row to collapse
Returns:
Returns no value

void ewl_tree_row_expand ( Ewl_Tree tree,
void *  data,
unsigned int  row 
)

When the tree displays the data in data it will expand the give row. This data is the parent of the expansion row.

Parameters:
tree,: The tree to set the expansion into
data,: The data that contains the expansion
row,: The row to expand
Returns:
Returns no value

unsigned int ewl_tree_row_expanded_is ( Ewl_Tree tree,
void *  data,
unsigned int  row 
)

Checks if row is expanded in data of tree.

Parameters:
tree,: The tree to work with
data,: The set of data to work with
row,: The row to check
Returns:
Returns TRUE if the given row is expanded, FALSE otherwise

void ewl_tree_row_visible_ensure ( Ewl_Tree tree,
void *  data,
unsigned int  row 
)

Ensures that the requested row is visible, if it is not the tree is scrolled, so that the row becomes visible.

Parameters:
tree,: The tree to work with
row,: The row that would be made visible, if it is not
Returns:
Returns no value
At the moment it does not work for sub tree nodes.

Ewl_Tree_Selection_Type ewl_tree_selection_type_get ( Ewl_Tree tree  ) 

Get the selection type from the tree.

Parameters:
tree,: The tree to get the mode from
Returns:
Returns the current Ewl_Tree_Selection_Type of the tree

void ewl_tree_selection_type_set ( Ewl_Tree tree,
Ewl_Tree_Selection_Type  type 
)

Set the mode of the tree.

Parameters:
tree,: The Ewl_Tree to set the mode into
type,: The Ewl_Tree_Selection_Mode to set into the tree
Returns:
Returns no value.


Copyright © Enlightenment.org

Enlightened Widget Library Documentation Generated: Sun Sep 27 01:49:47 2009