DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2951
Version: 1.4-feature
I have an application with a colour bar type legend which does not give
the required resolution, so I needed to be able to adjust the low and
high values in an intuitive but minimally invasive way on screen.
I hacked together the following demonstrator, drawing some inspiration
from Fl_Slider. The features I required were:
- a vertical slider
- possibility of setting min and max values of continuous range (no step)
- possibility to move low and high sliders (min <= low < high <= max)
I then hacked it further to fit directly with the rest of my application.
Questions:
1. Does anybody know of a similar widget out there?
2. Is it worth factoring out a separate DoubleValuator base class?
3. Apart from vertical/horizontal what other features are needed?
4. Does it require min/low/high/max fields?
5. Would a floating tooltip with feedback be enough? (eg Greg's TipWin)
I'd be willing to have a go a this, but can't provide any timeframes.
Link: http://www.fltk.org/str.php?L2951
Version: 1.4-feature
// test program to demonstrate DoubleSlider concept
//
// compile using 'fltk-config --compile filename.cxx'
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
// Double slider widget:
// program sets min and max values, and then user can move sliders
// to reduce the high and low values within this range.
//
class DoubleSlider : public Fl_Box
{
// everything is public as this is just a proof-of-concept
public:
int loPos, hiPos; // pixel position of top of low and high sliders
int top, bottom; // pixel position of top and bottom of range
int clickOffset; // difference between top of slider and mouse
bool loClicked, hiClicked; // which slider has been selected
double lolo, lo, hi, hihi; // min, low, high and max values
DoubleSlider(int X, int Y, int W, int H, char* T=0)
: Fl_Box(X, Y, W, H, T)
{
box(FL_DOWN_BOX);
lolo = lo = 0.0;
hihi = hi = 1.0;
loClicked = false;
hiClicked = false;
clickOffset = 0;
top = Y;
bottom = Y + H;
hiPos = Y;
loPos = Y + H - W;
}
~DoubleSlider()
{
}
// draw within the interior of the box
//
void draw(int X, int Y, int W, int H)
{
int upper = top + Fl::box_dy(box());
int lower = bottom - Fl::box_dy(box());
// calculate widget positions of sliders
hiPos = upper + ((lower-upper - W) * (hihi - hi) / (hihi - lolo));
loPos = upper + ((lower-upper - W) * (hihi - lo) / (hihi - lolo));
// draw background line linking sliders
Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR;
draw_box(FL_THIN_DOWN_BOX, X+W/2-2, hiPos+W/2, 4, loPos-hiPos, black);
// draw sliders
fl_draw_box(FL_UP_BOX, X, hiPos, W, W, selection_color());
fl_draw_box(FL_UP_BOX, X, loPos, W, W, selection_color());
// add the lines across the middle of the sliders
int xi = X + Fl::box_dx(FL_UP_BOX);
int wi = W - Fl::box_dw(FL_UP_BOX);
fl_color(fl_darker(selection_color()));
fl_rectf(xi, hiPos+W/2-1, wi, 3);
fl_rectf(xi, loPos+W/2-1, wi, 3);
}
void draw()
{
if (damage() & FL_DAMAGE_ALL)
{
draw_box(FL_FLAT_BOX, selection_color());
draw_box(box(), x(), top, w(), bottom-top, selection_color());
}
draw( x() + Fl::box_dx(box()),
top + Fl::box_dy(box()),
w() - Fl::box_dw(box()),
bottom- top - Fl::box_dh(box()));
}
int onPush(int X, int Y, int W, int H, int mX, int mY)
{
if (X < mX && mX < X+W && hiPos < mY && mY < hiPos+W)
{
loClicked = false;
hiClicked = true;
clickOffset = mY - hiPos;
return 1;
}
if (X < mX && mX < X+W && loPos < mY && mY < loPos+W)
{
loClicked = true;
hiClicked = false;
clickOffset = mY - loPos;
return 1;
}
loClicked = false;
hiClicked = false;
clickOffset = 0;
return 0;
}
int onDrag(int X, int Y, int W, int H, int mX, int mY)
{
int upper = top + Fl::box_dy(box());
int lower = bottom - Fl::box_dy(box());
double value;
mY = mY - clickOffset;
if (hiClicked == true)
{
mY = (mY > upper) ? mY : upper;
mY = (mY < loPos-W) ? mY : loPos-W;
value = lolo + (lower-W - mY) * (hihi - lolo) / (lower-W - upper);
if (value != hi)
{
hi = value;
redraw();
}
return 1;
}
if (loClicked == true)
{
mY = (mY > hiPos+W) ? mY : hiPos+W;
mY = (mY < lower-W) ? mY : lower-W;
value = lolo + (lower-W - mY) * (hihi - lolo) / (lower-W - upper);
if (value != lo)
{
lo = value;
redraw();
}
return 1;
}
return 0;
}
int onRelease(int X, int Y, int W, int H, int mX, int mY)
{
return 1;
}
int handle(int event, int X, int Y, int W, int H)
{
switch(event)
{
case FL_PUSH:
return onPush(X, Y, W, H, Fl::event_x(), Fl::event_y());
break;
case FL_DRAG:
return onDrag(X, Y, W, H, Fl::event_x(), Fl::event_y());
break;
case FL_RELEASE:
return onRelease(X, Y, W, H, Fl::event_x(), Fl::event_y());
break;
}
return Fl_Box::handle(event);
}
int handle(int event)
{
return handle( event,
x() + Fl::box_dx(box()),
y() + Fl::box_dy(box()),
w() - Fl::box_dw(box()),
h() - Fl::box_dh(box()));
}
};
int main(int argc, char* argv[])
{
Fl_Window* w = new Fl_Window(200, 200);
DoubleSlider* ds = new DoubleSlider(10, 10, 20, 180);
ds->lo = 0.25;
ds->hi = 0.75;
ds->top += 50;
w->end();
w->show(argc, argv);
return Fl::run();
}
_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev