diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
| commit | f9039b2ae21988783feae9b362818e7923e82d14 (patch) | |
| tree | 6d6fe3679d73448758f9794e7d4d4f6b22a4adad /src/Fl_Positioner.cxx | |
| parent | 67e89232f9ba067825a158734a09e0fa21aacbe3 (diff) | |
Initial revision
git-svn-id: file:///fltk/svn/fltk/trunk@2 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Positioner.cxx')
| -rw-r--r-- | src/Fl_Positioner.cxx | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/Fl_Positioner.cxx b/src/Fl_Positioner.cxx new file mode 100644 index 000000000..017a4ef4d --- /dev/null +++ b/src/Fl_Positioner.cxx @@ -0,0 +1,106 @@ +// Fl_Positioner.C + +// The positioner widget from Forms, gives 2D input +// Written by: Mark Overmars + +#include <FL/Fl.H> +#include <FL/Fl_Positioner.H> +#include <FL/fl_draw.H> + +static double flinear(double val, double smin, double smax, double gmin, double gmax) +{ + if (smin == smax) return gmax; + else return gmin + (gmax - gmin) * (val - smin) / (smax - smin); +} + +void Fl_Positioner::draw(int x, int y, int w, int h) { + int x1 = x + 4; + int y1 = y + 4; + int w1 = w - 2 * 4; + int h1 = h - 2 * 4; + int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5); + int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5); + draw_box(box(), x, y, w, h, color()); + fl_color(selection_color()); + fl_xyline(x1, yy, x1+w1); + fl_yxline(xx, y1, y1+h1); +} + +void Fl_Positioner::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +int Fl_Positioner::value(double X, double Y) { + clear_changed(); + if (X == xvalue_ && Y == yvalue_) return 0; + xvalue_ = X; yvalue_ = Y; + redraw(); + return 1; +} + +int Fl_Positioner::xvalue(double X) { + return(value(X, yvalue_)); +} + +int Fl_Positioner::yvalue(double Y) { + return(value(xvalue_, Y)); +} + +int Fl_Positioner::handle(int event, int x, int y, int w, int h) { + switch (event) { + case FL_PUSH: + case FL_DRAG: + case FL_RELEASE: { + double x1 = x + 4; + double y1 = y + 4; + double w1 = w - 2 * 4; + double h1 = h - 2 * 4; + double X = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax); + if (xstep_) X = int(X/xstep_+0.5) * xstep_; + if (X < xmin) X = xmin; + if (X > xmax) X = xmax; + double Y = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax); + if (ystep_) Y = int(Y/ystep_+0.5) * ystep_; + if (Y < ymin) Y = ymin; + if (Y > ymax) Y = ymax; + if (value(X, Y)) set_changed();} + if (!(when() & FL_WHEN_CHANGED || + when() & FL_WHEN_RELEASE && event == FL_RELEASE)) return 1; + if (changed() || when()&FL_WHEN_NOT_CHANGED) { + clear_changed(); do_callback();} + return 1; + default: + return 0; + } +} + +int Fl_Positioner::handle(int e) { + return handle(e, x(), y(), w(), h()); +} + +Fl_Positioner::Fl_Positioner(int x, int y, int w, int h, const char* l) +: Fl_Widget(x, y, w, h, l) { + box(FL_DOWN_BOX); + selection_color(FL_RED); + align(FL_ALIGN_BOTTOM); + when(FL_WHEN_CHANGED); + xmin = ymin = 0; + xmax = ymax = 1; + xvalue_ = yvalue_ = .5; + xstep_ = ystep_ = 0; +} + +void Fl_Positioner::xbounds(double a, double b) { + if (a != xmin || b != xmax) { + xmin = a; xmax = b; + redraw(); + } +} + +void Fl_Positioner::ybounds(double a, double b) { + if (a != ymin || b != ymax) { + ymin = a; ymax = b; + redraw(); + } +} |
