> I have an app with a dial on it and would like to have it wrap around, so
> I can just keep turning it, but can't see how to do it. Is there a way?


Hmm, this works (see attached) though was more of a hassle than I'd expected...

------------------

//
// Test a demo of a roller that wraps over...
//

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Roller.H>
#include <FL/Fl_Dial.H>

#include <stdio.h>
#include <math.h>

static Fl_Double_Window *main_win = NULL;

/******************************************************************************/
static double wrap_clamp(Fl_Valuator *w, double v) {
  double min = w->minimum();
  double max = w->maximum();
  double res = v;
  if ((v<min)==(min<=max)) res = (max - (min - v));
  else if ((v>max)==(min<=max)) res = (min + (v - max));
  return res;
}
/******************************************************************************/
class Roll_Over : public Fl_Roller {
    public:
    Roll_Over(int X, int Y, int W, int H) : Fl_Roller(X, Y, W, H) { };
    double clamp(double v) {return wrap_clamp(this,v);};
    int handle(int event);
};

int Roll_Over::handle(int event) {
  static int ipos;
  int newpos = horizontal() ? Fl::event_x() : Fl::event_y();
  switch (event) {
  case FL_PUSH:
    if (Fl::visible_focus()) {
      Fl::focus(this);
      redraw();
    }
    handle_push();
    ipos = newpos;
    return 1;
  case FL_DRAG:
    handle_drag(clamp(round(increment(previous_value(),newpos-ipos))));
    return 1;
  case FL_RELEASE:
    handle_release();
    return 1;
  case FL_KEYBOARD :
    switch (Fl::event_key()) {
      case FL_Up:
        if (horizontal()) return 0;
        handle_drag(clamp(increment(value(),-1)));
        return 1;
      case FL_Down:
        if (horizontal()) return 0;
        handle_drag(clamp(increment(value(),1)));
        return 1;
      case FL_Left:
        if (!horizontal()) return 0;
        handle_drag(clamp(increment(value(),-1)));
        return 1;
      case FL_Right:
        if (!horizontal()) return 0;
        handle_drag(clamp(increment(value(),1)));
        return 1;
      default:
        return 0;
    }
    // break not required because of switch...
  case FL_FOCUS :
  case FL_UNFOCUS :
    if (Fl::visible_focus()) {
      redraw();
      return 1;
    } else return 0;
  case FL_ENTER :
  case FL_LEAVE :
    return 1;
  default:
    return 0;
  }
}

static Roll_Over *roller = NULL;
/******************************************************************************/
class Wrap_Dial : public Fl_Dial {
    public:
    Wrap_Dial(int X, int Y, int W, int H) : Fl_Dial(X, Y, W, H) 
{angle1(360);angle2(0); };
    double clamp(double v) {return wrap_clamp(this,v);};
    int handle(int event, int X, int Y, int W, int H);
    int handle(int e) {return handle(e, x(), y(), w(), h());};
};

int Wrap_Dial::handle(int event, int X, int Y, int W, int H) {
  short a1 = angle1();
  short a2 = angle2();
  switch (event) {
  case FL_PUSH: {
    Fl_Widget_Tracker wp(this);
    handle_push();
    if (wp.deleted()) return 1; }
  case FL_DRAG: {
    int mx = (Fl::event_x()-X-W/2)*H;
    int my = (Fl::event_y()-Y-H/2)*W;
    if (!mx && !my) return 1;
    double angle = 270-atan2((float)-my, (float)mx)*180/M_PI;
    double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
    while (angle < oldangle-180) angle += 360;
    while (angle > oldangle+180) angle -= 360;
    double val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
    handle_drag(clamp(round(val)));
  } return 1;
  case FL_RELEASE:
    handle_release();
    return 1;
  case FL_ENTER : /* FALLTHROUGH */
  case FL_LEAVE :
    return 1;
  default:
    return 0;
  }
}

static Wrap_Dial *dial = NULL;
/******************************************************************************/

static void cb_Exit(Fl_Button*, void*) {
  main_win->hide();
}

static void cb_roller(Roll_Over *rl, void *) {
    int val = (int)rl->value();
    printf("roll-to %3d\n", val); fflush(stdout);
}

static void cb_dial(Wrap_Dial *rl, void *) {
    int val = (int)(rl->value() * 100.0);
    printf("dial-to %3d\n", val); fflush(stdout);
}

int main(int argc, char **argv)
{
    main_win = new Fl_Double_Window(551, 366, "Endless Roller Demo");
    main_win->begin();

    Fl_Button* exit_bt = new Fl_Button(476, 326, 64, 28, "Exit");
    exit_bt->callback((Fl_Callback*)cb_Exit);

    roller = new Roll_Over(35, 100, 40, 170);
    roller->step(0.25);
    roller->maximum(50);
    roller->callback((Fl_Callback*)cb_roller);
    roller->clear_visible_focus();

    dial = new Wrap_Dial(100, 100, 100, 100);
    dial->callback((Fl_Callback*)cb_dial);

    main_win->end();

    main_win->show(argc, argv);
    return Fl::run();
}

/* end of file */

------------------


SELEX Galileo Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 
3EL
A company registered in England & Wales.  Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to