# Making Your Own Widgets

## Making a Subclass of fltk::Widget

New widgets are created by subclassing an existing FLTK widget.

Most commonly the fltk::Widget class is subclassed to make new types of controls.

You can also subclass other existing widgets to make a similar control with a different look or user-interface. For example, the check button widgets are all subclasses of fltk::Button since they all interact with the user via a mouse button click. The only difference is the code that draws the face of the button. The class fltk::Valuator provides useful methods for storing a single floating-point "value" and is subclassed for a number of control widgets.

`fltk::Widget` has only four virtual methods, and overriding some or all of these may be necessary.

### The Constructor

The constructor should have the following arguments:

    MyClass(int x, int y, int w, int h, const char *label = 0);

This will allow the class to be used in FLUID without problems.

The constructor must call the constructor for the base class and pass the same arguments:

    MyClass::MyClass(int x, int y, int w, int h, const char *label)
    : fltk::Widget(x, y, w, h, label) {
    // do initialization stuff...
    }

`fltk::Widget`'s protected constructor sets `x()`, `y()`, `w()`, `h()`, and `label()` to the passed values and initializes the other instance variables to:

    style(default_style);
    callback(default_callback,0);
    image(0);
    tooltip(0);
    shortcut(0);
    flags(0); // active, visible, fltk::ALIGN_CENTER
    type(0);
    set_damage(fltk::DAMAGE_ALL);
    layout_damage(fltk::LAYOUT_DAMAGE);
    when(fltk::WHEN_RELEASE);

### Handling Events

The virtual method `int fltk::Widget::handle(int event)` is called to handle each event passed to the widget. It can:

- Change the state of the widget.
- Call `fltk::Widget::redraw()` if the widget needs to be redisplayed.
- Call `fltk::Widget::redraw(n)` if the widget needs a partial-update (assumming you provide support for this in your `fltk::Widget::draw()` method).
- Call `fltk::Widget::do_callback()` if a callback should be generated.
- Call `fltk::Widget::handle()` on child widgets.

Events are identified by the integer argument. Other information about the most recent event is stored in static locations and aquired by calling the `fltk::event_*()` functions. This information remains valid until another event is handled.

Here is a sample `handle()` method for a widget that acts as a pushbutton and also accepts the keystroke 'x' to cause the callback:

    int MyClass::handle(int event) {
      switch(event) {
        case fltk::PUSH:
          highlight = 1;
          redraw();
          return 1;
        case fltk::DRAG: {
            int t = fltk::event_inside(this);
            if (t != highlight) {
              highlight = t;
    	  redraw();
    	}
          }
          return 1;
        case fltk::RELEASE:
          if (highlight) {
    	highlight = 0;
    	redraw();
            do_callback();
    	// never do anything after a callback, as the callback
    	// may delete the widget!
          }
          return 1;
        case fltk::SHORTCUT:
          if (fltk::event_key() == 'x') {
            do_callback();
    	return 1;
          }
          return 0;
        default:
          return 0;
      }
    }

You must return non-zero if your `handle()` method uses the event. If you return zero it indicates to the parent widget that it can try sending the event to another widget.

### Drawing the Widget

The `draw()` virtual method is called when FLTK wants you to redraw your widget. It will be called if and only if `damage()` is non-zero, and `damage()` will be cleared to zero after it returns. `draw()` should be declared protected, so that it can't be called from non-drawing code.

`damage()` contains the bitwise-OR of all the `redraw(n)` calls to this widget since it was last drawn. This can be used for minimal update, by only redrawing the parts whose bits are set. If the flag `fltk::DAMAGE_EXPOSE` is on in `damage()` then the widget is expected to draw every pixel inside it's bounding box. If you wish to simulate a non-square widget, you should call `fltk::Group::draw_group_box()` with appropriate clipping.

Expose events (and the method `expose(x,y,w,h)`) will cause `draw()` to be called with FLTK's clipping turned on. You can greatly speed up redrawing in some cases by testing `fltk::not_clipped(x,y,w,h)` or `fltk::clip_box(...)` and skipping invisible parts.

FLTK provides a large number of basic drawing functions. And fltk::Widget provides several convienent drawing methods.

### Resizing the Widget

The `layout()` method is called after the widget is resized or moved or if `relayout()` has been called.

`layout_damage()` will have the reason that `layout()` is being called. This can be `fltk::LAYOUT_X, fltk::LAYOUT_Y, fltk::LAYOUT_W, fltk::LAYOUT_H` or `fltk::LAYOUT_DAMAGE` if `relayout()` was called, or any combination of these.

