#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;
}