1 /*
2  *  This file is part of XForms.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with XForms; see the file COPYING.  If not, write to
16  *  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17  *  MA 02111-1307, USA.
18  *
19  * Author: Jens Thoms Toerring <jt@toerring.de>
20  */
21 
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <stdlib.h>
28 #include "include/forms.h"
29 
30 
31 typedef struct {
32     FL_FORM *   grav;
33     FL_OBJECT * box;
34     FL_OBJECT * rx;
35     FL_OBJECT * ry;
36 } FD_gravity_form;
37 
38 typedef struct {
39     FL_OBJECT *  box;
40     FL_OBJECT *  rx;
41     FL_OBJECT *  ry;
42     unsigned int grav;
43 } FD_grav_data;
44 
45 typedef struct {
46     FL_FORM * help;
47     int       is_shown;
48 } FD_help_form;
49 
50 
51 static FD_grav_data gd[ 9 ];
52 static unsigned int g[ ] = { FL_NorthWest, FL_North,     FL_NorthEast,
53                              FL_West,      FL_NoGravity, FL_East,
54                              FL_SouthWest, FL_South,     FL_SouthEast };
55 static int w = 500,
56            h = 400;
57 static int bw = 200,
58            bh = 200;
59 
60 
61 #define ULC_POS_LEFT_FIXED( obj )                \
62     (    ( obj )->nwgravity == FL_NorthWest      \
63       || ( obj )->nwgravity == FL_West           \
64       || ( obj )->nwgravity == FL_SouthWest )
65 
66 #define ULC_POS_RIGHT_FIXED( obj )               \
67     (    ( obj )->nwgravity == FL_NorthEast      \
68       || ( obj )->nwgravity == FL_East           \
69       || ( obj )->nwgravity == FL_SouthEast )
70 
71 #define LRC_POS_LEFT_FIXED( obj )                \
72     (    ( obj )->segravity == FL_NorthWest      \
73       || ( obj )->segravity == FL_West           \
74       || ( obj )->segravity == FL_SouthWest )
75 
76 #define LRC_POS_RIGHT_FIXED( obj )               \
77     (    ( obj )->segravity == FL_NorthEast      \
78       || ( obj )->segravity == FL_East           \
79       || ( obj )->segravity == FL_SouthEast )
80 
81 #define HAS_FIXED_HORI_ULC_POS( obj )                             \
82     ( ULC_POS_LEFT_FIXED( obj ) || ULC_POS_RIGHT_FIXED( obj ) )
83 
84 #define HAS_FIXED_HORI_LRC_POS( obj )                             \
85     ( LRC_POS_LEFT_FIXED( obj ) || LRC_POS_RIGHT_FIXED( obj ) )
86 
87 #define HAS_FIXED_WIDTH( obj )                                          \
88     ( HAS_FIXED_HORI_ULC_POS( obj ) && HAS_FIXED_HORI_LRC_POS( obj ) )
89 
90 
91 #define ULC_POS_TOP_FIXED( obj )                 \
92     (    ( obj )->nwgravity == FL_NorthWest      \
93       || ( obj )->nwgravity == FL_North          \
94       || ( obj )->nwgravity == FL_NorthEast )
95 
96 #define ULC_POS_BOTTOM_FIXED( obj )              \
97     (    ( obj )->nwgravity == FL_SouthWest      \
98       || ( obj )->nwgravity == FL_South          \
99       || ( obj )->nwgravity == FL_SouthEast )
100 
101 #define LRC_POS_TOP_FIXED( obj )                 \
102     (    ( obj )->segravity == FL_NorthWest      \
103       || ( obj )->segravity == FL_North          \
104       || ( obj )->segravity == FL_NorthEast )
105 
106 #define LRC_POS_BOTTOM_FIXED( obj )              \
107     (    ( obj )->segravity == FL_SouthWest      \
108       || ( obj )->segravity == FL_South          \
109       || ( obj )->segravity == FL_SouthEast )
110 
111 
112 #define HAS_FIXED_VERT_ULC_POS( obj )                             \
113     ( ULC_POS_TOP_FIXED( obj ) || ULC_POS_BOTTOM_FIXED( obj ) )
114 
115 #define HAS_FIXED_VERT_LRC_POS( obj )                             \
116     ( LRC_POS_TOP_FIXED( obj ) || LRC_POS_BOTTOM_FIXED( obj ) )
117 
118 #define HAS_FIXED_HEIGHT( obj )                                         \
119     ( HAS_FIXED_VERT_ULC_POS( obj ) && HAS_FIXED_VERT_LRC_POS( obj ) )
120 
121 
122 
123 
124 /***************************************
125  ***************************************/
126 
127 static void
check_resize(FD_grav_data * g)128 check_resize( FD_grav_data * g )
129 {
130     fl_set_button( g->rx, g->box->resize & FL_RESIZE_X );
131     fl_set_button( g->ry, g->box->resize & FL_RESIZE_Y );
132 
133     if ( HAS_FIXED_WIDTH( g->box ) )
134         fl_set_object_lcolor( g->rx, FL_INACTIVE_COL );
135     else
136         fl_set_object_lcolor( g->rx, FL_BLACK );
137 
138     if ( HAS_FIXED_HEIGHT( g->box ) )
139         fl_set_object_lcolor( g->ry, FL_INACTIVE_COL );
140     else
141         fl_set_object_lcolor( g->ry, FL_BLACK );
142 }
143 
144 
145 /***************************************
146  ***************************************/
147 
148 static void
nw_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)149 nw_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
150              long              data )
151 {
152     FD_grav_data * g = ( FD_grav_data * ) data;
153 
154     fl_set_object_gravity( g->box, g->grav, g->box->segravity );
155     check_resize( g );
156 }
157 
158 
159 /***************************************
160  ***************************************/
161 
162 static void
se_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)163 se_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
164              long              data )
165 {
166     FD_grav_data * g = ( FD_grav_data * ) data;
167 
168     fl_set_object_gravity( g->box, g->box->nwgravity, g->grav );
169     check_resize( g );
170 }
171 
172 
173 /***************************************
174  ***************************************/
175 
176 static void
rx_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)177 rx_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
178              long              data )
179 {
180     FD_grav_data * g = ( FD_grav_data * ) data;
181     unsigned int r = g->box->resize;
182 
183     if ( r & FL_RESIZE_X )
184         r &= ~ FL_RESIZE_X;
185     else
186         r |= FL_RESIZE_X;
187 
188     fl_set_object_resize( g->box, r );
189 }
190 
191 
192 /***************************************
193  ***************************************/
194 
195 static void
ry_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)196 ry_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
197              long              data )
198 {
199     FD_grav_data * g = ( FD_grav_data * ) data;
200     unsigned int r = g->box->resize;
201 
202     if ( r & FL_RESIZE_Y )
203         r &= ~ FL_RESIZE_Y;
204     else
205         r |= FL_RESIZE_Y;
206 
207     fl_set_object_resize( g->box, r );
208 }
209 
210 
211 /***************************************
212  ***************************************/
213 
214 static void
reset_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)215 reset_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
216                 long        data )
217 {
218     FD_grav_data * g = ( FD_grav_data * ) data;
219 
220     fl_set_form_size( g->box->form, w, h );
221     fl_set_object_geometry( g->box, ( w - bw ) / 2, ( h - bh ) / 2, bw, bh );
222 }
223 
224 
225 /***************************************
226  ***************************************/
227 
228 static void
help_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)229 help_callback( FL_OBJECT * obj  FL_UNUSED_ARG,
230                 long       data )
231 {
232     FD_help_form * h = ( FD_help_form * ) data;
233 
234     if ( ! h->is_shown )
235     {
236         fl_show_form( h->help, FL_PLACE_CENTER | FL_FREE_SIZE,
237                       FL_FULLBORDER, "Gravity Demo Help" );
238         h->is_shown = 1;
239     }
240 }
241 
242 
243 /***************************************
244  ***************************************/
245 
246 static void
close_callback(FL_OBJECT * obj FL_UNUSED_ARG,long data)247 close_callback( FL_OBJECT * obj   FL_UNUSED_ARG,
248                 long        data )
249 {
250     FD_help_form * h = ( FD_help_form * ) data;
251 
252     fl_hide_form( h->help );
253     h->is_shown = 0;
254 }
255 
256 
257 /***************************************
258  ***************************************/
259 
260 static FD_gravity_form *
create_form_gravity(FD_help_form * help)261 create_form_gravity( FD_help_form * help )
262 {
263     FL_OBJECT * obj;
264     FD_gravity_form * fdui = fl_malloc( sizeof *fdui );
265     const char * label[ ] = { "NW", "N", "NE", "W", "-", "E", "SW", "S", "SE" };
266     int i;
267     int s = 25;
268     int m = 5;
269 
270     fdui->grav = fl_bgn_form( FL_FLAT_BOX, 500, 400 );
271 
272     fl_set_form_background_color( fdui->grav, FL_DARKER_COL1 );
273 
274     fdui->box = obj = fl_add_box( FL_FRAME_BOX, ( w - bw ) / 2, ( h - bh ) / 2,
275                                   bw, bh, "" );
276     fl_set_object_color( obj, FL_GREEN, FL_GREEN );
277 
278     fl_bgn_group( );
279 
280     for ( i = 0; i < 9; i++ )
281     {
282         obj = fl_add_button( FL_RADIO_BUTTON,
283                              s * ( i % 3 ) + m, s * ( i / 3 ) + m, s, s,
284                              label[ i ] );
285         fl_set_object_bw( obj, -1 );
286         fl_set_object_resize( obj, FL_RESIZE_NONE );
287         fl_set_object_gravity( obj, FL_NorthWest, FL_NorthWest );
288         fl_set_object_callback( obj, nw_callback, ( long ) ( gd + i ) );
289         fl_set_object_color( obj, FL_COL1, FL_MCOL );
290         fl_set_button( obj, fdui->box->nwgravity == g[ i ] );
291         fl_set_button_mouse_buttons( obj, 1 );
292     }
293     fl_end_group( );
294 
295     fl_bgn_group( );
296     for ( i = 0; i < 9; i++ )
297     {
298         obj = fl_add_button( FL_RADIO_BUTTON,
299                              s * ( i % 3 ) + w - 3 * s - m,
300                              s * ( i / 3 ) + h - 3 * s - m, s, s,
301                              label[ i ] );
302         fl_set_object_bw( obj, -1 );
303         fl_set_object_resize( obj, FL_RESIZE_NONE );
304         fl_set_object_gravity( obj, FL_SouthEast, FL_SouthEast );
305         fl_set_object_callback( obj, se_callback, ( long ) ( gd + i ) );
306         fl_set_object_color( obj, FL_COL1, FL_MCOL );
307         fl_set_button( obj, fdui->box->segravity == g[ i ] );
308         fl_set_button_mouse_buttons( obj, 1 );
309     }
310 
311     fl_end_group( );
312 
313     fdui->rx = obj = fl_add_button( FL_PUSH_BUTTON, m, h - s - m, 80, s,
314                                     "X Resize" );
315     fl_set_object_bw( obj, -1 );
316     fl_set_object_resize( obj, FL_RESIZE_NONE );
317     fl_set_object_gravity( obj, FL_SouthWest, FL_SouthWest );
318     fl_set_object_callback( obj, rx_callback, ( long ) gd );
319     fl_set_object_color( obj, FL_COL1, FL_MCOL );
320     fl_set_button( obj, fdui->box->resize & FL_RESIZE_X );
321     fl_set_button_mouse_buttons( obj, 1 );
322 
323     fdui->ry = obj = fl_add_button( FL_PUSH_BUTTON, 2 * m + 80, h - s - m,
324                                     80, s, "Y Resize" );
325     fl_set_object_bw( obj, -1 );
326     fl_set_object_resize( obj, FL_RESIZE_NONE );
327     fl_set_object_gravity( obj, FL_SouthWest, FL_SouthWest );
328     fl_set_object_callback( obj, ry_callback, ( long ) gd );
329     fl_set_object_color( obj, FL_COL1, FL_MCOL );
330     fl_set_button( obj, fdui->box->resize & FL_RESIZE_Y );
331     fl_set_button_mouse_buttons( obj, 1 );
332 
333     obj = fl_add_button( FL_NORMAL_BUTTON, w - 85, 5, 80, s, "Help" );
334     fl_set_object_bw( obj, -1 );
335     fl_set_object_gravity( obj, FL_NorthEast, FL_NorthEast );
336     fl_set_object_callback( obj, help_callback, ( long ) help );
337     fl_set_button_mouse_buttons( obj, 1 );
338 
339     obj = fl_add_button( FL_NORMAL_BUTTON, 200, h - s - m,
340                          80, s, "Reset" );
341     fl_set_object_bw( obj, -1 );
342     fl_set_object_resize( obj, FL_RESIZE_NONE );
343     fl_set_object_gravity( obj, FL_South, FL_South );
344     fl_set_object_callback( obj, reset_callback, ( long ) gd );
345     fl_set_button_mouse_buttons( obj, 1 );
346 
347     obj = fl_add_button( FL_NORMAL_BUTTON, m + 280, h - s - m, 80, s, "Quit" );
348     fl_set_object_bw( obj, -1 );
349     fl_set_object_resize( obj, FL_RESIZE_NONE );
350     fl_set_object_gravity( obj, FL_South, FL_South );
351     fl_set_button_mouse_buttons( obj, 1 );
352 
353     fl_end_form();
354 
355     return fdui;
356 }
357 
358 
359 /***************************************
360  ***************************************/
361 
362 static FD_help_form *
create_form_help(void)363 create_form_help( void )
364 {
365     FL_OBJECT * obj;
366     FD_help_form * fdui = fl_malloc( sizeof *fdui );
367     const char * text = "Gravity and resize settings demonstration\n"
368                         "\n"
369                         "The interaction between gravity and resize settings\n"
370                         "can sometimes be difficult to understand  This pro-\n"
371                         "gram allows you to test some of the effects.\n"
372                         "\n"
373                         "With the sets of buttons in the upper left hand and\n"
374                         "lower right hand corner you can set the gravity for\n"
375                         "the corresponding corners of the green rectangle.\n"
376                         "\n"
377                         "With the buttons labeled 'X Resize' and 'Y Resize'\n"
378                         "you can set if the rectangle may be scaled in x-\n"
379                         "and/or y-direction. Please note that for several\n"
380                         "combinations of gravity settings the resizing\n"
381                         "settings are not taken into account by XForms. In\n"
382                         "these cases the corresponding buttons are grayed\n"
383                         "out (but not deactivated).";
384 
385     fdui->help = fl_bgn_form( FL_FLAT_BOX, 345, 325 );
386 
387     fdui->is_shown = 0;
388 
389     obj = fl_add_browser( FL_NORMAL_BROWSER, 5, 5, 335, 285, "" );
390     fl_set_object_bw( obj, -1 );
391     fl_set_object_color( obj, FL_WHITE, FL_WHITE );
392     fl_set_object_gravity( obj, FL_NorthWest, FL_SouthEast );
393     fl_add_browser_line( obj, text );
394 
395     obj = fl_add_button( FL_NORMAL_BUTTON, 133, 295, 80, 25, "Close" );
396     fl_set_object_bw( obj, -1 );
397     fl_set_object_gravity( obj, FL_South, FL_South );
398     fl_set_object_resize( obj, FL_RESIZE_NONE );
399     fl_set_object_callback( obj, close_callback, ( long ) fdui );
400     fl_set_button_mouse_buttons( obj, 1 );
401 
402     fl_end_form();
403 
404     return fdui;
405 }
406 
407 
408 /***************************************
409  ***************************************/
410 
411 int
main(int argc,char * argv[])412 main( int    argc,
413       char * argv[ ] )
414 {
415     FD_gravity_form * grav;
416     FD_help_form * help;
417     int i;
418 
419     fl_initialize( &argc, argv, "Gravity Demo", 0, 0 );
420     help = create_form_help( );
421     grav = create_form_gravity( help );
422     fl_set_app_mainform( grav->grav );
423 
424     for ( i = 0; i < 9; i++ )
425     {
426         gd[ i ].box = grav->box;
427         gd[ i ].grav = g[ i ];
428         gd[ i ].rx = grav->rx;
429         gd[ i ].ry = grav->ry;
430     }
431 
432     fl_show_form( grav->grav, FL_PLACE_CENTER | FL_FREE_SIZE,
433                   FL_FULLBORDER, "Gravity Demo" );
434 
435     fl_do_forms( );
436 
437     fl_finish( );
438 
439     return 0;
440 }
441 
442 
443 /*
444  * Local variables:
445  * tab-width: 4
446  * indent-tabs-mode: nil
447  * End:
448  */
449