FL/Fl_Scalepack: Give scalepack the ability contain a resizable() child.
This commit is contained in:
parent
82583365f6
commit
ee705fffa3
|
@ -25,16 +25,20 @@
|
|||
fit itself. Of course, this only works well with highly flexible
|
||||
widgets, but the task comes up often enough to warrent this class.
|
||||
|
||||
If any child happens to be the resizable() widget, it is given half
|
||||
of the available area, with the other widgets packed around it in
|
||||
the remaining space.
|
||||
If and child happens to be the resizable() widget, then it will be
|
||||
resized so the all the other children can fit around it, with their
|
||||
current sizes (and the size of the Fl_Scalepack) maintained.
|
||||
|
||||
NOTES: An Fl_Pack as a direct child will not work, because Fl_Pack
|
||||
changes its size in draw(), which throws off our resize
|
||||
calculation. The whole idea of widgets being able to resize
|
||||
themselves within draw() is horribly broken...
|
||||
*/
|
||||
|
||||
#include "Fl_Scalepack.H"
|
||||
|
||||
#include <FL/Fl.H>
|
||||
|
||||
#include <FL/fl_draw.H>
|
||||
#include <stdio.h>
|
||||
|
||||
Fl_Scalepack::Fl_Scalepack ( int X, int Y, int W, int H, const char *L ) :
|
||||
|
@ -44,9 +48,23 @@ Fl_Scalepack::Fl_Scalepack ( int X, int Y, int W, int H, const char *L ) :
|
|||
_spacing = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Fl_Scalepack::resize ( int X, int Y, int W, int H )
|
||||
{
|
||||
/* Fl_Group's resize will change our child widget sizes, which
|
||||
interferes with our own resizing method. */
|
||||
Fl_Widget::resize( X, Y, W, H );
|
||||
}
|
||||
|
||||
void
|
||||
Fl_Scalepack::draw ( void )
|
||||
{
|
||||
|
||||
if ( resizable() == this )
|
||||
/* this resizable( this ) is the default for Fl_Group and is
|
||||
* reset by Fl_Group::clear(), but it is not our default... */
|
||||
resizable( 0 );
|
||||
|
||||
int tx = x() + Fl::box_dx( box() );
|
||||
int ty = y() + Fl::box_dy( box() );
|
||||
int tw = w() - Fl::box_dw( box() );
|
||||
|
@ -54,45 +72,165 @@ Fl_Scalepack::draw ( void )
|
|||
|
||||
if ( damage() & FL_DAMAGE_ALL )
|
||||
{
|
||||
if ( box() == FL_NO_BOX )
|
||||
fl_rectf( x(), y(), w(), h(), FL_BACKGROUND_COLOR );
|
||||
else
|
||||
draw_box();
|
||||
|
||||
draw_label();
|
||||
}
|
||||
|
||||
int v = 0;
|
||||
|
||||
int cth = 0;
|
||||
int ctw = 0;
|
||||
|
||||
Fl_Widget * const * a = array();
|
||||
|
||||
for ( int i = children(); i--; )
|
||||
if ( child( i )->visible() )
|
||||
{
|
||||
Fl_Widget *o = *a++;
|
||||
|
||||
if ( o->visible() )
|
||||
{
|
||||
++v;
|
||||
|
||||
if ( o != this->resizable() )
|
||||
{
|
||||
cth += o->h();
|
||||
ctw += o->w();
|
||||
}
|
||||
|
||||
cth += _spacing;
|
||||
ctw += _spacing;
|
||||
}
|
||||
}
|
||||
|
||||
ctw -= _spacing;
|
||||
cth -= _spacing;
|
||||
|
||||
if ( 0 == v )
|
||||
return;
|
||||
|
||||
int sz, pos;
|
||||
if ( this->resizable() )
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
{
|
||||
sz = tw / v;
|
||||
pos = tw - ( tw % sz );
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = th / v;
|
||||
pos = th - ( th % sz );
|
||||
}
|
||||
Fl_Widget * const * a = array();
|
||||
|
||||
for ( int i = children(); i--; )
|
||||
if ( child( i )->visible() )
|
||||
{
|
||||
pos -= sz;
|
||||
Fl_Widget *o = *a++;
|
||||
|
||||
if ( o->visible() )
|
||||
{
|
||||
int X, Y, W, H;
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
child( i )->resize( tx + pos, ty, sz, th );
|
||||
{
|
||||
X = tx + pos;
|
||||
Y = ty;
|
||||
W = o->w();
|
||||
H = th;
|
||||
}
|
||||
else
|
||||
child( i )->resize( tx, ty + pos, tw, sz );
|
||||
{
|
||||
X = tx;
|
||||
Y = ty + pos;
|
||||
W = tw;
|
||||
H = o->h();
|
||||
}
|
||||
|
||||
if ( damage() & FL_DAMAGE_CHILD )
|
||||
update_child( *child( i ) );
|
||||
if ( this->resizable() == o )
|
||||
{
|
||||
if ( type() == HORIZONTAL )
|
||||
W = tw - ctw - 3;
|
||||
else
|
||||
draw_child( *child( i ) );
|
||||
H = th - cth;
|
||||
}
|
||||
|
||||
if (X != o->x() || Y != o->y() || W != o->w() || H != o->h() )
|
||||
{
|
||||
o->resize(X,Y,W,H);
|
||||
o->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
|
||||
if ( damage() & FL_DAMAGE_ALL )
|
||||
{
|
||||
draw_child( *o );
|
||||
draw_outside_label( *o );
|
||||
}
|
||||
else
|
||||
update_child( *o );
|
||||
|
||||
/* if ( this->resizable() == o ) */
|
||||
/* fl_rect( o->x(), o->y(), o->w(), o->h(), type() == VERTICAL ? FL_GREEN : FL_BLUE ); */
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
pos += o->w() + spacing();
|
||||
else
|
||||
pos += o->h() + spacing();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sz = 0;
|
||||
int pos = 0;
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
sz = (tw - (_spacing * (v - 1))) / v;
|
||||
else
|
||||
sz = (th - (_spacing * (v - 1))) / v;
|
||||
|
||||
Fl_Widget * const * a = array();
|
||||
|
||||
for ( int i = children(); i--; )
|
||||
{
|
||||
Fl_Widget *o = *a++;
|
||||
|
||||
if ( o->visible() )
|
||||
{
|
||||
int X, Y, W, H;
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
{
|
||||
X = tx + pos;
|
||||
Y = ty;
|
||||
W = sz;
|
||||
H = th;
|
||||
}
|
||||
else
|
||||
{
|
||||
X = tx;
|
||||
Y = ty + pos;
|
||||
W = tw;
|
||||
H = sz;
|
||||
}
|
||||
|
||||
if (X != o->x() || Y != o->y() || W != o->w() || H != o->h() )
|
||||
{
|
||||
o->resize(X,Y,W,H);
|
||||
o->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
|
||||
if ( damage() & FL_DAMAGE_ALL )
|
||||
{
|
||||
draw_child( *o );
|
||||
draw_outside_label( *o );
|
||||
}
|
||||
else
|
||||
update_child( *o );
|
||||
|
||||
// fl_rect( o->x(), o->y(), o->w(), o->h(), type() == VERTICAL ? FL_RED : FL_YELLOW );
|
||||
|
||||
if ( type() == HORIZONTAL )
|
||||
pos += o->w() + spacing();
|
||||
else
|
||||
pos += o->h() + spacing();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
int spacing ( void ) const { return _spacing; }
|
||||
void spacing ( int v ) { _spacing = v; redraw(); }
|
||||
|
||||
virtual void resize ( int, int, int, int );
|
||||
|
||||
virtual void draw ( void );
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue