1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
//
// "$Id$"
//
// Positioner widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
// 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();
}
/** Returns the current position in x and y.*/
int Fl_Positioner::value(double X, double Y) {
clear_changed();
if (X == xvalue_ && Y == yvalue_) return 0;
xvalue_ = X; yvalue_ = Y;
redraw();
return 1;
}
/** Sets the X axis coordinate.*/
int Fl_Positioner::xvalue(double X) {
return(value(X, yvalue_));
}
/** Sets the Y axis coordinate.*/
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 xx = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax);
if (xstep_) xx = int(xx/xstep_+0.5) * xstep_;
if (xmin < xmax) {
if (xx < xmin) xx = xmin;
if (xx > xmax) xx = xmax;
} else {
if (xx > xmin) xx = xmin;
if (xx < xmax) xx = xmax;
}
double yy = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax);
if (ystep_) yy = int(yy/ystep_+0.5) * ystep_;
if (ymin < ymax) {
if (yy < ymin) yy = ymin;
if (yy > ymax) yy = ymax;
} else {
if (yy > ymin) yy = ymin;
if (yy < ymax) yy = ymax;
}
if (xx != xvalue_ || yy != yvalue_) {
xvalue_ = xx; yvalue_ = yy;
set_changed();
redraw();
} }
if (!(when() & FL_WHEN_CHANGED ||
(when() & FL_WHEN_RELEASE && event == FL_RELEASE))) return 1;
if (changed() || when()&FL_WHEN_NOT_CHANGED) {
if (event == FL_RELEASE) clear_changed();
do_callback();
}
return 1;
default:
return 0;
}
}
int Fl_Positioner::handle(int e) {
return handle(e, x(), y(), w(), h());
}
/**
Creates a new Fl_Positioner widget using the given position,
size, and label string. The default boxtype is FL_NO_BOX.
*/
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;
}
/** Sets the X axis bounds.*/
void Fl_Positioner::xbounds(double a, double b) {
if (a != xmin || b != xmax) {
xmin = a; xmax = b;
redraw();
}
}
/** Sets the Y axis bounds.*/
void Fl_Positioner::ybounds(double a, double b) {
if (a != ymin || b != ymax) {
ymin = a; ymax = b;
redraw();
}
}
//
// End of "$Id$".
//
|