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 
20 
21 /*
22  * Demo showing the use of FREE Object with color leakage
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "include/forms.h"
31 #include <stdlib.h>
32 
33 
34 typedef struct {
35     FL_FORM   * drawfree;
36     void      * vdata;
37     char      * cdata;
38     long        ldata;
39     FL_OBJECT * freeobj;
40     FL_OBJECT * colorobj;
41     FL_OBJECT * hsli;
42     FL_OBJECT * wsli;
43     FL_OBJECT * rsli;
44     FL_OBJECT * gsli;
45     FL_OBJECT * bsli;
46     FL_OBJECT * drobj[ 3 ];
47 } FD_drawfree;
48 
49 extern FD_drawfree *create_form_drawfree( void );
50 static FD_drawfree *drawui;
51 extern void draw_initialize( FD_drawfree * );
52 
53 static int max_w = 150,
54            max_h = 150;
55 static Display *dpy;
56 
57 
58 /***************************************
59  ***************************************/
60 
61 int
main(int argc,char * argv[])62 main( int    argc,
63       char * argv[ ] )
64 {
65     dpy = fl_initialize( &argc, argv, "FormDemo", 0, 0 );
66     drawui = create_form_drawfree( );
67     fl_set_color_leak( 1 );
68     draw_initialize( drawui );
69     fl_show_form( drawui->drawfree, FL_PLACE_CENTER, FL_TRANSIENT,
70                   "FreeObject" );
71     fl_do_forms( );
72 
73 	fl_free( drawui );
74 	fl_finish( );
75     return 0;
76 }
77 
78 
79 /* Structure mantainace */
80 
81 typedef void ( * DrawFunc )( int, int, int, int, int, unsigned long );
82 
83 
84 /***************************************
85  ***************************************/
86 
87 void
draw_triangle(int fill,int x,int y,int w,int h,unsigned long col)88 draw_triangle( int           fill,
89 			   int           x,
90 			   int           y,
91 			   int           w,
92 			   int           h,
93 			   unsigned long col)
94 {
95 	XPoint xpoint[ 5 ];
96 	GC gc = fl_state[ fl_vmode ].gc[ 0 ];
97 	Window win = fl_winget( );
98 
99 	xpoint[ 0 ].x = x;
100 	xpoint[ 0 ].y = y + h - 1;
101 	xpoint[ 1 ].x = x + w/2;
102 	xpoint[ 1 ].y = y;
103 	xpoint[ 2 ].x = x + w - 1;
104 	xpoint[ 2 ].y = y + h - 1;
105 	XSetForeground( dpy, gc, fl_get_flcolor( col ) );
106 
107 	if ( fill )
108 		XFillPolygon ( dpy, win, gc, xpoint, 3, Nonconvex, Unsorted );
109 	else
110 	{
111 		xpoint[ 3 ].x = xpoint[ 0 ].x;
112 		xpoint[ 3 ].y = xpoint[ 0 ].y;
113 		XDrawLines( dpy, win, gc, xpoint, 4, CoordModeOrigin );
114 	}
115 }
116 
117 
118 /***************************************
119  ***************************************/
120 
121 static DrawFunc drawfunc[ ] = { fl_oval, fl_rectangle, draw_triangle };
122 
123 typedef struct
124 {
125     DrawFunc drawit;
126     int x,
127 	    y,
128 	    w,
129 	    h,
130 	    fill,
131 	    c[ 3 ];
132     int newfig;
133 } DrawFigure;
134 
135 static DrawFigure saved_figure[ 800 ],
136                   *cur_fig;
137 
138 
139 /***************************************
140  ***************************************/
141 
142 void
draw_initialize(FD_drawfree * ui)143 draw_initialize( FD_drawfree * ui )
144 {
145     cur_fig = saved_figure;
146     cur_fig->c[ 0 ] = cur_fig->c[ 1 ] = cur_fig->c[ 2 ] = 127,
147     cur_fig->w = cur_fig->h = 30;
148     cur_fig->drawit = fl_oval;
149     cur_fig->fill = 1;
150 
151     fl_mapcolor( FL_FREE_COL1,
152 				 cur_fig->c[ 0 ], cur_fig->c[ 1 ], cur_fig->c[ 2 ] );
153 
154     fl_set_slider_bounds( ui->wsli, 1, max_w );
155     fl_set_slider_bounds( ui->hsli, 1, max_h );
156     fl_set_slider_precision( ui->wsli, 0 );
157     fl_set_slider_precision( ui->hsli, 0 );
158     fl_set_slider_value( ui->wsli, cur_fig->w );
159     fl_set_slider_value( ui->hsli, cur_fig->h );
160 
161     /* Intial drawing function */
162 
163     fl_set_button( ui->drobj[ 0 ], 1 );
164 
165     /* Setup the color slider so we can find out colorobject from
166        the callback funtions. This is not necessary as drawui
167        is static, this is done to show how to access other objects
168        from an object callback function */
169 
170     ui->rsli->u_vdata = ui;
171     ui->gsli->u_vdata = ui;
172     ui->bsli->u_vdata = ui;
173 }
174 
175 
176 /***************************************
177  ***************************************/
178 
179 void
switch_object(FL_OBJECT * ob FL_UNUSED_ARG,long which)180 switch_object( FL_OBJECT * ob  FL_UNUSED_ARG,
181 			   long        which )
182 {
183     cur_fig->drawit = drawfunc[ which ];
184 }
185 
186 
187 /***************************************
188  ***************************************/
189 
190 void
change_color(FL_OBJECT * ob,long which)191 change_color( FL_OBJECT * ob,
192 			  long        which )
193 {
194     cur_fig->c[ which ] = 255 * fl_get_slider_value( ob );
195     fl_mapcolor( FL_FREE_COL1,
196 				 cur_fig->c[ 0 ], cur_fig->c[ 1 ], cur_fig->c[ 2 ] );
197     fl_redraw_object( ( ( FD_drawfree * ) ob->u_vdata )->colorobj );
198 }
199 
200 
201 /***************************************
202  ***************************************/
203 
204 void
fill_cb(FL_OBJECT * ob,long notused FL_UNUSED_ARG)205 fill_cb( FL_OBJECT * ob,
206 		 long        notused  FL_UNUSED_ARG )
207 {
208     cur_fig->fill = ! fl_get_button( ob );
209 }
210 
211 
212 /***************************************
213  ***************************************/
214 
215 void
change_size(FL_OBJECT * ob,long which)216 change_size( FL_OBJECT * ob,
217 			 long        which )
218 {
219     if ( which == 0 )
220 		cur_fig->w = fl_get_slider_value( ob );
221     else
222 		cur_fig->h = fl_get_slider_value( ob );
223 }
224 
225 
226 /***************************************
227  ***************************************/
228 
229 void
refresh_cb(FL_OBJECT * ob FL_UNUSED_ARG,long which FL_UNUSED_ARG)230 refresh_cb( FL_OBJECT * ob     FL_UNUSED_ARG,
231 			long        which  FL_UNUSED_ARG )
232 {
233     fl_redraw_object( drawui->freeobj );
234 }
235 
236 
237 /***************************************
238  ***************************************/
239 
240 void
clear_cb(FL_OBJECT * ob FL_UNUSED_ARG,long notused FL_UNUSED_ARG)241 clear_cb( FL_OBJECT * ob       FL_UNUSED_ARG,
242 		  long        notused  FL_UNUSED_ARG )
243 {
244     saved_figure[ 0 ] = *cur_fig;
245     cur_fig = saved_figure;
246     fl_redraw_object( drawui->freeobj );
247 }
248 
249 
250 /***************************************
251   The routine that does drawing
252  ***************************************/
253 
254 int
freeobject_handler(FL_OBJECT * ob,int event,FL_Coord mx,FL_Coord my,int key,void * xev FL_UNUSED_ARG)255 freeobject_handler( FL_OBJECT * ob,
256 					int         event,
257 					FL_Coord    mx,
258 					FL_Coord    my,
259 					int         key,
260 					void      * xev  FL_UNUSED_ARG )
261 {
262     DrawFigure *dr;
263 
264     switch ( event )
265     {
266 		case FL_DRAW:
267 			if ( cur_fig->newfig == 1 )
268 				cur_fig->drawit( cur_fig->fill,
269 								 cur_fig->x + ob->x,
270 								 cur_fig->y + ob->y,
271 								 cur_fig->w, cur_fig->h, FL_FREE_COL1 );
272 			else
273 			{
274 				fl_draw_box( ob->boxtype, ob->x, ob->y, ob->w, ob->h, ob->col1,
275                              FL_BOUND_WIDTH );
276 
277 				for ( dr = saved_figure; dr < cur_fig; dr++ )
278 				{
279 					fl_mapcolor( FL_FREE_COL1,
280 								 dr->c[ 0 ], dr->c[ 1 ], dr->c[ 2 ] );
281 					dr->drawit( dr->fill, dr->x + ob->x,
282 								dr->y + ob->y,
283 								dr->w, dr->h, FL_FREE_COL1 );
284 				}
285 			}
286 			cur_fig->newfig = 0;
287 			break;
288 
289 		case FL_PUSH:
290 			if ( key != 2 )
291 			{
292 				cur_fig->x = mx - cur_fig->w / 2;
293 				cur_fig->y = my - cur_fig->h / 2;
294 
295 				/* Convert position to relative to the free object */
296 
297 				cur_fig->x -= ob->x;
298 				cur_fig->y -= ob->y;
299 
300 				cur_fig->newfig = 1;
301 				fl_redraw_object( ob );
302 				*( cur_fig + 1 ) = *cur_fig;
303 				cur_fig++;
304 				cur_fig->newfig = 0;
305 			}
306 			break;
307     }
308 
309     return 0;
310 }
311 
312 
313 /***************************************
314  ***************************************/
315 
316 FD_drawfree *
create_form_drawfree(void)317 create_form_drawfree( void )
318 {
319 	FL_OBJECT *obj;
320 	FD_drawfree *fdui = fl_calloc( 1, sizeof *fdui );
321 
322 	fdui->drawfree = fl_bgn_form( FL_NO_BOX, 530, 490 );
323 
324 	fl_add_box( FL_UP_BOX, 0, 0, 530, 490, "" );
325 
326 	fl_add_frame( FL_DOWN_FRAME, 145, 55, 370, 405, "" );
327 
328 	fdui->freeobj = obj = fl_add_free( FL_NORMAL_FREE, 145, 55, 370, 405, "",
329 									   freeobject_handler );
330 	fl_set_object_boxtype( obj, FL_FLAT_BOX );
331 
332 	fdui->colorobj = obj = fl_add_box( FL_BORDER_BOX, 25, 325, 90, 25, "");
333     fl_set_object_color( obj, FL_FREE_COL1, FL_COL1 );
334 
335     fdui->hsli = obj = fl_add_valslider( FL_HOR_SLIDER, 15, 55, 120, 25,
336                                          "Height" );
337     fl_set_object_lalign( obj, FL_ALIGN_TOP );
338     fl_set_object_callback( obj, change_size, 1 );
339 
340 	obj = fl_add_button( FL_NORMAL_BUTTON, 395, 15, 105, 30, "Quit" );
341     fl_set_object_shortcut( obj, "Qq#q", 1 );
342 
343 	obj = fl_add_checkbutton( FL_PUSH_BUTTON, 15, 430, 100, 35, "Outline" );
344     fl_set_object_color( obj, FL_MCOL, FL_BLUE );
345     fl_set_object_callback( obj, fill_cb, 0 );
346 
347 	fdui->wsli = obj = fl_add_valslider( FL_HOR_SLIDER, 15, 95, 120, 25,
348 										 "Width" );
349     fl_set_object_lalign( obj, FL_ALIGN_TOP );
350     fl_set_object_callback( obj, change_size, 0 );
351 
352 	obj = fl_add_button( FL_NORMAL_BUTTON, 280, 15, 105, 30, "Refresh" );
353     fl_set_object_callback( obj, refresh_cb, 0 );
354 
355 	obj = fl_add_button( FL_NORMAL_BUTTON, 165, 15, 105, 30, "Clear" );
356     fl_set_object_callback( obj, clear_cb, 0 );
357 
358 	fl_bgn_group( );
359 
360 	fdui->drobj[ 0 ] = obj = fl_add_button( FL_RADIO_BUTTON, 10, 390, 40, 40,
361 											"@#circle" );
362     fl_set_object_lcolor( obj, FL_YELLOW );
363     fl_set_object_callback( obj, switch_object, 0 );
364 
365 	fdui->drobj[ 1 ] = obj = fl_add_button( FL_RADIO_BUTTON, 50, 390, 40, 40,
366 											"@#square" );
367     fl_set_object_lcolor( obj, FL_YELLOW );
368     fl_set_object_callback( obj, switch_object, 1 );
369 
370 	fdui->drobj[ 2 ] = obj = fl_add_button( FL_RADIO_BUTTON, 90, 390, 40, 40,
371 											"@#8>" );
372     fl_set_object_lcolor( obj, FL_YELLOW );
373     fl_set_object_callback( obj, switch_object, 2 );
374 
375 	fl_end_group();
376 
377 	fdui->rsli = obj = fl_add_slider( FL_VERT_FILL_SLIDER, 25, 195, 30, 125,
378 									  "" );
379     fl_set_object_color( obj, FL_COL1, FL_RED );
380     fl_set_object_callback( obj, change_color, 0 );
381 
382 	fdui->gsli = obj = fl_add_slider( FL_VERT_FILL_SLIDER, 55, 195, 30, 125,
383 									  "" );
384     fl_set_object_color( obj, FL_COL1, FL_GREEN );
385     fl_set_object_callback( obj, change_color, 1 );
386 
387 	fdui->bsli = obj = fl_add_slider( FL_VERT_FILL_SLIDER, 85, 195, 30, 125,
388 									  "" );
389     fl_set_object_color( obj, FL_COL1, FL_BLUE );
390     fl_set_object_callback( obj, change_color, 2 );
391 
392 	fl_end_form( );
393 
394 	return fdui;
395 }
396 
397 
398 /*
399  * Local variables:
400  * tab-width: 4
401  * indent-tabs-mode: nil
402  * End:
403  */
404