#include <FL/Fl_Menu_.H>
This is designed for data formats where finding the Nth child of a parent is a very quick operation, ie an array. If your data is a list you can search it, the performance is probably acceptable for small lists with less than a hundred or so items. For a bidirectional list it may be useful to cache the last request and do a relative search, as Fl_Browser and Fl_Menu will usually ask for adjoining items.
If you wish to make a hierarcial Fl_Browser, you must have space in your data to store the state of the FL_OPEN flag on each parent item, and must implement the flags_changed() method.
If you wish to use an Fl_Multi_Browser you must also have space in your data to store the state of the FL_VALUE flag on each item, and must implement the flags_changed() method.
This should return -1 if the item is not a "parent" item or the index array is illegal. It is not necessary to return the correct value until the parent is "open", which means the FL_OPEN flag was set in it, so if it is expensive to calculate the number you can return 1 for any closed parent.
Here is a sample implementation, where Node is a data type that you have defined:
int My_Fl_List::children(const Fl_Menu_*, const int* indexes, int level) { Node* node = root; for (int l = 0; l < level; l++) { if (indexes[l] >= node->children_count()) return -1; node = node->child(indexes[l]); if (!node->is_parent()) return -1; } return node->children_count(); }
Here is a sample implementation, where Node is a data type that you have defined:
Fl_Widget* My_Fl_List::child(const Fl_Menu_*, const int* indexes, int level) { Node* node = root; for (int l = 0; l <= level; l++) { if (!node->is_parent()) return -1; if (indexes[l] >= node->children_count()) return -1; node = node->child(indexes[l]); } static Fl_Widget* widget; if (!widget) { Fl_Group::current(0); widget = new Fl_Item(); } widget->label(node->text()); widget->w(0); // cause measure() to be called widget->user_data(node); if (node->selected) widget->set_flag(FL_VALUE); else widget->clear_flag(FL_VALUE); if (node->is_parent() && node->open) widget->set_flag(FL_OPEN); else widget->clear_flag(FL_OPEN); return widget; }
Currently on the FL_VALUE and FL_OPEN flags are ever changed.
Here is a sample implementation, where Node is a data type that you have defined:
void My_Fl_List::flags_changed(const Fl_Menu_*, Fl_Widget* widget) { Node* node = (Node*)(widget->user_data()); node->open = (widget->flags() & FL_OPEN) !=0; node->selected = (widget->flags() & FL_VALUE) != 0; }