Update NTK.
[nondaw.git] / FL / Fl_Scalepack.C
blobcd6bcc475d11825f2715c46fc1fbe290280cddf6
2 /*******************************************************************************/
3 /* Copyright (C) 2008 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
21 /* Fl_Scalepack
23    This is similar to an Fl_Pack, but instead of the pack resizing
24    itself to enclose its children, this pack resizes its children to
25    fit itself. Of course, this only works well with highly flexible
26    widgets, but the task comes up often enough to warrent this class.
28    If and child happens to be the resizable() widget, then it will be
29    resized so the all the other children can fit around it, with their
30    current sizes (and the size of the Fl_Scalepack) maintained.
32    NOTES: An Fl_Pack as a direct child will not work, because Fl_Pack
33    changes its size in draw(), which throws off our resize
34    calculation. The whole idea of widgets being able to resize
35    themselves within draw() is horribly broken...
38 #include "Fl_Scalepack.H"
40 #include <FL/Fl.H>
41 #include <FL/fl_draw.H>
42 #include <stdio.h>
44 Fl_Scalepack::Fl_Scalepack ( int X, int Y, int W, int H, const char *L ) :
45     Fl_Group( X, Y, W, H, L )
47     resizable( 0 );
48     _spacing = 0;
51 void
52 Fl_Scalepack::resize ( int X, int Y, int W, int H )
54     /* Fl_Group's resize will change our child widget sizes, which
55      interferes with our own resizing method. */
56     Fl_Widget::resize( X, Y, W, H );
59 void
60 Fl_Scalepack::draw ( void )
63     if ( resizable() == this )
64         /* this resizable( this ) is the default for Fl_Group and is
65          * reset by Fl_Group::clear(), but it is not our default... */
66         resizable( 0 );
68     int tx = x() + Fl::box_dx( box() );
69     int ty = y() + Fl::box_dy( box() );
70     int tw = w() - Fl::box_dw( box() );
71     int th = h() - Fl::box_dh( box() );
73     if ( damage() & FL_DAMAGE_ALL )
74     {
75         if ( box() == FL_NO_BOX )
76             fl_rectf( x(), y(), w(), h(), FL_BACKGROUND_COLOR );
77         else
78             draw_box();
80         draw_label();
81     }
83     int v = 0;
85     int cth = 0;
86     int ctw = 0;
88     Fl_Widget * const * a = array();
90     for ( int i = children(); i--; )
91     {
92         Fl_Widget *o = *a++;
94         if ( o->visible() )
95         {
96             ++v;
98             if ( o != this->resizable() )
99             {
100                 cth += o->h();
101                 ctw += o->w();
102             }
104             cth += _spacing;
105             ctw += _spacing;
106         }
107     }
109     ctw -= _spacing;
110     cth -= _spacing;
112     if ( 0 == v )
113         return;
115     if ( this->resizable() )
116     {
117         int pos = 0;
119         Fl_Widget * const * a = array();
121         for ( int i = children(); i--; )
122         {
123             Fl_Widget *o = *a++;
125             if ( o->visible() )
126             {
127                 int X, Y, W, H;
129                 if ( type() == HORIZONTAL )
130                 {
131                     X = tx + pos;
132                     Y = ty;
133                     W = o->w();
134                     H = th;
135                 }
136                 else
137                 {
138                     X = tx;
139                     Y = ty + pos;
140                     W = tw;
141                     H = o->h();
142                 }
144                 if ( this->resizable() == o )
145                 {
146                     if ( type() == HORIZONTAL )
147                         W = tw - ctw - 3;
148                     else
149                         H = th - cth;
150                 }
152                 if (X != o->x() || Y != o->y() || W != o->w() || H != o->h() )
153                 {
154                     o->resize(X,Y,W,H);
155                     o->clear_damage(FL_DAMAGE_ALL);
156                 }
158                 if ( damage() & FL_DAMAGE_ALL )
159                 {
160                     draw_child( *o );
161                     draw_outside_label( *o );
162                 }
163                 else
164                     update_child( *o );
166 /*                 if ( this->resizable() == o ) */
167 /*                     fl_rect( o->x(), o->y(), o->w(), o->h(), type() == VERTICAL ? FL_GREEN : FL_BLUE ); */
169                 if ( type() == HORIZONTAL )
170                     pos += o->w() + spacing();
171                 else
172                     pos += o->h() + spacing();
174             }
175         }
176     }
177     else
178     {
179         int sz = 0;
180         int pos = 0;
182         if ( type() == HORIZONTAL )
183             sz = (tw - (_spacing * (v - 1))) / v;
184         else
185             sz = (th - (_spacing * (v - 1))) / v;
187         Fl_Widget * const * a = array();
189         for ( int i = children(); i--; )
190         {
191             Fl_Widget *o = *a++;
193             if ( o->visible() )
194             {
195                 int X, Y, W, H;
197                 if ( type() == HORIZONTAL )
198                 {
199                     X = tx + pos;
200                     Y = ty;
201                     W = sz;
202                     H = th;
203                 }
204                 else
205                 {
206                     X = tx;
207                     Y = ty + pos;
208                     W = tw;
209                     H = sz;
210                 }
212                 if (X != o->x() || Y != o->y() || W != o->w() || H != o->h() )
213                 {
214                     o->resize(X,Y,W,H);
215                     o->clear_damage(FL_DAMAGE_ALL);
216                 }
218                 if ( damage() & FL_DAMAGE_ALL )
219                 {
220                     draw_child( *o );
221                     draw_outside_label( *o );
222                 }
223                 else
224                     update_child( *o );
226 //                    fl_rect( o->x(), o->y(), o->w(), o->h(), type() == VERTICAL ? FL_RED : FL_YELLOW );
228                 if ( type() == HORIZONTAL )
229                     pos += o->w() + spacing();
230                 else
231                     pos += o->h() + spacing();
233             }
234         }
235     }