From 330c8a01fdd4a13352a0d225aac3ef10ce291701 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Thu, 28 Jul 2011 21:27:32 +0000 Subject: [PATCH] elementary/genlist - Examples 04 and 05 explained. SVN revision: 61869 --- legacy/elementary/doc/examples.dox | 268 ++++++++++++++++++++- legacy/elementary/src/examples/Makefile.am | 4 + legacy/elementary/src/lib/Elementary.h.in | 2 + 3 files changed, 272 insertions(+), 2 deletions(-) diff --git a/legacy/elementary/doc/examples.dox b/legacy/elementary/doc/examples.dox index 51d0582234..f71d070751 100644 --- a/legacy/elementary/doc/examples.dox +++ b/legacy/elementary/doc/examples.dox @@ -67,6 +67,10 @@ * * @ref genlist_example_02 * + * @ref genlist_example_04 + * + * @ref genlist_example_05 + * * @ref progressbar_example * * @ref slideshow_example @@ -4015,7 +4019,7 @@ */ /** - * @page genlist_example_01 + * @page genlist_example_01 Genlist - basic usage * * This example creates a simple genlist with a small number of items and * a callback that is called whenever an item is selected. All the properties of @@ -4103,7 +4107,7 @@ */ /** - * @page genlist_example_02 + * @page genlist_example_02 Genlist - list setup functions * * This example is very similar to the @ref genlist_example_01, but it fetch * most of the properties of the genlist and displays them on startup (thus @@ -4214,6 +4218,253 @@ * @image latex screenshots/genlistexample_02.eps width=\textwidth */ +/** + * @page genlist_example_04 Genlist - items manipulation + * + * This example is also similar ot the @ref genlist_example_01, but it + * demonstrates most of the item manipulation functions. See the full source + * code at @ref genlist_example_04_c. + * + * In this example, we also will use the concept of creating groups of items in + * the genlist. Each group of items is composed by a parent item (which will be + * the index of the group) and several children of this item. Thus, for the + * children, we declare a normal item class. But we also are going to declare a + * different item class for the group index (which in practice is another type + * of item in the genlist): + * + * @dontinclude genlist_example_04.c + * @skip _item_sel_cb + * @skip static + * @until } + * @until } + * + * We will add buttons to the window, where each button provides one + * functionality of the genlist item API. Each button will have a callback + * attached, that will really execute this functionality. An example of these + * callbacks is the next one, for the elm_genlist_item_insert_after() function: + * + * @skip insert_before_cb + * @skip static + * @until } + * + * If you want ot see the other button functions, look at the full source code + * link above. + * + * Each button will be created with a function that already creates the button, + * add it to an elementary box, and attach the specified callback. This is the + * function that does it: + * + * @skip genlist_item_update + * @skip static + * @until } + * + * In our @c elm_main function, besides the code for setting up the window, box + * and background, we also initialize our two item classes: + * + * @skip _itc.item_style + * @until _itc_group.func.del + * + * This example uses a different style for the items, the @a double_label, which + * provides a text field for the item text, and another text field for a subtext. + * + * For the group index we use the @a group_index style, which provides a + * different appearance, helping to identify the end of a group and beginning of + * another one. + * + * Now, after the code for creating the list, setting up the box and other + * stuff, let's add the buttons with their respective callbacks: + * + * @skip _button_add + * @until bt_top_show + * + * The main code for adding items to the list is a bit more complex than the one + * from the previous examples. We check if each item is multiple of 7, and if + * so, they are group indexes (thus each group has 6 elements by default, in + * this example): + * + * @skip for + * @until } + * @until } + * + * Then we also check for specific items, and add callbacks to them on the + * respective buttons, so we can show, bring in, etc.: + * + * @until } + * @until } + * + * Once you understand the code from the @ref genlist_example_01, it should be + * easy to understand this one too. Look at the full code, and also try to play + * a bit with the buttons, adding items, bringing them to the viewport, and so. + * + * The example will look like this when running: + * + * @image html screenshots/genlist_example_04.png + * @image latex screenshots/genlistexample_04.eps width=\textwidth + */ + +/** + * @page genlist_example_05 Genlist - working with subitems + * + * This is probably the most complex example of elementary @ref Genlist. We + * create a tree of items, using the subitems properties of the items, and keep + * it in memory to be able to expand/hide subitems of an item. The full source + * code can be found at @ref genlist_example_05_c + * + * The main point is the way that Genlist manages subitems. Clicking on an + * item's button to expand it won't really show its children. It will only + * generate the "expand,request" signal, and the expansion must be done + * manually. + * + * In this example we want to be able to add items as subitems of another item. + * If an item has any child, it must be displayed using a parent class, + * otherwise it will use the normal item class. + * + * It will be possible to delete items too. Once a tree is constructed (with + * subitems of subitems), and the user clicks on the first parent (root of the + * tree), the entire subtree must be hidden. However, just calling + * elm_genlist_item_expanded_set(item, EINA_FALSE) won't hide them. The only + * thing that happens is that the parent item will change its appearance to + * represent that it's contracted. And the signal "contracted" will be emitted + * from the genlist. Thus, we must call elm_genlist_item_subitems_clear() to + * delete all its subitems, but still keep a way to recreate them when expanding + * the parent again. That's why we are going to keep a node struct for each + * item, that will be the data of the item, with the following information: + * + * @dontinclude genlist_example_05.c + * @skip typedef + * @until } + * + * This @c Node_Data contains the value for the item, a number indicating its + * level under the tree, a list of children (to be able to expand it later) and + * a boolean indicating if it's a favorite item or not. + * + * We use 3 different item classes in this example: + * + * One for items that don't have children: + * + * @skip nitems + * @skip static + * @until } + * @until } + * + * One for items that have children: + * + * @skip item_sel + * @skip static + * @until } + * @until } + * + * And one for items that were favorited: + * + * @skip static + * @until } + * @until } + * + * The favorite item class is there just to demonstrate the + * elm_genlist_item_item_class_update() function in action. It would be much + * simpler to implement the favorite behavior by just changing the icon inside + * the icon_get functions when the @c favorite boolean is activated. + * + * Now we are going to declare the callbacks for the buttons that add, delete + * and change items. + * + * First, a button for appending items to the list: + * + * @until item_append + * @until } + * + * If an item is selected, a new item will be appended to the same level of that + * item, but using the selected item's parent as its parent too. If no item is + * selected, the new item will be appended to the root of the tree. + * + * Then the callback for marking an item as favorite: + * + * @until elm_genlist_item_update + * @until } + * + * This callback is very simple, it just changes the item class of the selected + * item for the "favorite" one, or go back to the "item" or "parent" class + * depending on that item having children or not. + * + * Now, the most complex operation (adding a child to an item): + * + * @until elm_genlist_item_update + * @until } + * + * This function gets the data of the selected item, create a new data (for the + * item being added), and appends it to the children list of the selected item. + * + * Then we must check if the selected item (let's call it @c item1 now) to which + * the new item (called @c item2 from now on) was already a parent item too + * (using the parent item class) or just a normal item (using the default item + * class). In the first case, we just have to append the item to the end of the + * @c item1 children list. + * + * However, if the @c item1 didn't have any child previously, we have to change + * it to a parent item now. It would be easy to just change its item class to + * the parent type, but there's no way to change the item flags and make it be + * of the type #ELM_GENLIST_ITEM_SUBITEMS. Thus, we have to delete it and create + * a new item, and add this new item to the same position that the deleted one + * was. That's the reason of the checks inside the bigger @c if. + * + * After adding the item to the newly converted parent, we set it to not + * expanded (since we don't want to show the added item immediately) and select + * it again, since the original item was deleted and no item is selected at the + * moment. + * + * Finally, let's show the callback for deleting items: + * + * @until elm_genlist_item_update + * @until } + * + * Since we have an iternal list representing each element of our tree, once we + * delete an item we have to go deleting each child of that item, in our + * internal list. That's why we have the function @c _clear_list, which + * recursively goes freeing all the item data. + * + * This is necessary because only when we really want to delete the item is when + * we need to delete the item data. When we are just contracting the item, we + * need to hide the children by deleting them, but keeping the item data. + * + * Now there are two callbacks that will be called whenever the user clicks on + * the expand/contract icon of the item. They will just request to items to be + * contracted or expanded: + * + * @until elm_genlist_item_expanded_set( + * @until elm_genlist_item_expanded_set( + * @until } + * + * When the elm_genlist_item_expanded_set() function is called with @c + * EINA_TRUE, the @c _expanded_cb will be called. And when this happens, the + * subtree of that item must be recreated again. This is done using the internal + * list stored as item data for each item. The function code follows: + * + * @until } + * + * Each appended item is set to contracted, so we don't have to deal with + * checking if the item was contracted or expanded before its parent being + * contracted. It could be easily implemented, though, by adding a flag expanded + * inside the item data. + * + * Now, the @c _contracted_cb, which is much simpler: + * + * @until } + * + * We just have to call elm_genlist_item_subitems_clear(), that will take care + * of deleting every item, and keep the item data still stored (since we don't + * have any del function set on any of our item classes). + * + * Finally, the code inside @c elm_main is very similar to the other examples: + * + * @skip elm_main + * @until ELM_MAIN + * + * The example will look like this when running: + * + * @image html screenshots/genlist_example_05.png + * @image latex screenshots/genlistexample_05.eps width=\textwidth + */ + /** * @page progressbar_example Progress bar widget example * @@ -5056,6 +5307,7 @@ * * @include layout_example.edc * @example layout_example.edc + */ /** * @page gengrid_example_c Gengrid example @@ -5075,6 +5327,18 @@ * @example genlist_example_02.c */ +/** + * @page genlist_example_04_c genlist_example_04.c + * @include genlist_example_04.c + * @example genlist_example_04.c + */ + +/** + * @page genlist_example_05_c genlist_example_05.c + * @include genlist_example_05.c + * @example genlist_example_05.c + */ + /** * @page progressbar_example_c Progress bar example * @include progressbar_example.c diff --git a/legacy/elementary/src/examples/Makefile.am b/legacy/elementary/src/examples/Makefile.am index 0d62581ba9..ab019ab574 100644 --- a/legacy/elementary/src/examples/Makefile.am +++ b/legacy/elementary/src/examples/Makefile.am @@ -248,6 +248,10 @@ SCREENSHOTS = \ toggle_example_01:toggle_example_01.png:0.0 \ panel_example_01:panel_example_01.png:0.0 \ gengrid_example:gengrid_example.png:0.0 \ + genlist_example_01:genlist_example_01.png:0.1 \ + genlist_example_02:genlist_example_02.png:0.1 \ + genlist_example_04:genlist_example_04.png:0.1 \ + genlist_example_05:genlist_example_05.png:0.1 \ entry_example:entry_example.png:0.0 \ progressbar_example:progressbar_example.png:0.0 \ notify_example_01:notify_example_01.png:0.0 \ diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index b26262dcda..461d6dc4aa 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -11970,6 +11970,8 @@ extern "C" { * its capabilities: * - @ref genlist_example_01 * - @ref genlist_example_02 + * - @ref genlist_example_04 + * - @ref genlist_example_05 */ /**