Add initial log support for sliders (#1232).

Works for all slider types.
Adds tick marks to "nice slider".
Defaults to linear if min or max is zero.
There is room for improvement for drawing the tick marks.
This commit is contained in:
Matthias Melcher 2025-11-26 14:07:34 +01:00
parent 9e5467d5c1
commit 86b9df01ee
3 changed files with 262 additions and 66 deletions

View File

@ -24,7 +24,8 @@
#include "Fl_Valuator.H"
#endif
// values for type(), lowest bit indicate horizontal:
#include <FL/Fl_Rect.H>
#define FL_VERT_SLIDER 0
#define FL_HOR_SLIDER 1
#define FL_VERT_FILL_SLIDER 2
@ -58,10 +59,39 @@
*/
class FL_EXPORT Fl_Slider : public Fl_Valuator {
public:
/// Bitset for tick mark positions for Fl_Nice_Slider.
/// \see Fl_Slider::ticks(), Fl_Slider::ticks(Tick_Position)
typedef enum : uchar {
TICKS_NONE = 0x00, ///< draw no ticks
TICKS_BELOW = 0x01, ///< draw ticks below a horizontal slider
TICKS_ABOVE = 0x02, ///< draw ticks above a horizontal slider
TICKS_LEFT = 0x01, ///< draw ticks to the left of a vertical slider
TICKS_RIGHT = 0x02 ///< draw ticks to the right of a vertical slider
// Later: LABEL : label the first, middle, and last tick with its value
// Later: FRACTIONAL : make a half ticks a bit shorter, and quarter ticks even shorter
// Later: DECIMAL: make .5 ticks shorter and 0.1 ticks even shorter
// Later: POINTY_KNOB : make the slider knob pointy on the side where the ticks are
// Later: SMALLE_KNOB : make the slider knob small, so the ticks are better visible
} Tick_Position;
/// Bitset for tick mark positions for Fl_Nice_Slider.
/// \see Fl_Slider::ticks(), Fl_Slider::ticks(Tick_Position)
typedef enum : uchar {
LINEAR_SCALE = 0, ///< Linear scale (default)
LOG_SCALE ///< Logarithmic scale
} Scale_Type;
private:
float slider_size_;
uchar slider_;
Scale_Type scale_type_ { LINEAR_SCALE };
Tick_Position ticks_ { TICKS_NONE };
uchar num_ticks_ { 11 };
void _Fl_Slider();
void draw_bg(int, int, int, int);
void draw_bg(int, int, int, int, int S=16);
protected:
@ -69,6 +99,9 @@ protected:
void draw(int, int, int, int);
int handle(int, int, int, int, int);
void draw() override;
void draw_ticks(const Fl_Rect& r, int S);
double value_to_position(double val) const;
double position_to_value(double pos) const;
public:
@ -100,6 +133,34 @@ public:
/** Sets the slider box type. */
void slider(Fl_Boxtype c) {slider_ = (uchar)c;}
/** Gets the scale type.
\return scale type
*/
Scale_Type scale() const { return scale_type_; }
/** Sets the scale type.
\param[in] s scale type
*/
void scale(Scale_Type s) { scale_type_ = s; }
/** Gets the tick mark position.
\return tick mark position bitset
*/
uchar ticks() const { return ticks_; }
/** Gets the number of tick marks.
\return number of tick marks
*/
uchar num_ticks() const { return num_ticks_; }
/** Sets the tick mark position for Fl_Nice_Slider.
FL_TICKS_BELOW and FL_TICKS_ABOVE can be or'd together for horizontal sliders,
and FL_TICKS_LEFT and FL_TICKS_RIGHT for vertical sliders.
\param[in] t tick mark position bitset
\param[in] num_ticks number of tick marks to draw
*/
void ticks(uchar t, uchar num_ticks=11) { ticks_ = (Tick_Position)t; num_ticks_ = num_ticks; }
};
#endif

View File

@ -95,16 +95,18 @@ int Fl_Slider::scrollvalue(int pos, int size, int first, int total) {
// right (top) the left (bottom) edge is not all the way over, a
// position on the widget itself covers a wider range than 0-1,
// actually it ranges from 0 to 1/(1-size).
void Fl_Slider::draw_bg(int X, int Y, int W, int H) {
// S is the size of the slider knob
void Fl_Slider::draw_bg(int X, int Y, int W, int H, int S) {
fl_push_clip(X, Y, W, H);
draw_box();
fl_pop_clip();
Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR;
if (type() == FL_VERT_NICE_SLIDER) {
if (ticks()) draw_ticks(Fl_Rect { X, Y+S/2, W, H-S}, S);
draw_box(FL_THIN_DOWN_BOX, X+W/2-2, Y, 4, H, black);
} else if (type() == FL_HOR_NICE_SLIDER) {
if (ticks()) draw_ticks(Fl_Rect { X+S/2, Y, W-S, H}, S);
draw_box(FL_THIN_DOWN_BOX, X, Y+H/2-2, W, 4, black);
}
}
@ -114,11 +116,8 @@ void Fl_Slider::draw(int X, int Y, int W, int H) {
double val;
if (minimum() == maximum())
val = 0.5;
else {
val = (value()-minimum())/(maximum()-minimum());
if (val > 1.0) val = 1.0;
else if (val < 0.0) val = 0.0;
}
else
val = value_to_position(value());
int ww = (horizontal() ? W : H);
int xx, S;
@ -146,7 +145,7 @@ void Fl_Slider::draw(int X, int Y, int W, int H) {
wsl = W;
}
draw_bg(X, Y, W, H);
draw_bg(X, Y, W, H, S);
Fl_Boxtype box1 = slider();
if (!box1) {box1 = (Fl_Boxtype)(box()&-2); if (!box1) box1 = FL_UP_BOX;}
@ -216,6 +215,39 @@ void Fl_Slider::draw() {
h()-Fl::box_dh(box()));
}
/** Draw tick marks.
\param[in] r motion range of the slider
\param[in] S size of the slider, horizontal or vertical
*/
void Fl_Slider::draw_ticks(const Fl_Rect& r, int /*S*/ /*, int min_spacing*/)
{
if ((ticks() == TICKS_NONE) || (num_ticks() == 0)) return;
Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR;
fl_color(black);
int n = num_ticks();
double nd = (double)(n-1);
for (int i=0; i<n; i++) {
double v = i / nd;
if (scale() == LOG_SCALE) {
v = position_to_value(1.0-v);
v = (v - minimum()) / (maximum()-minimum());
}
if (horizontal()) {
int y1, y2;
if (ticks() & TICKS_ABOVE) y1 = r.y(); else y1 = r.y() + r.h()/2;
if (ticks() & TICKS_BELOW) y2 = r.b()-1; else y2 = r.y() + r.h()/2;
fl_yxline(r.r()-v*(r.w()-1)-1, y1, y2);
} else {
int x1, x2;
if (ticks() & TICKS_LEFT) x1 = r.x(); else x1 = r.x() + r.w()/2;
if (ticks() & TICKS_RIGHT) x2 = r.r()-1; else x2 = r.x() + r.w()/2;
fl_xyline(x1, r.b()-v*(r.h()-1)-1, x2);
}
}
}
int Fl_Slider::handle(int event, int X, int Y, int W, int H) {
// Fl_Widget_Tracker wp(this);
switch (event) {
@ -230,11 +262,8 @@ int Fl_Slider::handle(int event, int X, int Y, int W, int H) {
double val;
if (minimum() == maximum())
val = 0.5;
else {
val = (value()-minimum())/(maximum()-minimum());
if (val > 1.0) val = 1.0;
else if (val < 0.0) val = 0.0;
}
else
val = value_to_position(value());
int ww = (horizontal() ? W : H);
int mx = (horizontal() ? Fl::event_x()-X : Fl::event_y()-Y);
@ -279,7 +308,9 @@ int Fl_Slider::handle(int event, int X, int Y, int W, int H) {
xx = ww-S;
offcenter = mx-xx; if (offcenter > S) offcenter = S;
}
v = round(xx*(maximum()-minimum())/(ww-S) + minimum());
// Convert position back to value using the appropriate scale
double pos = (ww-S) > 0 ? double(xx) / double(ww-S) : 0.0;
v = round(position_to_value(pos));
// make sure a click outside the sliderbar moves it:
if (event == FL_PUSH && v == value()) {
offcenter = S/2;
@ -346,6 +377,7 @@ int Fl_Slider::handle(int event, int X, int Y, int W, int H) {
}
}
int Fl_Slider::handle(int event) {
if (event == FL_PUSH && Fl::visible_focus()) {
Fl::focus(this);
@ -393,3 +425,63 @@ Fl_Nice_Slider::Fl_Nice_Slider(int X,int Y,int W,int H,const char *L)
type(FL_VERT_NICE_SLIDER);
box(FL_FLAT_BOX);
}
/**
Converts a value to a normalized position (0.0 to 1.0) based on the current scale type.
For linear scale, this is a simple linear interpolation.
For logarithmic scale, this uses logarithmic interpolation.
\param[in] val The value to convert.
\return A normalized position between 0.0 and 1.0.
*/
double Fl_Slider::value_to_position(double val) const {
if (minimum() == maximum()) return 0.5;
if (scale_type_ == LOG_SCALE) {
// For logarithmic scale, both min and max must be positive
if (minimum() <= 0 || maximum() <= 0 || val <= 0) {
// Fall back to linear if values are not suitable for log scale
double pos = (val - minimum()) / (maximum() - minimum());
if (pos > 1.0) pos = 1.0;
else if (pos < 0.0) pos = 0.0;
return pos;
}
double log_min = log(minimum());
double log_max = log(maximum());
double log_val = log(val);
double pos = (log_val - log_min) / (log_max - log_min);
if (pos > 1.0) pos = 1.0;
else if (pos < 0.0) pos = 0.0;
return pos;
} else {
// Linear scale
double pos = (val - minimum()) / (maximum() - minimum());
if (pos > 1.0) pos = 1.0;
else if (pos < 0.0) pos = 0.0;
return pos;
}
}
/**
Converts a normalized position (0.0 to 1.0) to a value based on the current scale type.
For linear scale, this is a simple linear interpolation.
For logarithmic scale, this uses exponential interpolation.
\param[in] pos The normalized position to convert.
\return The corresponding value.
*/
double Fl_Slider::position_to_value(double pos) const {
if (minimum() == maximum()) return minimum();
if (scale_type_ == LOG_SCALE) {
// For logarithmic scale, both min and max must be positive
if (minimum() <= 0 || maximum() <= 0) {
// Fall back to linear if values are not suitable for log scale
return pos * (maximum() - minimum()) + minimum();
}
double log_min = log(minimum());
double log_max = log(maximum());
return exp(pos * (log_max - log_min) + log_min);
} else {
// Linear scale
return pos * (maximum() - minimum()) + minimum();
}
}

View File

@ -2,234 +2,277 @@
version 1.0500
header_name {.h}
code_name {.cxx}
include_guard {}
Function {} {open
} {
Fl_Window {} {
label {Valuator classes, showing values for type()} open
xywh {409 271 580 640} type Double color 43 selection_color 43
xywh {454 295 620 640} type Double color 43 selection_color 43
code0 {\#include <stdio.h>} visible
} {
Fl_Group {} {
label Fl_Slider
xywh {10 10 280 210} box ENGRAVED_BOX labelfont 1 align 17
label Fl_Slider open
xywh {10 10 320 210} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Slider {} {
label 0
user_data {"Fl_Slider FL_VERT_SLIDER"}
callback callback
tooltip {Vertical Slider} xywh {30 45 20 145} selection_color 1 labelsize 8 align 1
tooltip {Vertical Slider} xywh {30 70 20 140} selection_color 1 labelsize 8 align 1 v_label_margin 2
}
Fl_Slider {} {
label FL_VERT_FILL_SLIDER
label {FL_VERT_FILL_SLIDER
|
|
|}
user_data {"Fl_Slider FL_VERT_FILL_SLIDER"}
callback callback
xywh {70 55 20 145} type {Vert Fill} selection_color 1 labelsize 8
xywh {70 70 20 140} type {Vert Fill} selection_color 1 labelsize 8 align 5
}
Fl_Slider {} {
label FL_VERT_NICE_SLIDER
label {FL_VERT_NICE_SLIDER
|
|}
user_data {"Fl_Slider FL_VERT_NICE_SLIDER"}
callback callback
xywh {105 45 20 145} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 1
xywh {105 70 20 140} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 5
}
Fl_Slider {} {
label {TICKS_RIGHT
|}
user_data {"Fl_Slider FL_VERT_NICE_SLIDER"}
callback callback
xywh {138 70 20 140} type {Vert Knob} box FLAT_BOX selection_color 1 labelsize 8 align 5
code0 {o->ticks(Fl_Slider::TICKS_RIGHT);}
}
Fl_Slider {} {
label FL_HORIZONTAL
user_data {"Fl_Slider FL_HORIZONTAL"}
callback callback
xywh {140 80 130 20} type Horizontal selection_color 1 labelsize 8
xywh {190 75 130 20} type Horizontal selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Slider {} {
label FL_HOR_FILL_SLIDER
user_data {"Fl_Slider FL_HOR_FILL_SLIDER"}
callback callback
xywh {140 120 130 20} type {Horz Fill} selection_color 1 labelsize 8
xywh {190 110 130 20} type {Horz Fill} selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Slider {} {
label FL_HOR_NICE_SLIDER
user_data {"Fl_Slider FL_HOR_NICE_SLIDER"}
callback callback
xywh {140 160 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8
xywh {190 145 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Slider {} {
label {TICKS_ABOVE|TICKS_BELOW}
user_data {"Fl_Slider FL_HOR_NICE_SLIDER"}
callback callback
xywh {190 180 130 20} type {Horz Knob} box FLAT_BOX selection_color 1 labelsize 8 v_label_margin 2
code0 {o->ticks(Fl_Slider::TICKS_ABOVE|Fl_Slider::TICKS_BELOW);}
}
}
Fl_Group {} {
label Fl_Value_Slider
xywh {10 230 280 210} box ENGRAVED_BOX labelfont 1 align 17
label Fl_Value_Slider open
xywh {10 230 320 210} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Value_Slider {} {
label 0
user_data {"FL_VERT_SLIDER"}
callback callback
tooltip {Value Slider} xywh {30 260 30 145} selection_color 1 labelsize 8 align 1
tooltip {Value Slider} xywh {30 290 30 140} selection_color 1 labelsize 8 align 1 v_label_margin 2
}
Fl_Value_Slider {} {
label FL_VERT_FILL_SLIDER
label {FL_VERT_FILL_SLIDER
|
|
|}
user_data {"Fl_Value_Slider FL_VERT_FILL_SLIDER"}
callback callback
xywh {70 275 30 140} type {Vert Fill} selection_color 1 labelsize 8
callback callback selected
xywh {70 290 30 140} type {Vert Fill} selection_color 1 labelsize 8 align 5
}
Fl_Value_Slider {} {
label FL_VERT_NICE_SLIDER
label {FL_VERT_NICE_SLIDER
|
|}
user_data {"Fl_Value_Slider FL_VERT_NICE_SLIDER"}
callback callback
xywh {110 260 20 145} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 1
xywh {110 290 20 140} type {Vert Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 align 5
}
Fl_Value_Slider {} {
label {LOG_SCALE
|}
user_data {"Fl_Value_Slider FL_VERT_NICE_SLIDER"}
callback callback
xywh {142 290 20 140} type {Vert Knob} box FLAT_BOX selection_color 1 labelsize 8 align 5 minimum 100 step 1 value 1
code0 {o->scale(Fl_Slider::LOG_SCALE);}
code1 {o->ticks(Fl_Slider::TICKS_RIGHT);}
}
Fl_Value_Slider {} {
label FL_HOR_SLIDER
user_data {"Fl_Value_Slider FL_HOR_SLIDER"}
callback callback
xywh {140 290 130 20} type Horizontal selection_color 1 labelsize 8
xywh {190 295 130 20} type Horizontal selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Value_Slider {} {
label FL_HOR_FILL_SLIDER
user_data {"Fl_Value_Slider FL_HOR_FILL_SLIDER"}
callback callback
xywh {140 330 130 20} type {Horz Fill} selection_color 1 labelsize 8
xywh {190 330 130 20} type {Horz Fill} selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Value_Slider {} {
label FL_HOR_NICE_SLIDER
user_data {"Fl_Value_Slider FL_HOR_NICE_SLIDER"}
callback callback
xywh {140 370 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8
xywh {190 365 130 20} type {Horz Knob} box FLAT_BOX color 10 selection_color 1 labelsize 8 v_label_margin 2
}
Fl_Value_Slider {} {
label LOG_SCALE
user_data {"Fl_Value_Slider FL_HOR_NICE_SLIDER"}
callback callback
xywh {190 400 130 20} type {Horz Knob} box FLAT_BOX selection_color 1 labelsize 8 v_label_margin 2 minimum 1 maximum 100 step 1
code0 {o->ticks(Fl_Slider::TICKS_ABOVE|Fl_Slider::TICKS_BELOW);}
code1 {o->scale(Fl_Slider::LOG_SCALE);}
}
}
Fl_Group {} {
label Fl_Value_Input
xywh {10 450 135 50} box ENGRAVED_BOX labelfont 1 align 17
xywh {10 450 155 50} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Value_Input {} {
label 0
user_data {"Fl_Value_Input"}
callback callback
tooltip {Value Input} xywh {30 470 105 25} labelsize 8 maximum 100 step 0.1
tooltip {Value Input} xywh {30 470 125 25} labelsize 8 maximum 100 step 0.1
}
}
Fl_Group {} {
label Fl_Value_Output
user_data {"Fl_Value_Output"}
xywh {155 450 135 50} box ENGRAVED_BOX labelfont 1 align 17
xywh {175 450 155 50} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Value_Output {} {
label 0
callback callback
tooltip {Value Output} xywh {170 470 105 25} labelsize 8 maximum 100 step 0.1
tooltip {Value Output} xywh {190 470 125 25} labelsize 8 maximum 100 step 0.1
}
}
Fl_Group {} {
label { Fl_Scrollbar}
xywh {300 10 130 120} box ENGRAVED_BOX labelfont 1 align 21
label { Fl_Scrollbar} open
xywh {340 10 130 120} box ENGRAVED_BOX labelfont 1 align 21
} {
Fl_Scrollbar {} {
label FL_HORIZONTAL
user_data {"Fl_Scrollbar FL_HORIZONTAL"}
callback callback
tooltip {Horizontal Scrollbar} xywh {305 55 95 20} type Horizontal labelsize 8 maximum 100 value 20
tooltip {Horizontal Scrollbar} xywh {345 55 95 20} type Horizontal labelsize 8 v_label_margin 2 maximum 100 value 20
}
Fl_Scrollbar {} {
label {FL_VERTICAL (0) ->}
user_data {"Fl_Scrollbar FL_VERTICAL"}
callback callback
tooltip {Vertical Scrollbar} xywh {405 30 20 90} labelsize 8 align 13 maximum 100 value 20
tooltip {Vertical Scrollbar} xywh {445 30 20 90} labelsize 8 align 13 maximum 100 value 20
}
}
Fl_Group {} {
label Fl_Adjuster
xywh {440 10 130 120} box ENGRAVED_BOX labelfont 1 align 17
xywh {480 10 130 120} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Adjuster {} {
label {w()>h()}
user_data {"Fl_Adjuster w()>h()"}
callback callback
tooltip {Horizontal Adjuster} xywh {450 60 75 25} labelsize 8
tooltip {Horizontal Adjuster} xywh {490 60 75 25} labelsize 8 v_label_margin 2
}
Fl_Adjuster {} {
label {w()<h()}
user_data {"Fl_Adjuster w()<h()"}
callback callback
tooltip {Vertical Adjuster} xywh {530 35 25 75} labelsize 8
tooltip {Vertical Adjuster} xywh {570 35 25 75} labelsize 8 v_label_margin 2
}
}
Fl_Group {} {
label Fl_Counter
xywh {300 140 130 120} box ENGRAVED_BOX labelfont 1 align 17
xywh {340 140 130 120} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Counter {} {
label 0
user_data {"Fl_Counter"}
callback callback
tooltip {Standard Counter} xywh {310 175 110 25} labelsize 8
tooltip {Standard Counter} xywh {350 175 110 25} labelsize 8 v_label_margin 2
}
Fl_Counter {} {
label FL_SIMPLE_COUNTER
user_data {"Fl_Counter FL_SIMPLE_COUNTER"}
callback callback
tooltip {Simple Counter} xywh {310 215 110 25} type Simple labelsize 8
tooltip {Simple Counter} xywh {350 215 110 25} type Simple labelsize 8 v_label_margin 2
}
}
Fl_Group {} {
label Fl_Spinner
xywh {440 140 130 120} box ENGRAVED_BOX labelfont 1 align 17
xywh {480 140 130 120} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Spinner {} {
label FL_INT_INPUT
user_data {"Fl_Spinner FL_INT_INPUT"}
callback callback_spinner
xywh {465 176 80 24} labelsize 8 align 2 minimum -30 maximum 30 step 2 value 5
xywh {505 176 80 24} labelsize 8 align 2 v_label_margin 2 minimum -30 maximum 30 step 2 value 5
}
Fl_Spinner {} {
label FL_FLOAT_INPUT
user_data {"Fl_Spinner FL_FLOAT_INPUT"}
callback callback_spinner
xywh {465 216 80 24} type Float labelsize 8 align 2 minimum 0 maximum 1 step 0.01 value 0.05
xywh {505 216 80 24} type Float labelsize 8 align 2 v_label_margin 2 minimum 0 maximum 1 step 0.01 value 0.05
code0 {o->wrap(0); // disable wrap mode}
}
}
Fl_Group {} {
label Fl_Dial
xywh {300 270 270 105} box ENGRAVED_BOX labelfont 1 align 17
xywh {340 270 270 105} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Dial {} {
label 0
user_data {"Fl_Dial"}
callback callback
tooltip {Standard Dial} xywh {320 295 65 65} color 10 selection_color 1 labelsize 8 value 0.5
tooltip {Standard Dial} xywh {360 295 65 65} color 10 selection_color 1 labelsize 8 v_label_margin 2 value 0.5
code0 {o->angles(0,315);}
}
Fl_Dial {} {
label FL_LINE_DIAL
user_data {"Fl_Dial FL_LINE_DIAL"}
callback callback
tooltip {Line Dial} xywh {400 295 65 65} type Line color 10 selection_color 1 labelsize 8 value 0.5
tooltip {Line Dial} xywh {440 295 65 65} type Line color 10 selection_color 1 labelsize 8 v_label_margin 2 value 0.5
}
Fl_Dial {} {
label FL_FILL_DIAL
user_data {"Fl_Dial FL_FILL_DIAL"}
callback callback
tooltip {Fill Dial} xywh {480 295 65 65} type Fill color 10 selection_color 1 labelsize 8 value 1
tooltip {Fill Dial} xywh {520 295 65 65} type Fill color 10 selection_color 1 labelsize 8 v_label_margin 2 value 1
code0 {o->angles(0,360);}
}
}
Fl_Group {} {
label Fl_Roller
xywh {300 385 150 115} box ENGRAVED_BOX labelfont 1 align 17
xywh {340 385 150 115} box ENGRAVED_BOX labelfont 1 align 17
} {
Fl_Roller {} {
label 0
user_data {"Fl_Roller FL_VERTICAL"}
callback callback
tooltip {Vertical Roller} xywh {315 390 20 95} labelsize 8
tooltip {Vertical Roller} xywh {355 390 20 95} labelsize 8 v_label_margin 2
}
Fl_Roller {} {
label FL_HORIZONTAL
user_data {"Fl_Roller FL_HORIZONTAL"}
callback callback
tooltip {Horizontal Roller} xywh {345 430 90 20} type Horizontal labelsize 8
tooltip {Horizontal Roller} xywh {385 430 90 20} type Horizontal labelsize 8 v_label_margin 2
}
}
Fl_Box {} {
label {Some widgets have color(FL_GREEN) and color2(FL_RED) to show the areas these effect.}
xywh {460 385 110 115} box BORDER_FRAME color 0 selection_color 0 labelsize 11 align 128
xywh {500 385 110 115} box BORDER_FRAME color 0 selection_color 0 labelsize 11 align 128
}
Fl_Terminal tty {selected
xywh {10 513 560 117}
Fl_Terminal tty {
xywh {10 513 600 117}
code0 {o->ansi(true);}
}
}