You must call the base class implementation to get the `layout_damage()` bits turned off.

For composite widgets the bit `fltk::LAYOUT_CHILD` will be turned on to indicate that a child widget needs to have `layout()` called. Your implementation must call this.

`layout()` should call `redraw()` if it determines that the display needs to be redrawn.

## Making a Composite Widget

A "composite" widget contains a set of child widgets and makes it look like a single large widget. fltk::Group is the main composite widget widget class in FLTK, and all of the other composite widgets (fltk::Pack, fltk::Scroll, fltk::Tabs, fltk::Tile, and fltk::Window) are subclasses of it.

For most uses the set of child widgets is fixed by the composite widget. Instances of the child widgets may be included in the parent:

    class MyClass : public fltk::Group {
      fltk::Button the_button;
      fltk::Slider the_slider;
      ...
    };

The constructor has to initialize these instances. They are automatically `add()`ed to the group, since the `fltk::Group` constructor does `begin()`. Don't forget to call `end()` or use the `fltk::End` pseudo-class:

    MyClass::MyClass(int x, int y, int w, int h) :
      fltk::Group(x, y, w, h),
      the_button(x + 5, y + 5, 100, 20),
      the_slider(x, y + 50, w, 20)
    {
      ...(you could add dynamically created child widgets here)...
      end(); // don't forget to do this!
    }

The child widgets need callbacks. These will be called with a pointer to the children, but the widget itself may be found in the `parent()` pointer of the child. Usually these callbacks can be static private methods, with a matching private method:

    void MyClass::slider_cb(fltk::Widget* v, void *) { // static method
      ((MyClass*)(v->parent())->slider_cb();
    }
    void MyClass::slider_cb() { // normal method
      use(the_slider->value());
    }

If you make the `handle()` method, you can quickly pass all the events to the children using the `fltk::Group::handle()` method. You don't need to override `handle()` if your composite widget does nothing other than pass events to the children:

    int MyClass::handle(int event) {
      if (fltk::Group::handle(event)) return 1;
      ... handle events that children don't want ...
    }

If you override `draw()` you need to draw all the children. If `redraw()` or `damage()` is called on a child, `damage(fltk::DAMAGE_CHILD)` is done to the group, so this bit of `damage()` can be used to indicate that a child needs to be drawn. It is fastest if you avoid drawing anything else in this case:

    int MyClass::draw() {
      fltk::Widget *const*a = array();
      if (damage() == fltk::DAMAGE_CHILD) { // only redraw some children
        for (int i = children(); i --; a ++) update_child(**a);
      } else { // total redraw
        ... draw background graphics ...
        // now draw all the children atop the background:
        for (int i = children_; i --; a ++) {
          draw_child(**a);
          draw_outside_label(**a); // you may not want to do this
        }
      }
    }

`fltk::Group` provides some protected methods to make drawing easier:

- draw_child
- draw_outside_label
- update_child

#### void fltk::Group::draw_child(fltk::Widget&)

This will force the child's `damage()` bits all to one and call `draw()` on it, then clear the `damage()`. You should call this on all children if a total redraw of your widget is requested, or if you draw something (like a background box) that damages the child. Nothing is done if the child is not `visible()` or if it is clipped.

#### void fltk::Group::draw_outside_label(fltk::Widget&) const

Draw the labels that are not drawn by `draw_inside_label()`. If you want more control over the label positions you might want to call `child->draw_label(x,y,w,h,a)`.

#### void fltk::Group::update_child(fltk::Widget&)

Draws the child only if its `damage()` is non-zero. You should call this on all the children if your own damage is equal to fltk::DAMAGE_CHILD. Nothing is done if the child is not `visible()` or if it is clipped.

## Making a subclass of fltk::Window

You may want your widget to be a subclass of `fltk::Window`. This can be useful if your widget wants to occupy an entire window, and can also be used to take advantage of system-provided clipping, or to work with a library that expects a system window ID to indicate where to draw.

Subclassing `fltk::Window`is almost exactly like subclassing `fltk::Widget`, and in fact you can easily switch a subclass back and forth. Warning: `fltk::Window` is a subclass of `fltk::Group` so make sure your constructor calls `end()` (unless you actually want children added to your window).

You may also want to subclass `fltk::Window` in order to get access to different visuals or to change other attributes of the windows. See the X-specific documentation for more information.