On 04.02.2012 07:59, Greg Ercolano wrote:
> On 02/03/12 15:08, testalucida wrote:
>> That's my layout by column of Fl_Output widgets in a Fl_Group:
>> |_|<--- measurement returns w = 0 ==> BAD
>
> Hmm, when add a printf() to show the wi/he values
> from the code Ian posted, it always printed non-zero values,
> so I guess I'm not able to get that w=0.
I'm sure the OP (testalucida) got this (w=0) only with his own code,
i.e. w/o setting the font correctly.
> Still, I think you can/should rewrite this class
> so as to avoid using resize() inside draw().
Agreed 200% ;-)
> If I were writing this, I'd remove the draw() code completely,
> because it seems the goal of the app is to auto-size the widget
> based on the value() passed to it, not change how the widget draws
> itself.
Yep.
> I'd suggest overloading value() instead, to measure the string
> and resize the widget whenever the string's contents is changed.
>
> This avoids having resize() inside draw(), which many
> folks here agree should be avoided.
Very good idea. So you would only call fl_measure() when the label
really changes, which is much better than in each draw() call.
> Here's what I'd recommend, and again, not getting w==0 when I run it:
>
> // testalucida's measure with Ian's changes,
> // Erco added changes to remove draw() and repurpose value() instead.
IMHO perfect code removed here for shortness.
The only problem with this is if the window is resizable. Then the
widget's size changes when the user resizes the window, and then
it is no more the "correct" size. See below.
> int main() {
> Fl_Double_Window *pWin = new Fl_Double_Window(100, 100, 300, 300,
> "TestMyDisplay");
> TestMyDisplay *pDisp = new TestMyDisplay(0, 0, 300, 300);
Add the following two lines here (before show()) to see the effect:
pWin->resizable(pWin); // make Window resizable
pWin->size_range(200,200,800,600); // opt.: set size range
> pWin->show();
...
So, if you want to avoid this, you must also override resize() and
do something appropriate within resize().
What I did (see full code below):
- made window resizable
- changed value() to set the value and call resize()
- added resize() method to do the calculation (with 4 different
options, 3 of 'em commented out)
Enjoy ;-)
Albrecht
// testalucida's measure with Ian's changes,
// Erco added changes to remove draw() and repurpose value() instead.
// added window resizing (enable WINDOW_RESIZABLE)
// added resize(), moved size calculation to resize()
// added automatic text resizing (enable AUTO_RESIZE_TEXT)
// fltk-config --compile measure-test.cxx
#define WINDOW_RESIZABLE (1) // 1 = resizable, 0 = not resizable
#define AUTO_RESIZE_TEXT (1) // 1 = resize text, 0 = constant size
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Output.H>
#include <FL/fl_draw.H>
#include <string>
#include <vector>
class MyDisplay : public Fl_Output {
public:
MyDisplay(int x, int y, int w, int h, const char *lbl) :
Fl_Output(x,y,w,h,lbl) {
textsize(11);
}
// Set the value, auto-size the widget to the width of the string
void value(const char *val) {
Fl_Output::value(val);
resize(x(), y(), w(), h());
}
void resize(int X, int Y, int W, int H) {
int ts = textsize();
#if AUTO_RESIZE_TEXT
ts = (window()->w()*11 + 150) / 300;
if (ts < 7) ts = 7;
else if (ts > 20) ts = 20;
textsize(ts);
#endif
fl_font(textfont(), ts);
int wi=0, he=0;
fl_measure(Fl_Output::value(), wi, he, 0);
printf("WI/HE=%d %d, ts=%d\n", wi, he, ts); // DEBUGGING
fflush(stdout);
// resize the widget accordingly (choose one of the next 4 lines)
Fl_Output::resize(X, Y, wi+6, ts+6); // height dep. on textsize()
// Fl_Output::resize(X, Y, wi+6, he); // similar
// Fl_Output::resize(X, Y, wi+6, H); // height changes by resizing
// Fl_Output::resize(X, Y, wi+6, h()); // height stays constant
}
};
class TestMyDisplay : public Fl_Group {
public:
TestMyDisplay(int X, int Y, int W, int H):Fl_Group(X, Y, W, H) {
end();
}
void setData(std::vector<std::string> &labels,
std::vector<std::string> &values) {
begin();
for (int i=0, imax=labels.size(); i<imax; i++) {
fprintf(stderr, "label: %s\n", labels[i].c_str());
MyDisplay *pDy = new MyDisplay(150, y()+3+i*30, 150, 25,
labels[i].c_str());
pDy->value(values[i].c_str());
}
end();
}
};
int main() {
Fl_Double_Window *pWin = new Fl_Double_Window(100, 100, 300, 300,
"TestMyDisplay");
TestMyDisplay *pDisp = new TestMyDisplay(0, 0, 300, 300);
#if WINDOW_RESIZABLE
pWin->resizable(pWin); // make Window resizable
pWin->size_range(200,200,800,600); // opt.: set size range
#endif
pWin->show();
std::vector<std::string> labels, values;
labels.push_back("Label 1: ");
labels.push_back("Label 2: ");
labels.push_back("Label 3: ");
values.push_back("Val 1: ");
values.push_back("TestValue 2: ");
values.push_back("Value 3: ");
pDisp->setData(labels, values);
return Fl::run();
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk