summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2022-02-13 22:01:16 +0100
committerGitHub <noreply@github.com>2022-02-13 22:01:16 +0100
commit8c3778e13feebced373497a3e4060ae065cf65b7 (patch)
tree96ba807115e42e5f3cd35156343ccf5f700e5559
parentf196ffbb528f9ec5030697bc03fb956f79c9563e (diff)
Better Fluid Widget dimension controls (#394)
* Size and position widgets can evaluate basic math. * Allowing x, y, w, and h as variables for formulas. Also supporting 'i' as a counting index when selecting multiple widgets, so setting Y: to i*25+10 arranges all selected widgets vertically. * Additional variables cx, etc. for children box cx, cy, cw, ch
-rw-r--r--fluid/Fl_Type.cxx24
-rw-r--r--fluid/Fl_Type.h3
-rw-r--r--fluid/Fl_Widget_Type.cxx173
-rw-r--r--fluid/Shortcut_Button.cxx147
-rw-r--r--fluid/Shortcut_Button.h33
-rw-r--r--fluid/widget_panel.cxx60
-rw-r--r--fluid/widget_panel.fl31
-rw-r--r--fluid/widget_panel.h19
8 files changed, 426 insertions, 64 deletions
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx
index 50a59869b..b991e737d 100644
--- a/fluid/Fl_Type.cxx
+++ b/fluid/Fl_Type.cxx
@@ -299,6 +299,30 @@ Fl_Type::~Fl_Type() {
if (comment_) free((void*)comment_);
}
+// Return the previous sibling in the tree structure or NULL.
+Fl_Type *Fl_Type::prev_sibling() {
+ Fl_Type *n;
+ for (n = prev; n && n->level > level; n = n->prev) ;
+ return n;
+}
+
+// Return the next sibling in the tree structure or NULL.
+Fl_Type *Fl_Type::next_sibling() {
+ Fl_Type *n;
+ for (n = next; n && n->level > level; n = n->next) ;
+ if (n->level==level)
+ return n;
+ return 0;
+}
+
+// Return the first child or NULL
+Fl_Type *Fl_Type::first_child() {
+ Fl_Type *n = next;
+ if (n->level > level)
+ return n;
+ return NULL;
+}
+
// Generate a descriptive text for this item, to put in browser & window titles
const char* Fl_Type::title() {
const char* c = name();
diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h
index fa3a81ce9..2fd82f546 100644
--- a/fluid/Fl_Type.h
+++ b/fluid/Fl_Type.h
@@ -68,6 +68,9 @@ public: // things that should not be public:
int level; // number of parents over this
static Fl_Type *first, *last;
Fl_Type *next, *prev;
+ Fl_Type *prev_sibling();
+ Fl_Type *next_sibling();
+ Fl_Type *first_child();
Fl_Type *factory;
const char *callback_name();
diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx
index 918ca70ab..0b523ccca 100644
--- a/fluid/Fl_Widget_Type.cxx
+++ b/fluid/Fl_Widget_Type.cxx
@@ -501,9 +501,160 @@ void tooltip_cb(Fl_Input* i, void *v) {
}
}
-Fl_Value_Input *x_input, *y_input, *w_input, *h_input;
+Fluid_Coord_Input *x_input, *y_input, *w_input, *h_input;
-void x_cb(Fl_Value_Input *i, void *v) {
+static int widget_i = 0;
+
+static int vars_i_cb(const Fluid_Coord_Input*, void *v) {
+ return widget_i;
+}
+
+static int vars_x_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = (Fl_Type*)v;
+ if (t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->x();
+}
+
+static int vars_y_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = (Fl_Type*)v;
+ if (t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->y();
+}
+
+static int vars_w_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = (Fl_Type*)v;
+ if (t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->w();
+}
+
+static int vars_h_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = (Fl_Type*)v;
+ if (t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->h();
+}
+
+static int vars_px_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->parent;
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->x();
+ return 0;
+}
+
+static int vars_py_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->parent;
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->y();
+ return 0;
+}
+
+static int vars_pw_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->parent;
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->w();
+ return 0;
+}
+
+static int vars_ph_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->parent;
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->h();
+ return 0;
+}
+
+static int vars_sx_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->x();
+ return 0;
+}
+
+static int vars_sy_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->y();
+ return 0;
+}
+
+static int vars_sw_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->w();
+ return 0;
+}
+
+static int vars_sh_cb(const Fluid_Coord_Input*, void *v) {
+ Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Fl_Widget_Type*)t)->o->h();
+ return 0;
+}
+
+static int bbox_x, bbox_y, bbox_r, bbox_b;
+static int bbox_min(int a, int b) { return (a<b) ? a : b; }
+static int bbox_max(int a, int b) { return (a>b) ? a : b; }
+
+static void calculate_bbox(Fl_Type *p) {
+ char first = 1;
+ bbox_x = bbox_y = bbox_r = bbox_b = 0;
+ for (p=p->first_child(); p; p=p->next_sibling()) {
+ if (p->is_widget()) {
+ Fl_Widget *o = ((Fl_Widget_Type*)p)->o;
+ if (first) {
+ bbox_x = o->x(); bbox_y = o->y();
+ bbox_r = o->x() + o->w(); bbox_b = o->y() + o->h();
+ first = 0;
+ } else {
+ bbox_x = bbox_min(bbox_x, o->x());
+ bbox_y = bbox_min(bbox_y, o->y());
+ bbox_r = bbox_max(bbox_r, o->x() + o->w());
+ bbox_b = bbox_max(bbox_b, o->y() + o->h());
+ }
+ }
+ }
+}
+
+static int vars_cx_cb(const Fluid_Coord_Input*, void *v) {
+ calculate_bbox((Fl_Type*)v);
+ return bbox_x;
+}
+
+static int vars_cy_cb(const Fluid_Coord_Input*, void *v) {
+ calculate_bbox((Fl_Type*)v);
+ return bbox_y;
+}
+
+static int vars_cw_cb(const Fluid_Coord_Input*, void *v) {
+ calculate_bbox((Fl_Type*)v);
+ return bbox_r - bbox_x;
+}
+
+static int vars_ch_cb(const Fluid_Coord_Input*, void *v) {
+ calculate_bbox((Fl_Type*)v);
+ return bbox_b - bbox_y;
+}
+
+Fluid_Coord_Input_Vars widget_vars[] = {
+ { "i", vars_i_cb }, // zero based counter of selected widgets
+ { "x", vars_x_cb }, // position and size of current widget
+ { "y", vars_y_cb },
+ { "w", vars_w_cb },
+ { "h", vars_h_cb },
+ { "px", vars_px_cb }, // position and size of parent widget
+ { "py", vars_py_cb },
+ { "pw", vars_pw_cb },
+ { "ph", vars_ph_cb },
+ { "sx", vars_sx_cb }, // position and size of previous sibling
+ { "sy", vars_sy_cb },
+ { "sw", vars_sw_cb },
+ { "sh", vars_sh_cb },
+ { "cx", vars_cx_cb }, // position and size of bounding box of all children
+ { "cy", vars_cy_cb },
+ { "cw", vars_cw_cb },
+ { "ch", vars_ch_cb },
+ { 0 }
+};
+
+void x_cb(Fluid_Coord_Input *i, void *v) {
if (v == LOAD) {
x_input = i;
if (current_widget->is_widget()) {
@@ -511,16 +662,19 @@ void x_cb(Fl_Value_Input *i, void *v) {
x_input->activate();
} else x_input->deactivate();
} else {
+ widget_i = 0;
int mod = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
if (o->selected && o->is_widget()) {
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+ i->variables(widget_vars, o);
w->resize((int)i->value(), w->y(), w->w(), w->h());
if (w->window()) w->window()->redraw();
if (o->is_window()) {
((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
gridx, gridy, 0);
}
+ widget_i++;
mod = 1;
}
}
@@ -528,7 +682,7 @@ void x_cb(Fl_Value_Input *i, void *v) {
}
}
-void y_cb(Fl_Value_Input *i, void *v) {
+void y_cb(Fluid_Coord_Input *i, void *v) {
if (v == LOAD) {
y_input = i;
if (current_widget->is_widget()) {
@@ -536,16 +690,19 @@ void y_cb(Fl_Value_Input *i, void *v) {
y_input->activate();
} else y_input->deactivate();
} else {
+ widget_i = 0;
int mod = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
if (o->selected && o->is_widget()) {
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+ i->variables(widget_vars, o);
w->resize(w->x(), (int)i->value(), w->w(), w->h());
if (w->window()) w->window()->redraw();
if (o->is_window()) {
((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
gridx, gridy, 0);
}
+ widget_i++;
mod = 1;
}
}
@@ -553,7 +710,7 @@ void y_cb(Fl_Value_Input *i, void *v) {
}
}
-void w_cb(Fl_Value_Input *i, void *v) {
+void w_cb(Fluid_Coord_Input *i, void *v) {
if (v == LOAD) {
w_input = i;
if (current_widget->is_widget()) {
@@ -561,16 +718,19 @@ void w_cb(Fl_Value_Input *i, void *v) {
w_input->activate();
} else w_input->deactivate();
} else {
+ widget_i = 0;
int mod = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
if (o->selected && o->is_widget()) {
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+ i->variables(widget_vars, o);
w->resize(w->x(), w->y(), (int)i->value(), w->h());
if (w->window()) w->window()->redraw();
if (o->is_window()) {
((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
gridx, gridy, 0);
}
+ widget_i++;
mod = 1;
}
}
@@ -578,7 +738,7 @@ void w_cb(Fl_Value_Input *i, void *v) {
}
}
-void h_cb(Fl_Value_Input *i, void *v) {
+void h_cb(Fluid_Coord_Input *i, void *v) {
if (v == LOAD) {
h_input = i;
if (current_widget->is_widget()) {
@@ -586,16 +746,19 @@ void h_cb(Fl_Value_Input *i, void *v) {
h_input->activate();
} else h_input->deactivate();
} else {
+ widget_i = 0;
int mod = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
if (o->selected && o->is_widget()) {
Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
+ i->variables(widget_vars, o);
w->resize(w->x(), w->y(), w->w(), (int)i->value());
if (w->window()) w->window()->redraw();
if (o->is_window()) {
((Fl_Window *)w)->size_range(gridx, gridy, Fl::w(), Fl::h(),
gridx, gridy, 0);
}
+ widget_i++;
mod = 1;
}
}
diff --git a/fluid/Shortcut_Button.cxx b/fluid/Shortcut_Button.cxx
index cb18aa2cc..72e4470a9 100644
--- a/fluid/Shortcut_Button.cxx
+++ b/fluid/Shortcut_Button.cxx
@@ -14,23 +14,6 @@
// https://www.fltk.org/bugs.php
//
-/// \defgroup fl_type Basic Node for all Widgets and Functions
-/// \{
-
-/** \class Fl_Type
-Each object described by Fluid is one of these objects. They
-are all stored in a double-linked list.
-
-The "type" of the object is covered by the virtual functions.
-There will probably be a lot of these virtual functions.
-
-The type browser is also a list of these objects, but they
-are "factory" instances, not "real" ones. These objects exist
-only so the "make" method can be called on them. They are
-not in the linked list and are not written to files or
-copied or otherwise examined.
-*/
-
#include "Shortcut_Button.h"
#include "fluid.h"
@@ -194,4 +177,132 @@ int Widget_Bin_Window_Button::handle(int inEvent)
return Fl_Button::handle(inEvent);
}
-/// \}
+/** \class Fluid_Coord_Input
+ An Input field for widget coordinates and sizes.
+ This widget adds basic math capability to the text input field.
+ */
+
+Fluid_Coord_Input::Fluid_Coord_Input(int x, int y, int w, int h, const char *l) :
+Fl_Input(x, y, w, h, l),
+user_callback_(0L),
+vars_(0L),
+vars_user_data_(0L)
+{
+ Fl_Input::callback((Fl_Callback*)callback_handler_cb);
+}
+
+void Fluid_Coord_Input::callback_handler_cb(Fluid_Coord_Input *This, void *v) {
+ This->callback_handler(v);
+}
+
+void Fluid_Coord_Input::callback_handler(void *v) {
+ if (user_callback_)
+ (*user_callback_)(this, v);
+ value( value() );
+}
+
+int Fluid_Coord_Input::eval_var(uchar *&s) const {
+ if (!vars_)
+ return 0;
+ // find the end of the variable name
+ uchar *v = s;
+ while (isalpha(*s)) s++;
+ int n = (int)(s-v);
+ // find the variable in the list
+ for (Fluid_Coord_Input_Vars *vars = vars_; vars->name_; vars++) {
+ if (strncmp((char*)v, vars->name_, n)==0 && vars->name_[n]==0)
+ return vars->callback_(this, vars_user_data_);
+ }
+ return 0;
+}
+
+/**
+ Evaluate a textual function into an integer.
+ \param s remaining text in this function
+ \param prio priority of current operation
+ \param flags
+ \return the value so far
+ */
+int Fluid_Coord_Input::eval(uchar *&s, int prio) const {
+ int v =0, sgn = 1;
+ uchar c = *s++;
+
+ // check for unary operator
+ if (c=='-') { sgn = -1; c = *s++; }
+ else if (c=='+') { sgn = 1; c = *s++; }
+
+ if (c>='0' && c<='9') {
+ // numeric value
+ while (c>='0' && c<='9') {
+ v = v*10 + (c-'0');
+ c = *s++;
+ }
+ } else if (isalpha(c)) {
+ v = eval_var(--s);
+ c = *s++;
+ } else if (c=='(') {
+ // opening bracket
+ v = eval(s, 5);
+ } else {
+ return sgn*v; // syntax error
+ }
+ if (sgn==-1) v = -v;
+
+ // Now evaluate all following binary operators
+ for (;;) {
+ if (c==0) {
+ return v;
+ } else if (c=='+' || c=='-') {
+ if (prio<=4) { s--; return v; }
+ if (c=='+') { v += eval(s, 4); }
+ else if (c=='-') { v -= eval(s, 4); }
+ } else if (c=='*' || c=='/') {
+ if (prio<=3) { s--; return v; }
+ if (c=='*') { v *= eval(s, 3); }
+ else if (c=='/') { v /= eval(s, 3); }
+ } else if (c==')') {
+ return v;
+ } else {
+ return v; // syntax error
+ }
+ c = *s++;
+ }
+ return v;
+}
+
+int Fluid_Coord_Input::eval(const char *s) const
+{
+ // duplicate the text, so we can modify it
+ uchar *buf = (uchar*)strdup(s);
+ uchar *src = buf, *dst = buf;
+ // remove all whitespace to make the parser easier
+ for (;;) {
+ uchar c = *src++;
+ if (c==' ' || c=='\t') continue;
+ *dst++ = c;
+ if (c==0) break;
+ }
+ src = buf;
+ // now jump into the recursion
+ int ret = eval(src, 5);
+ ::free(buf);
+ return ret;
+}
+
+
+int Fluid_Coord_Input::value() const {
+
+// int v = 0;
+// v = eval("2+5+10");
+// v = eval("2*5+20"); // 30
+// v = eval("2+5*20"); // 102
+// v = eval("(2+5)*20"); // 140
+// v = eval("2*(2+5)*20"); // 140
+ return eval(text());
+}
+
+void Fluid_Coord_Input::value(int v) {
+ char buf[32];
+ fl_snprintf(buf, sizeof(buf), "%d", v);
+ text(buf);
+}
diff --git a/fluid/Shortcut_Button.h b/fluid/Shortcut_Button.h
index 1c46b8afc..443d2bd67 100644
--- a/fluid/Shortcut_Button.h
+++ b/fluid/Shortcut_Button.h
@@ -18,6 +18,7 @@
#define _FLUID_SHORTCUT_BUTTON_H
#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
class Shortcut_Button : public Fl_Button {
public:
@@ -42,5 +43,37 @@ public:
Fl_Button(X,Y,W,H,l) { }
};
+
+typedef int (Fluid_Coord_Callback)(class Fluid_Coord_Input const *, void*);
+
+typedef struct Fluid_Coord_Input_Vars {
+ const char *name_;
+ Fluid_Coord_Callback *callback_;
+} Fluid_Coord_Input_Vars;
+
+class Fluid_Coord_Input : public Fl_Input {
+ Fl_Callback *user_callback_;
+ Fluid_Coord_Input_Vars *vars_;
+ void *vars_user_data_;
+ static void callback_handler_cb(Fluid_Coord_Input *This, void *v);
+ void callback_handler(void *v);
+ int eval_var(uchar *&s) const;
+ int eval(uchar *&s, int prio) const;
+ int eval(const char *s) const;
+public:
+ Fluid_Coord_Input(int x, int y, int w, int h, const char *l=0L);
+ const char *text() const { return Fl_Input::value(); }
+ void text(const char *v) { Fl_Input::value(v); }
+ int value() const;
+ void value(int v);
+ void callback(Fl_Callback *cb) {
+ user_callback_ = cb;
+ }
+ void variables(Fluid_Coord_Input_Vars *vars, void *user_data) {
+ vars_ = vars;
+ vars_user_data_ = user_data;
+ }
+};
+
#endif
diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx
index f232e0d32..892fcf14b 100644
--- a/fluid/widget_panel.cxx
+++ b/fluid/widget_panel.cxx
@@ -52,13 +52,13 @@ Fl_Menu_Item menu_1[] = {
{0,0,0,0,0,0,0,0,0}
};
-Fl_Value_Input *widget_x_input=(Fl_Value_Input *)0;
+Fluid_Coord_Input *widget_x_input=(Fluid_Coord_Input *)0;
-Fl_Value_Input *widget_y_input=(Fl_Value_Input *)0;
+Fluid_Coord_Input *widget_y_input=(Fluid_Coord_Input *)0;
-Fl_Value_Input *widget_w_input=(Fl_Value_Input *)0;
+Fluid_Coord_Input *widget_w_input=(Fluid_Coord_Input *)0;
-Fl_Value_Input *widget_h_input=(Fl_Value_Input *)0;
+Fluid_Coord_Input *widget_h_input=(Fluid_Coord_Input *)0;
Fl_Menu_Item menu_2[] = {
{"private", 0, 0, (void*)(0), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0},
@@ -262,42 +262,62 @@ Fl_Double_Window* make_widget_panel() {
o->labelsize(11);
o->callback((Fl_Callback*)propagate_load);
o->align(Fl_Align(FL_ALIGN_LEFT));
- { widget_x_input = new Fl_Value_Input(95, 150, 55, 20, "X:");
+ { widget_x_input = new Fluid_Coord_Input(95, 150, 55, 20, "X:");
widget_x_input->tooltip("The X position of the widget.");
+ widget_x_input->box(FL_DOWN_BOX);
+ widget_x_input->color(FL_BACKGROUND2_COLOR);
+ widget_x_input->selection_color(FL_SELECTION_COLOR);
+ widget_x_input->labeltype(FL_NORMAL_LABEL);
+ widget_x_input->labelfont(0);
widget_x_input->labelsize(11);
- widget_x_input->maximum(2048);
- widget_x_input->step(1);
+ widget_x_input->labelcolor(FL_FOREGROUND_COLOR);
widget_x_input->textsize(11);
widget_x_input->callback((Fl_Callback*)x_cb);
widget_x_input->align(Fl_Align(FL_ALIGN_TOP_LEFT));
- } // Fl_Value_Input* widget_x_input
- { widget_y_input = new Fl_Value_Input(155, 150, 55, 20, "Y:");
+ widget_x_input->when(FL_WHEN_RELEASE);
+ } // Fluid_Coord_Input* widget_x_input
+ { widget_y_input = new Fluid_Coord_Input(155, 150, 55, 20, "Y:");
widget_y_input->tooltip("The Y position of the widget.");
+ widget_y_input->box(FL_DOWN_BOX);
+ widget_y_input->color(FL_BACKGROUND2_COLOR);
+ widget_y_input->selection_color(FL_SELECTION_COLOR);
+ widget_y_input->labeltype(FL_NORMAL_LABEL);
+ widget_y_input->labelfont(0);
widget_y_input->labelsize(11);
- widget_y_input->maximum(2048);
- widget_y_input->step(1);
+ widget_y_input->labelcolor(FL_FOREGROUND_COLOR);
widget_y_input->textsize(11);
widget_y_input->callback((Fl_Callback*)y_cb);
widget_y_input->align(Fl_Align(FL_ALIGN_TOP_LEFT));
- } // Fl_Value_Input* widget_y_input
- { widget_w_input = new Fl_Value_Input(215, 150, 55, 20, "Width:");
+ widget_y_input->when(FL_WHEN_RELEASE);
+ } // Fluid_Coord_Input* widget_y_input
+ { widget_w_input = new Fluid_Coord_Input(215, 150, 55, 20, "Width:");
widget_w_input->tooltip("The width of the widget.");
+ widget_w_input->box(FL_DOWN_BOX);
+ widget_w_input->color(FL_BACKGROUND2_COLOR);
+ widget_w_input->selection_color(FL_SELECTION_COLOR);
+ widget_w_input->labeltype(FL_NORMAL_LABEL);
+ widget_w_input->labelfont(0);
widget_w_input->labelsize(11);
- widget_w_input->maximum(2048);
- widget_w_input->step(1);
+ widget_w_input->labelcolor(FL_FOREGROUND_COLOR);
widget_w_input->textsize(11);
widget_w_input->callback((Fl_Callback*)w_cb);
widget_w_input->align(Fl_Align(FL_ALIGN_TOP_LEFT));
- } // Fl_Value_Input* widget_w_input
- { widget_h_input = new Fl_Value_Input(275, 150, 55, 20, "Height:");
+ widget_w_input->when(FL_WHEN_RELEASE);
+ } // Fluid_Coord_Input* widget_w_input
+ { widget_h_input = new Fluid_Coord_Input(275, 150, 55, 20, "Height:");
widget_h_input->tooltip("The height of the widget.");
+ widget_h_input->box(FL_DOWN_BOX);
+ widget_h_input->color(FL_BACKGROUND2_COLOR);
+ widget_h_input->selection_color(FL_SELECTION_COLOR);
+ widget_h_input->labeltype(FL_NORMAL_LABEL);
+ widget_h_input->labelfont(0);
widget_h_input->labelsize(11);
- widget_h_input->maximum(2048);
- widget_h_input->step(1);
+ widget_h_input->labelcolor(FL_FOREGROUND_COLOR);
widget_h_input->textsize(11);
widget_h_input->callback((Fl_Callback*)h_cb);
widget_h_input->align(Fl_Align(FL_ALIGN_TOP_LEFT));
- } // Fl_Value_Input* widget_h_input
+ widget_h_input->when(FL_WHEN_RELEASE);
+ } // Fluid_Coord_Input* widget_h_input
{ Fl_Light_Button* o = new Fl_Light_Button(335, 150, 65, 20, "Relative");
o->tooltip("If set, widgets inside a widget class of type Fl_Group are repositioned relat\
ive to the origin at construction time");
diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl
index 9cf71c5e7..3be7cd5c3 100644
--- a/fluid/widget_panel.fl
+++ b/fluid/widget_panel.fl
@@ -23,13 +23,16 @@ comment {//
decl {\#include "Fl_Widget_Type.h"} {private global
}
+decl {\#include "Shortcut_Button.h"} {selected public global
+}
+
Function {make_widget_panel()} {
comment {Create a panel that can be used with all known widgets} open
} {
Fl_Window {} {
comment {Use a Double Window to avoid flickering.} open
- xywh {500 209 420 400} type Double labelsize 11 align 80 hide resizable hotspot
- code0 {o->size_range(o->w(), o->h());} size_range {420 400 0 0}
+ xywh {500 209 420 400} type Double labelsize 11 align 80 resizable hotspot
+ code0 {o->size_range(o->w(), o->h());} size_range {420 400 0 0} visible
} {
Fl_Tabs {} {
callback {propagate_load((Fl_Group *)o,v);} open
@@ -37,7 +40,7 @@ Function {make_widget_panel()} {
} {
Fl_Group {} {
label GUI
- callback propagate_load selected
+ callback propagate_load open
xywh {10 30 400 330} labelsize 11 when 0 resizable
} {
Fl_Group {} {
@@ -255,28 +258,32 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 1 te
}
Fl_Group {} {
label {Position:}
- callback propagate_load
+ callback propagate_load open
xywh {95 150 314 20} labelfont 1 labelsize 11 align 4
} {
- Fl_Value_Input widget_x_input {
+ Fl_Input widget_x_input {
label {X:}
callback x_cb
- tooltip {The X position of the widget.} xywh {95 150 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+ tooltip {The X position of the widget.} xywh {95 150 55 20} labelsize 11 align 5 textsize 11
+ class Fluid_Coord_Input
}
- Fl_Value_Input widget_y_input {
+ Fl_Input widget_y_input {
label {Y:}
callback y_cb
- tooltip {The Y position of the widget.} xywh {155 150 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+ tooltip {The Y position of the widget.} xywh {155 150 55 20} labelsize 11 align 5 textsize 11
+ class Fluid_Coord_Input
}
- Fl_Value_Input widget_w_input {
+ Fl_Input widget_w_input {
label {Width:}
callback w_cb
- tooltip {The width of the widget.} xywh {215 150 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+ tooltip {The width of the widget.} xywh {215 150 55 20} labelsize 11 align 5 textsize 11
+ class Fluid_Coord_Input
}
- Fl_Value_Input widget_h_input {
+ Fl_Input widget_h_input {
label {Height:}
callback h_cb
- tooltip {The height of the widget.} xywh {275 150 55 20} labelsize 11 align 5 maximum 2048 step 1 textsize 11
+ tooltip {The height of the widget.} xywh {275 150 55 20} labelsize 11 align 5 textsize 11
+ class Fluid_Coord_Input
}
Fl_Light_Button {} {
label Relative
diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h
index 221ac37d6..283b27a3d 100644
--- a/fluid/widget_panel.h
+++ b/fluid/widget_panel.h
@@ -19,6 +19,7 @@
#ifndef widget_panel_h
#define widget_panel_h
#include <FL/Fl.H>
+#include "Shortcut_Button.h"
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
@@ -37,17 +38,17 @@ extern void align_cb(Fl_Button*, void*);
extern void align_text_image_cb(Fl_Choice*, void*);
extern void align_position_cb(Fl_Choice*, void*);
#include <FL/Fl_Box.H>
-#include <FL/Fl_Value_Input.H>
-extern void x_cb(Fl_Value_Input*, void*);
-extern Fl_Value_Input *widget_x_input;
-extern void y_cb(Fl_Value_Input*, void*);
-extern Fl_Value_Input *widget_y_input;
-extern void w_cb(Fl_Value_Input*, void*);
-extern Fl_Value_Input *widget_w_input;
-extern void h_cb(Fl_Value_Input*, void*);
-extern Fl_Value_Input *widget_h_input;
+extern void x_cb(Fluid_Coord_Input*, void*);
+extern Fluid_Coord_Input *widget_x_input;
+extern void y_cb(Fluid_Coord_Input*, void*);
+extern Fluid_Coord_Input *widget_y_input;
+extern void w_cb(Fluid_Coord_Input*, void*);
+extern Fluid_Coord_Input *widget_w_input;
+extern void h_cb(Fluid_Coord_Input*, void*);
+extern Fluid_Coord_Input *widget_h_input;
#include <FL/Fl_Light_Button.H>
extern void wc_relative_cb(Fl_Light_Button*, void*);
+#include <FL/Fl_Value_Input.H>
extern void slider_size_cb(Fl_Value_Input*, void*);
extern void min_cb(Fl_Value_Input*, void*);
extern void max_cb(Fl_Value_Input*, void*);