Thread: Re: [Plib-users] legend update
Brought to you by:
sjbaker
|
From: Stephen J B. <sj...@li...> - 2002-01-29 14:34:38
|
> void sliderCB( puObject *sli) {
>
> float value;
> char sliText[4];
>
> slicb->getValue(&value);
> sprintf(sliText, "%.2f", value);
> cout << sliText << endl; // this output is *exactly* what I need
>
> slicb->setLegend(sliText); // non-sense chars on the legend :(
> ...
> }
>
> No matter what I do to try and reformat the string (with sprintf),
> prior to sending it on the legend, I get on my legend some strange
> characters. What am I possibly doing wrong?
> Can somebody see my mistake above?
Someone already (correctly) pointed out that sliText is a local variable
(which is certainly a problem) - but it's also not large enough.
The '%.2f' format will generate things like '0.01' - four characters
plus a '\0' byte - making five characters in all. Hence, sliText
needs to have *AT LEAST* five elements - not four as you declared it.
----
Steve Baker (817)619-2657 (Vox/Vox-Mail)
L3Com/Link Simulation & Training (817)619-2466 (Fax)
Work: sj...@li... http://www.link.com
Home: sjb...@ai... http://www.sjbaker.org
|
|
From: Stephen J B. <sj...@li...> - 2002-01-29 17:05:01
|
>> Someone already (correctly) pointed out that sliText is a local variable >> (which is certainly a problem) - but it's also not large enough. > >Correct Steve - thanks for pointing that out. > > However, there is yet another problem with your design. If you have more > than one slider connected to that callback, there will be only one string > buffer, but there has to be one for each slider. You surely don't want all > sliders to have the same legend. Yep - if there is more than one of these beasts, that's true. > A possible, but not the best, solution would be to abuse the slider's > string buffer to store the legend string. Yuk. > You could also derive your own > class from puSlider and add a char[] array member. That would work...or you could use the 'userdata' field to hold the array - that's *probably* what I would do. ---- Steve Baker (817)619-2657 (Vox/Vox-Mail) L3Com/Link Simulation & Training (817)619-2466 (Fax) Work: sj...@li... http://www.link.com Home: sjb...@ai... http://www.sjbaker.org |
|
From: Sebastian U. <ud...@ha...> - 2002-01-29 17:25:41
|
On Tue, 29 Jan 2002, sj...@li... (Stephen J Baker) wrote:
> Date: Tue, 29 Jan 2002 11:01:25 -0600 (CST)
> To: <pli...@li...>
> From: sj...@li... (Stephen J Baker)
> Reply-To: sj...@li...
> Subject: Re: [Plib-users] legend update
[...]
> > A possible, but not the best, solution would be to abuse the slider's
> > string buffer to store the legend string.
>
> Yuk.
Hehe ... I know it sounds ugly, but it does work since the callback is
invoked in puSlider::doHit () *after* the setValue () call, which does fill
the string value buffer with the floating-point number.
So, basically, you connect the widget's string value buffer to it's legend
pointer once and then override the content of the string buffer on every
slider movement from the callback.
Okay ... Yuk :).
> > You could also derive your own
> > class from puSlider and add a char[] array member.
>
> That would work...or you could use the 'userdata' field to hold the
> array - that's *probably* what I would do.
So you would place something like that in the callback:
/* [...] */
if ( sli -> getUserData () == NULL )
{
char *p = new char [10] ;
sli -> setUserData ( p ) ;
}
snprintf ( (char *) sli -> getUserData (), 10, "%.2f", sli -> getFloatValue () ) ;
/* [...] */
Mhm ... you had take care of the deallocation of the array then ...
- Sebastian
|
|
From: stathis <st...@nt...> - 2002-01-29 17:23:47
|
Hi again,
I read carefully what everyone proposed. For my purposes the sliderCB as I initialy said
is a "generic" callback used by many sliders, so the static idea is not solving it (globally
defined pointers to arrays of chars do, but need 1 for each slider). I think the best
solution would be to actually derive a class from puSlider as Sebastian said. To quickly
solve it I ended up hacking a little bit the pu.h.I know I shouldn't but I have to get a
solution quickly for now.
Here is what I've done, which I am sure is not the most compact and correct way of
doing it, but it works for now:
pu.h around line 415:
char string [ PUSTRING_MAX ] ;
char formatted [ PUSTRING_MAX ] ; // I added this to store my formatted string
pu.h around line 482:
char *getStringValue () { return res_string ? res_string : string ; }
// I added the one below
char *getStringValue (const char * format) {
sprintf(formatted, format, string);
return res_string ? res_string : formatted ;
}
This allows me to change my initial solution with the long digit output
from:
slicb->setLegend(slicb->getStringValue());
to:
slicb->setLegend(slicb->getStringValue("%.4s"));
Now all my sliders will return me a user defined formatted output. I don't think this will
break the other widgets, but feel free to correct me.
I'm sorry I don't mean to intrude the inner workings of this so nice library so I will move
my stuff where it belongs when time and skill allows. (Be kind I'm not a pro programmer).
Thank you very much for the input.
stathis
|
|
From: Sebastian U. <ud...@ha...> - 2002-01-29 19:45:19
|
On Tue, 29 Jan 2002, st...@nt... (stathis) wrote:
> Date: Tue, 29 Jan 2002 17:33:41 -0000
> To: pli...@li...
> From: st...@nt... (stathis)
> Subject: RE: [Plib-users] legend update
>
> Hi again,
>
> I read carefully what everyone proposed. For my purposes the sliderCB as
> I initialy said is a "generic" callback used by many sliders, so the static
> idea is not solving it [...] I think the best solution would be to
> actually derive a class from puSlider as Sebastian said. To quickly solve
> it I ended up hacking a little bit the pu.h.I know I shouldn't but I have
> to get a solution quickly for now.
[...]
How about:
class legendSlider : public puSlider
{
protected:
char legendbuf [ 10 ] ;
public:
void doHit ( int button, int updown, int x, int y )
{
puSlider::doHit ( button, updown, x, y ) ;
snprintf ( legendbuf, 10, "%.2f", getFloatValue () ) ;
}
legendSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puSlider ( minx, miny, sz, vertical )
{
setLegend ( legendbuf ) ;
}
} ;
- Sebastian
|
|
From: Norman V. <nh...@ca...> - 2002-01-29 15:01:20
|
Stephen J Baker writes:
>
>> void sliderCB( puObject *sli) {
>>
>> float value;
>> char sliText[4];
>>
>> slicb->getValue(&value);
>> sprintf(sliText, "%.2f", value);
>> cout << sliText << endl; // this output is *exactly* what I need
>>
>> slicb->setLegend(sliText); // non-sense chars on the legend :(
>> ...
>> }
>>
>> No matter what I do to try and reformat the string (with sprintf),
>> prior to sending it on the legend, I get on my legend some strange
>> characters. What am I possibly doing wrong?
>> Can somebody see my mistake above?
>
>Someone already (correctly) pointed out that sliText is a
>local variable
>(which is certainly a problem) - but it's also not large enough.
>
>The '%.2f' format will generate things like '0.01' - four characters
>plus a '\0' byte - making five characters in all. Hence, sliText
>needs to have *AT LEAST* five elements - not four as you declared it.
Good Catch !
FWIW
I implemented a variation of this theme for the FlightGear
AutoPilot Gain adjuster.
http://www.vso.cape.com/~nhv/files/PLib/APDialog.jpg
The code while not the prettiest, works and should be adapatable
if anyone is interested see FlightGear / src / AutoPilot / auto_gui.cxx
which is accessible through the CVS web Interface
< follow link to CVS Resources @ www.flightgear.org >
Cheers
Norman
|
|
From: Sebastian U. <ud...@ha...> - 2002-01-29 15:36:13
|
On Tue, 29 Jan 2002, sj...@li... (Stephen J Baker) wrote: > Date: Tue, 29 Jan 2002 08:31:04 -0600 (CST) > To: <pli...@li...> > From: sj...@li... (Stephen J Baker) > Reply-To: sj...@li... > Subject: Re: [Plib-users] legend update [...] > Someone already (correctly) pointed out that sliText is a local variable > (which is certainly a problem) - but it's also not large enough. Correct Steve - thanks for pointing that out. However, there is yet another problem with your design. If you have more than one slider connected to that callback, there will be only one string buffer, but there has to be one for each slider. You surely don't want all sliders to have the same legend. A possible, but not the best, solution would be to abuse the slider's string buffer to store the legend string. You could also derive your own class from puSlider and add a char[] array member. - Sebastian |
|
From: dave <da...@mi...> - 2002-01-29 16:33:50
|
Good tips all, but none of them are the one that instantly popped into
my mind, which is:
If you are going to use the C strings rather than a string class, always
zero the destination space before printing,cat-ing,or copying into it.
For one thing, this forces you to consider the length of the space
before clearing.
<SOAPBOX>
I have found hundreds of bugs in my employers codes over the years
related to sloppy C programming practices, especially strings (and yes,
I too get sloppy). One employer even built a special set of wrappers for
the string functions that eliminated having to think about the n+1 byte
for the terminating zero. It sure looked ugly! :)
Having gotten tired of all this I abandoned C string functions entirely and
learned the iostreams part of C++ and started looking for a String class
in whatever projects I am assigned. If one isnt there I have my own I
wrote. This has saved me so much pain it was well worth it the effort.
But there is a footprint price to be paid if you are in an embedded
environment and using C++. This month's ELJ (Embedded Linux Journal) has
an article on a GUI project for a handheld where they use X-windows but
chose GTK+ instead of FLTK or QT. The complaint was that C++ brings too
many problems and its best to just try to be extremely disciplined in C.
So my usual snappy answer of "just dont use C", ahem, cough cough,
doesnt seem to work anymore, at least for highly tuned environments.
</SOAPBOX>
Regards,
Dave
Oh, BTW, Steve, the translucent widgets are sweet!
Stephen J Baker wrote:
>>void sliderCB( puObject *sli) {
>>
>> float value;
>> char sliText[4];
>>
>> slicb->getValue(&value);
>> sprintf(sliText, "%.2f", value);
>> cout << sliText << endl; // this output is *exactly* what I need
>>
>> slicb->setLegend(sliText); // non-sense chars on the legend :(
>> ...
>>}
>>
>>No matter what I do to try and reformat the string (with sprintf),
>>prior to sending it on the legend, I get on my legend some strange
>>characters. What am I possibly doing wrong?
>>Can somebody see my mistake above?
>>
>
> Someone already (correctly) pointed out that sliText is a local variable
> (which is certainly a problem) - but it's also not large enough.
>
> The '%.2f' format will generate things like '0.01' - four characters
> plus a '\0' byte - making five characters in all. Hence, sliText
> needs to have *AT LEAST* five elements - not four as you declared it.
>
> ----
> Steve Baker (817)619-2657 (Vox/Vox-Mail)
> L3Com/Link Simulation & Training (817)619-2466 (Fax)
> Work: sj...@li... http://www.link.com
> Home: sjb...@ai... http://www.sjbaker.org
>
>
> _______________________________________________
> plib-users mailing list
> pli...@li...
> https://lists.sourceforge.net/lists/listinfo/plib-users
>
>
>
>
|