DRC | 2ff39b8 | 2011-07-28 08:38:59 +0000 | [diff] [blame] | 1 | // |
| 2 | // "$Id: Fl_Positioner.cxx 7903 2010-11-28 21:06:39Z matt $" |
| 3 | // |
| 4 | // Positioner widget for the Fast Light Tool Kit (FLTK). |
| 5 | // |
| 6 | // Copyright 1998-2010 by Bill Spitzak and others. |
| 7 | // |
| 8 | // This library is free software; you can redistribute it and/or |
| 9 | // modify it under the terms of the GNU Library General Public |
| 10 | // License as published by the Free Software Foundation; either |
| 11 | // version 2 of the License, or (at your option) any later version. |
| 12 | // |
| 13 | // This library is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | // Library General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU Library General Public |
| 19 | // License along with this library; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| 21 | // USA. |
| 22 | // |
| 23 | // Please report all bugs and problems on the following page: |
| 24 | // |
| 25 | // http://www.fltk.org/str.php |
| 26 | // |
| 27 | |
| 28 | |
| 29 | // The positioner widget from Forms, gives 2D input |
| 30 | // Written by: Mark Overmars |
| 31 | |
| 32 | #include <FL/Fl.H> |
| 33 | #include <FL/Fl_Positioner.H> |
| 34 | #include <FL/fl_draw.H> |
| 35 | |
| 36 | static double flinear(double val, double smin, double smax, double gmin, double gmax) |
| 37 | { |
| 38 | if (smin == smax) return gmax; |
| 39 | else return gmin + (gmax - gmin) * (val - smin) / (smax - smin); |
| 40 | } |
| 41 | |
| 42 | void Fl_Positioner::draw(int X, int Y, int W, int H) { |
| 43 | int x1 = X + 4; |
| 44 | int y1 = Y + 4; |
| 45 | int w1 = W - 2 * 4; |
| 46 | int h1 = H - 2 * 4; |
| 47 | int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5); |
| 48 | int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5); |
| 49 | draw_box(box(), X, Y, W, H, color()); |
| 50 | fl_color(selection_color()); |
| 51 | fl_xyline(x1, yy, x1+w1); |
| 52 | fl_yxline(xx, y1, y1+h1); |
| 53 | } |
| 54 | |
| 55 | void Fl_Positioner::draw() { |
| 56 | draw(x(), y(), w(), h()); |
| 57 | draw_label(); |
| 58 | } |
| 59 | |
| 60 | /** Returns the current position in x and y.*/ |
| 61 | int Fl_Positioner::value(double X, double Y) { |
| 62 | clear_changed(); |
| 63 | if (X == xvalue_ && Y == yvalue_) return 0; |
| 64 | xvalue_ = X; yvalue_ = Y; |
| 65 | redraw(); |
| 66 | return 1; |
| 67 | } |
| 68 | |
| 69 | /** Sets the X axis coordinate.*/ |
| 70 | int Fl_Positioner::xvalue(double X) { |
| 71 | return(value(X, yvalue_)); |
| 72 | } |
| 73 | |
| 74 | /** Sets the Y axis coordinate.*/ |
| 75 | int Fl_Positioner::yvalue(double Y) { |
| 76 | return(value(xvalue_, Y)); |
| 77 | } |
| 78 | |
| 79 | int Fl_Positioner::handle(int event, int X, int Y, int W, int H) { |
| 80 | switch (event) { |
| 81 | case FL_PUSH: |
| 82 | case FL_DRAG: |
| 83 | case FL_RELEASE: { |
| 84 | double x1 = X + 4; |
| 85 | double y1 = Y + 4; |
| 86 | double w1 = W - 2 * 4; |
| 87 | double h1 = H - 2 * 4; |
| 88 | double xx = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax); |
| 89 | if (xstep_) xx = int(xx/xstep_+0.5) * xstep_; |
| 90 | if (xmin < xmax) { |
| 91 | if (xx < xmin) xx = xmin; |
| 92 | if (xx > xmax) xx = xmax; |
| 93 | } else { |
| 94 | if (xx > xmin) xx = xmin; |
| 95 | if (xx < xmax) xx = xmax; |
| 96 | } |
| 97 | double yy = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax); |
| 98 | if (ystep_) yy = int(yy/ystep_+0.5) * ystep_; |
| 99 | if (ymin < ymax) { |
| 100 | if (yy < ymin) yy = ymin; |
| 101 | if (yy > ymax) yy = ymax; |
| 102 | } else { |
| 103 | if (yy > ymin) yy = ymin; |
| 104 | if (yy < ymax) yy = ymax; |
| 105 | } |
| 106 | if (xx != xvalue_ || yy != yvalue_) { |
| 107 | xvalue_ = xx; yvalue_ = yy; |
| 108 | set_changed(); |
| 109 | redraw(); |
| 110 | } } |
| 111 | if (!(when() & FL_WHEN_CHANGED || |
| 112 | (when() & FL_WHEN_RELEASE && event == FL_RELEASE))) return 1; |
| 113 | if (changed() || when()&FL_WHEN_NOT_CHANGED) { |
| 114 | if (event == FL_RELEASE) clear_changed(); |
| 115 | do_callback(); |
| 116 | } |
| 117 | return 1; |
| 118 | default: |
| 119 | return 0; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | int Fl_Positioner::handle(int e) { |
| 124 | return handle(e, x(), y(), w(), h()); |
| 125 | } |
| 126 | |
| 127 | /** |
| 128 | Creates a new Fl_Positioner widget using the given position, |
| 129 | size, and label string. The default boxtype is FL_NO_BOX. |
| 130 | */ |
| 131 | Fl_Positioner::Fl_Positioner(int X, int Y, int W, int H, const char* l) |
| 132 | : Fl_Widget(X, Y, W, H, l) { |
| 133 | box(FL_DOWN_BOX); |
| 134 | selection_color(FL_RED); |
| 135 | align(FL_ALIGN_BOTTOM); |
| 136 | when(FL_WHEN_CHANGED); |
| 137 | xmin = ymin = 0; |
| 138 | xmax = ymax = 1; |
| 139 | xvalue_ = yvalue_ = .5; |
| 140 | xstep_ = ystep_ = 0; |
| 141 | } |
| 142 | |
| 143 | /** Sets the X axis bounds.*/ |
| 144 | void Fl_Positioner::xbounds(double a, double b) { |
| 145 | if (a != xmin || b != xmax) { |
| 146 | xmin = a; xmax = b; |
| 147 | redraw(); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | /** Sets the Y axis bounds.*/ |
| 152 | void Fl_Positioner::ybounds(double a, double b) { |
| 153 | if (a != ymin || b != ymax) { |
| 154 | ymin = a; ymax = b; |
| 155 | redraw(); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | // |
| 160 | // End of "$Id: Fl_Positioner.cxx 7903 2010-11-28 21:06:39Z matt $". |
| 161 | // |