John P. Pfost wrote:

I thought that the intention of FL_WHEN_CHANGED was to allow a user to push and hold a button to start an action which then stops when they released the button.

I wrote a small example that does something like this. I derived a class Fl_Timer_Button from Fl_Box (!) that only calls its callback in a settable interval, as long as the button is pushed. The callback then changes the button's color. Have fun ...

Albrecht
// This example program creates a Fl_Timer_Button. This button calls
// its callback, as long as a mouse button is pressed.
// The class is intentionally derived from Fl_Box and not from Fl_Button.
// Compile with: fltk-config --compile timer_button.cxx

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <stdio.h>

// *** Class Fl_Timer_Button:

class Fl_Timer_Button: public Fl_Box {

  int ci_ ;
  int active_ ;
  double timeout_ ;

  static void Timer_CB (void *);

public:

  Fl_Timer_Button(int X, int Y, int W, int H, char *L=0)
   : Fl_Box (X,Y,W,H,L)
  {
    active_ = 0;
    ci_ = 0;
    timeout_ = 0.25;
    box (FL_UP_BOX);
  };
  
  int Fl_Timer_Button::ci() { return ci_; }
  void Fl_Timer_Button::ci(int i) { ci_ = i; }

  double Fl_Timer_Button::timeout() { return timeout_; }
  void Fl_Timer_Button::timeout(double t) { timeout_ = t; }
  
protected:

  int handle (int ev);

}; // Fl_Timer_Button

int Fl_Timer_Button::handle (int ev)
{
  switch (ev) {
  
    case FL_PUSH:
      if (!active_) {
        active_++;
        box(FL_DOWN_BOX);
        Fl::add_timeout(timeout_,Timer_CB,this);
      }
      Fl_Box::handle(ev);
      redraw();
      return 1;

    case FL_RELEASE:
      if (active_) {
        active_ = 0;
        box(FL_UP_BOX);
        Fl::remove_timeout(Timer_CB);
      }
      Fl_Box::handle(ev);
      redraw();
      return 1;

    default:
      return Fl_Box::handle(ev);
  }
}

void Fl_Timer_Button::Timer_CB (void *v) {
   Fl_Timer_Button *b = (Fl_Timer_Button *)v;
   b->do_callback(b,(void *)0);
   Fl::repeat_timeout(b->timeout(),Timer_CB,b);
}

// *** End of class Fl_Timer_Button

// *** Application code:

static Fl_Color colors [] = {
   FL_RED,FL_YELLOW,FL_GREEN,FL_BLUE,
   FL_BLACK,FL_WHITE };

void button_cb(Fl_Widget *w, void *) {
  Fl_Timer_Button *b = (Fl_Timer_Button *)w;
  int x = b->ci();
  if (++x>5) x=0;
  b->ci(x);
  b->color(colors[x]);
  b->redraw();
}

int main(int argc, char **argv) {

  Fl_Double_Window *win1 = new Fl_Double_Window(400, 200, "Window #1");
  Fl_Timer_Button *but1 = new Fl_Timer_Button(50,50,300,100,
    "Push for test\n\nand keep the mouse button pressed");
  but1->callback(button_cb);
  win1->end();
  win1->show(argc, argv);
  return Fl::run();
}
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to