fltk::List Class Reference

Inherited by fltk::StringHierarchy, and Share_List.

List of all members.

Public Member Functions

virtual Widgetchild (const Menu *, const int *indexes, int level)
virtual int children (const Menu *, const int *indexes, int level)
virtual void flags_changed (const Menu *, Widget *)
virtual ~List ()

Detailed Description

Allows a Browser or Choice or other subclass of Menu to display a hierarchy of data that is managed by the application rather than FLTK.

This is done by making a subclass of List which creats a "dummy" widget, typically a subclass of Item, that describes a particular item that the browser or menu should display. Only one item is examined at any time and thus the dummy widget can be reused, so there is very little space overhead.

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, a Browser and Menu will usually ask for adjoining items.

If you wish to use a MultiBrowser you must also have space in your data to store the state of the fltk::SELECTED flag on each item, and and must implement the flags_changed() method.

If you wish to make a hierarcial Browser, you may want to have space in your data to store the state of the fltk::STATE flag on each parent item, and implement the flags_changed() method. If you don't do this the browser is only able to keep one item open at each level.

The base List class returns the child widgets from the Menu that owns it. All Menus share a single instance of this by default, so the default behavior is that child widgets appear as items in the menu or browser. Subclasses of List may want to call the base class to allow normal widgets to be prepended to whatever they return.


Constructor & Destructor Documentation

List::~List ( ) [virtual]

The destructor does nothing. It is mostly here to shut up compiler warnings, and to allow subclasses that you want to dynamically allocate to work.

Unfortunately C++ calls the destructor for static objects on program exit. I consider this a mistake, particularily because the destructor cannot assumme other objects (like the display connection) still exist. It also slows down program exit. As all useable systems can harvest resources used by crashed programs, calling these destructors serve no useful purpose.


Member Function Documentation

Widget * List::child ( const Menu menu,
const int *  indexes,
int  level 
) [virtual]

Return a given child as a widget. draw() and measure() will be called on this widget to figure out where to place it and to draw it. Typical implementations create a reusable fltk::Item and fill it in with the correct data. This should return NULL if there is anything illegal about the indexes.

Here is a sample implementation, where Node is a data type that you have defined. This demonstrates how to create the dummy widget:

fltk::Widget* My_List::child(const fltk::Menu*, const int* indexes, int level) {
  Node* node = root;
  for (int l = 0; l <= level; l++) {
    if (!node->is_parent()) return 0;
    if (indexes[l] >= node->children_count()) return 0;
    node = node->child(indexes[l]);
  }
  static fltk::Widget* widget;
  if (!widget) {
    fltk::Group::current(0);
    widget = new fltk::Item();
  }
  widget->label(node->text());
  widget->w(0); // cause measure() to be called
  widget->user_data(node);
  if (node->selected) widget->set_flag(fltk::SELECTED);
  else widget->clear_flag(fltk::SELECTED);
  if (node->is_parent() && node->open) widget->set_flag(fltk::STATE);
  else widget->clear_flag(fltk::STATE);
  return widget;
}

Reimplemented in fltk::StringHierarchy.

int List::children ( const Menu menu,
const int *  indexes,
int  level 
) [virtual]

Return how many children are under a given item. If level is zero, this should return how many items are at the top level. Otherwise indexes is an array of level numbers indicating the index of an item at the top level, the index of the an item that is the child of that, and so on.

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 fltk::STATE 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_List::children(const fltk::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();
}

Reimplemented in fltk::StringHierarchy, and fltk::StringList.

void List::flags_changed ( const Menu ,
Widget  
) [virtual]

This is called if the browser changes any flags on a widget, so that you can copy the values to permanent storage, and perhaps change other displays of the selection.

Currently only the fltk::OPENED and fltk::SELECTED flags are ever changed.

Here is a sample implementation, where Node is a data type that you have defined:

void My_List::flags_changed(const fltk::Menu*, fltk::Widget* widget) {
  Node* node = (Node*)(widget->user_data());
  node->open = widget->flag(fltk::OPENED);
  node->selected = widget->flag(fltk::SELECTED);
}

The documentation for this class was generated from the following files: