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 License
15  *  along with XForms.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 /**
20  * \file sp_button.c
21  *
22  *  This file is part of XForms package
23  *  Copyright (c) 1996-2002  T.C. Zhao and Mark Overmars
24  *  All rights reserved.
25  *
26  * Settting button class specific attributes.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include <ctype.h>
34 
35 #include "fd_main.h"
36 #include "fd_spec.h"
37 #include "fd_iconinfo.h"
38 #include "spec/button_spec.h"
39 
40 static FD_buttonattrib *bt_attrib = NULL;
41 static FL_OBJECT * curobj = NULL;
42 
43 static FL_OBJECT * create_default_button( FL_OBJECT * ob );
44 static void get_data_name( FL_OBJECT *,
45                            IconInfo * );
46 
47 
48 #define IsIconButton( obj )                     \
49     (    ( obj )->objclass == FL_BITMAPBUTTON   \
50       || ( obj )->objclass == FL_PIXMAPBUTTON )
51 
52 
53 /***************************************
54  ***************************************/
55 
56 FL_FORM *
button_create_spec_form(void)57 button_create_spec_form( void )
58 {
59     if ( bt_attrib )
60         return bt_attrib->buttonattrib;
61 
62     bt_attrib = create_form_buttonattrib( );
63 
64     fl_addto_choice( bt_attrib->pixalign,
65                      align_name( FL_ALIGN_CENTER, 0 ) );
66     fl_addto_choice( bt_attrib->pixalign,
67                      align_name( FL_ALIGN_TOP, 0 ) );
68     fl_addto_choice( bt_attrib->pixalign,
69                      align_name( FL_ALIGN_BOTTOM, 0 ) );
70     fl_addto_choice( bt_attrib->pixalign,
71                      align_name( FL_ALIGN_LEFT, 0 ) );
72     fl_addto_choice( bt_attrib->pixalign,
73                      align_name( FL_ALIGN_RIGHT, 0 ) );
74 
75     fl_set_input_return( bt_attrib->filename, FL_RETURN_END );
76     fl_set_input_return( bt_attrib->focus_filename, FL_RETURN_END );
77 
78     return bt_attrib->buttonattrib;
79 }
80 
81 
82 /***************************************
83  ***************************************/
84 
85 void
button_adjust_spec_form(FL_OBJECT * obj)86 button_adjust_spec_form( FL_OBJECT * obj )
87 {
88     curobj = obj;
89 
90     if ( obj->type == FL_PUSH_BUTTON || obj->type == FL_RADIO_BUTTON )
91         fl_show_object( bt_attrib->initialval );
92     else
93         fl_hide_object( bt_attrib->initialval );
94 
95     if ( IsIconButton( obj ) )
96     {
97         fl_show_object( bt_attrib->filename );
98         fl_show_object( bt_attrib->browse );
99         fl_show_object( bt_attrib->use_data );
100         fl_show_object( bt_attrib->fullpath );
101 
102         if ( obj->objclass == FL_PIXMAPBUTTON )
103         {
104             fl_show_object( bt_attrib->pixalign );
105             fl_show_object( bt_attrib->showfocus );
106             fl_show_object( bt_attrib->focus_filename );
107             fl_show_object( bt_attrib->browse2 );
108         }
109     }
110     else
111     {
112         fl_hide_object( bt_attrib->filename );
113         fl_hide_object( bt_attrib->focus_filename );
114         fl_hide_object( bt_attrib->browse );
115         fl_hide_object( bt_attrib->browse2 );
116         fl_hide_object( bt_attrib->use_data );
117         fl_hide_object( bt_attrib->fullpath );
118     }
119 
120     if ( obj->objclass != FL_PIXMAPBUTTON )
121     {
122         fl_hide_object( bt_attrib->pixalign );
123         fl_hide_object( bt_attrib->showfocus );
124         fl_hide_object( bt_attrib->focus_filename );
125         fl_hide_object( bt_attrib->browse2 );
126     }
127 }
128 
129 
130 /***************************************
131  ***************************************/
132 
133 void
button_fill_in_spec_form(FL_OBJECT * obj)134 button_fill_in_spec_form( FL_OBJECT * obj )
135 {
136     FL_BUTTON_SPEC *sp = obj->spec;
137     IconInfo *info = get_iconinfo( obj );
138 
139     fl_set_button( bt_attrib->react_left,   sp->react_to[ 0 ] );
140     fl_set_button( bt_attrib->react_middle, sp->react_to[ 1 ] );
141     fl_set_button( bt_attrib->react_right,  sp->react_to[ 2 ] );
142     fl_set_button( bt_attrib->react_up,     sp->react_to[ 3 ] );
143     fl_set_button( bt_attrib->react_down,   sp->react_to[ 4 ] );
144     fl_set_button( bt_attrib->initialval,   sp->val );
145 
146     if ( info )
147     {
148         fl_set_button( bt_attrib->use_data, info->use_data );
149         fl_set_button( bt_attrib->fullpath, info->fullpath );
150 
151         fl_set_button( bt_attrib->showfocus, info->show_focus );
152         fl_set_choice_text( bt_attrib->pixalign, align_name( info->align, 0 ) );
153 
154         fl_set_input( bt_attrib->filename, info->filename );
155         fl_set_input( bt_attrib->focus_filename, info->focus_filename );
156     }
157 }
158 
159 
160 /***************************************
161  ***************************************/
162 
163 void
button_reread_spec_form(FL_OBJECT * obj)164 button_reread_spec_form( FL_OBJECT * obj )
165 {
166     if ( ! IsIconButton( obj ) || ! curobj )
167         return;
168 
169     iconbutton_filename_change( bt_attrib->filename, 0 );
170 
171     if ( obj->objclass == FL_PIXMAPBUTTON )
172         focusiconbutton_filename_change( bt_attrib->focus_filename, 0 );
173 
174     redraw_the_form( 0 );
175 }
176 
177 
178 /***************************************
179  ***************************************/
180 
181 void
button_restore_spec(FL_OBJECT * obj)182 button_restore_spec( FL_OBJECT * obj )
183 {
184     IconInfo *info;
185 
186     if ( ! IsIconButton( obj ) )
187         return;
188 
189     info = get_iconinfo( obj );
190 
191     if ( *info->filename )
192     {
193         if ( obj->objclass == FL_PIXMAPBUTTON )
194             fl_set_pixmapbutton_file( obj, info->filename );
195         else
196             fl_set_bitmapbutton_file( obj, info->filename );
197     }
198     else
199     {
200         /* Show the default broken image link image */
201 
202         if ( obj->objclass == FL_PIXMAPBUTTON )
203             set_testing_pixmap( obj );
204         else
205             set_testing_bitmap( obj );
206     }
207 
208     if ( obj->objclass == FL_PIXMAPBUTTON )
209     {
210         if ( *info->focus_filename )
211             fl_set_pixmapbutton_focus_file( obj, info->focus_filename );
212 
213         fl_set_pixmap_align( obj, fl_to_inside_lalign( info->align ),
214                              info->dx, info->dy );
215     }
216 }
217 
218 
219 /***************************************
220  ***************************************/
221 
222 void
button_emit_spec_fd_code(FILE * fp,FL_OBJECT * obj)223 button_emit_spec_fd_code( FILE      * fp,
224                           FL_OBJECT * obj )
225 {
226     FL_OBJECT *defobj = defobj = create_default_button( obj );
227     FL_BUTTON_SPEC *sp    = obj->spec,
228                    *defsp = defobj->spec;
229     IconInfo *info,
230              *definfo;
231 
232     if ( memcmp( sp->react_to, defsp->react_to, sizeof sp->react_to ) )
233     {
234         unsigned int rt =   ( sp->react_to[ 0 ] &  1 )
235                           | ( sp->react_to[ 1 ] &  2 )
236                           | ( sp->react_to[ 2 ] &  4 )
237                           | ( sp->react_to[ 3 ] &  8 )
238                           | ( sp->react_to[ 4 ] & 16 );
239 
240         fprintf( fp, "    mbuttons: %u\n", rt );
241     }
242 
243     if ( sp->val != defsp->val )
244         fprintf( fp, "    value: %d\n", sp->val );
245 
246     if ( ! IsIconButton( obj ) )
247     {
248         fl_free_object( defobj );
249         return;
250     }
251 
252     info = get_iconinfo( obj );
253     spec_to_superspec( defobj );
254     definfo = get_iconinfo( defobj );
255 
256     get_data_name( obj, info );
257 
258     if ( *info->filename )
259     {
260         fprintf( fp, "    file: %s\n", info->filename );
261         if ( *info->focus_filename )
262             fprintf( fp, "    focus_file: %s\n", info->focus_filename );
263         fprintf( fp, "    fullpath: %d\n", info->fullpath );
264     }
265 
266     if (    obj->objclass == FL_PIXMAPBUTTON
267          && info->align != definfo->align )
268         fprintf( fp, "    align: %s\n",
269                  align_name( info->align | FL_ALIGN_INSIDE, 0 ) );
270 
271     if ( info->show_focus != definfo->show_focus )
272         fprintf( fp, "    focus: %d\n", info->show_focus );
273 
274     if ( *info->data && *info->filename )
275     {
276         fprintf( fp, "    data: %s\n", info->data );
277         if ( *info->focus_data )
278             fprintf( fp, "    focus_data: %s\n", info->focus_data );
279     }
280 
281     if ( *info->width )
282         fprintf( fp, "    width: %s\n", info->width );
283     if ( *info->height )
284         fprintf( fp, "    height: %s\n", info->height );
285 
286     free_iconinfo( defobj );
287     free_superspec( defobj );
288     fl_free_object( defobj );
289 }
290 
291 
292 /***************************************
293  ***************************************/
294 
295 void
button_emit_spec_c_code(FILE * fp,FL_OBJECT * obj)296 button_emit_spec_c_code( FILE      * fp,
297                          FL_OBJECT * obj )
298 {
299     FL_OBJECT *defobj = defobj = create_default_button( obj );
300     FL_BUTTON_SPEC *sp    = obj->spec,
301                    *defsp = defobj->spec;
302     IconInfo *info,
303              *definfo;
304 
305     if ( sp->val != defsp->val )
306         fprintf( fp, "    fl_set_button( obj, %d );\n", sp->val );
307 
308     if ( memcmp( sp->react_to, defsp->react_to, sizeof sp->react_to ) )
309     {
310         unsigned int rt =   ( sp->react_to[ 0 ] &  1 )
311                           | ( sp->react_to[ 1 ] &  2 )
312                           | ( sp->react_to[ 2 ] &  4 )
313                           | ( sp->react_to[ 3 ] &  8 )
314                           | ( sp->react_to[ 4 ] & 16 );
315 
316         fprintf( fp, "    fl_set_button_mouse_buttons( obj, %u );\n", rt );
317     }
318 
319     if ( ! IsIconButton( obj ) )
320     {
321         fl_free_object( defobj );
322         return;
323     }
324 
325     info = get_iconinfo( obj );
326     spec_to_superspec( defobj );
327     definfo = get_iconinfo( defobj );
328 
329     if (    obj->objclass == FL_PIXMAPBUTTON
330          && info->align != definfo->align )
331         fprintf( fp, "    fl_set_pixmapbutton_align( obj, %s, %d, %d );\n",
332                  align_name( info->align | FL_ALIGN_INSIDE, 1 ),
333                  info->dx, info->dy );
334 
335     if ( *info->filename && ! info->use_data )
336     {
337         fprintf( fp, "    fl_set_%sbutton_file( obj, \"%s\" );\n",
338                  obj->objclass == FL_PIXMAPBUTTON ? "pixmap" : "bitmap",
339                  info->filename );
340 
341         if ( obj->objclass == FL_PIXMAPBUTTON && *info->focus_filename )
342             fprintf( fp, "    fl_set_pixmapbutton_focus_file( obj, \"%s\" );\n",
343                      info->focus_filename );
344     }
345 
346     if ( *info->data && info->use_data && *info->filename )
347     {
348         if ( obj->objclass == FL_PIXMAPBUTTON )
349         {
350             fprintf( fp, "    fl_set_pixmapbutton_data( obj, %s );\n",
351                      info->data );
352 
353             if ( *info->focus_filename )
354                 fprintf( fp, "    fl_set_pixmapbutton_focus_data( obj, %s );\n",
355                          info->focus_data );
356         }
357         else
358             fprintf( fp, "    fl_set_bitmapbutton_data( obj, %s, %s, "
359                      "( unsigned char * ) %s );\n",
360                      info->width, info->height, info->data );
361     }
362 
363     if (    obj->objclass == FL_PIXMAPBUTTON
364          && info->show_focus != definfo->show_focus )
365         fprintf( fp, "    fl_set_pixmapbutton_focus_outline( obj, %d );\n",
366                  info->show_focus );
367 
368     free_iconinfo( defobj );
369     free_superspec( defobj );
370     fl_free_object( defobj );
371 }
372 
373 
374 /***************************************
375  ***************************************/
376 
377 void
button_emit_spec_header(FILE * fp,FL_OBJECT * obj)378 button_emit_spec_header( FILE      * fp,
379                          FL_OBJECT * obj )
380 {
381     IconInfo *info;
382 
383     if ( ! IsIconButton( obj ) )
384         return;
385 
386     info = get_iconinfo( obj );
387 
388     if ( info->use_data && *info->data && *info->filename )
389     {
390         const char *fn = info->fullpath ? info->filename
391                                         : file_tail( info->filename );
392 
393         if ( ! is_duplicate_info( fn ) )
394             fprintf( fp, "#include \"%s\"\n", fn );
395 
396         if ( obj->objclass == FL_PIXMAPBUTTON && *info->focus_filename )
397         {
398             fn = info->fullpath ? info->focus_filename
399                                 : file_tail( info->focus_filename );
400 
401             if ( ! is_duplicate_info( fn ) )
402                 fprintf( fp, "#include \"%s\"\n", fn );
403         }
404     }
405 }
406 
407 
408 /***************************************
409  ***************************************/
410 
411 void
usedata_change(FL_OBJECT * obj,long data FL_UNUSED_ARG)412 usedata_change( FL_OBJECT * obj,
413                 long        data  FL_UNUSED_ARG )
414 {
415     get_iconinfo( curobj )->use_data = fl_get_button( obj );
416 }
417 
418 
419 /***************************************
420  ***************************************/
421 
422 void
fullpath_cb(FL_OBJECT * ob,long data FL_UNUSED_ARG)423 fullpath_cb( FL_OBJECT * ob,
424              long        data  FL_UNUSED_ARG )
425 {
426     get_iconinfo( curobj )->fullpath = fl_get_button( ob );
427 }
428 
429 
430 /***************************************
431  ***************************************/
432 
433 void
react_to_button(FL_OBJECT * obj,long data)434 react_to_button( FL_OBJECT * obj,
435                  long        data )
436 {
437     unsigned int mb;
438 
439     fl_get_button_mouse_buttons( curobj, &mb );
440 
441     if ( fl_get_button( obj ) )
442         mb |= 1 << data;
443     else
444         mb &= ~ ( 1 << data );
445 
446     fl_set_button_mouse_buttons( curobj, mb );
447 }
448 
449 
450 /***************************************
451  ***************************************/
452 
453 void
initialval_change(FL_OBJECT * obj,long data FL_UNUSED_ARG)454 initialval_change( FL_OBJECT * obj,
455                    long        data  FL_UNUSED_ARG )
456 {
457     fl_set_button( curobj, fl_get_button( obj ) );
458     redraw_the_form( 0 );
459 }
460 
461 
462 /***************************************
463  ***************************************/
464 
465 void
showfocus_change(FL_OBJECT * obj,long data FL_UNUSED_ARG)466 showfocus_change( FL_OBJECT * obj,
467                   long        data  FL_UNUSED_ARG )
468 {
469     IconInfo *info = get_iconinfo( curobj );
470 
471     info->show_focus = fl_get_button( obj );
472     fl_set_pixmapbutton_focus_outline( curobj, info->show_focus );
473 }
474 
475 
476 /***************************************
477  ***************************************/
478 
479 void
iconbutton_filename_change(FL_OBJECT * ob,long data FL_UNUSED_ARG)480 iconbutton_filename_change( FL_OBJECT * ob,
481                             long        data  FL_UNUSED_ARG )
482 {
483     IconInfo *info = get_iconinfo( curobj );
484 
485     strcpy( info->filename, fl_get_input( ob ) );
486 
487     if ( *info->filename )
488     {
489         ( curobj->objclass == FL_PIXMAPBUTTON ?
490           fl_set_pixmapbutton_file : fl_set_bitmapbutton_file )
491             ( curobj, info->filename );
492     }
493     else
494     {
495         if ( curobj->objclass == FL_PIXMAPBUTTON )
496         {
497             fl_free_pixmap_pixmap( curobj );
498             set_testing_pixmap( curobj );
499         }
500         else
501             set_testing_bitmap( curobj );
502     }
503 
504     redraw_the_form( 0 );
505 }
506 
507 
508 /***************************************
509  ***************************************/
510 
511 void
focusiconbutton_filename_change(FL_OBJECT * obj,long data FL_UNUSED_ARG)512 focusiconbutton_filename_change( FL_OBJECT * obj,
513                                  long        data  FL_UNUSED_ARG )
514 {
515     IconInfo *info = get_iconinfo( curobj );
516 
517     strcpy( info->focus_filename, fl_get_input( obj ) );
518 
519     if ( *info->focus_filename )
520         fl_set_pixmapbutton_focus_file( curobj, info->focus_filename );
521 }
522 
523 
524 /***************************************
525  ***************************************/
526 
527 void
pixalign_change(FL_OBJECT * obj,long data FL_UNUSED_ARG)528 pixalign_change( FL_OBJECT * obj,
529                  long        data  FL_UNUSED_ARG )
530 {
531     IconInfo *info = get_iconinfo( curobj );
532     const char *s = fl_get_choice_text( obj );
533 
534     if ( ! s )
535         return;
536 
537     info->align = align_val( s );
538 
539     /* Don't allow outside align */
540 
541     fl_set_pixmap_align( curobj, fl_to_inside_lalign( info->align ),
542                          info->dx, info->dy );
543     redraw_the_form( 0 );
544 }
545 
546 
547 /***************************************
548  ***************************************/
549 
550 void
lookfor_pixmapfile_cb(FL_OBJECT * ob FL_UNUSED_ARG,long data)551 lookfor_pixmapfile_cb( FL_OBJECT * ob   FL_UNUSED_ARG,
552                        long        data )
553 {
554     const char *fn;
555     const char * def = data
556                        ? ( ( FL_BUTTON_STRUCT * ) curobj->spec )->focus_filename
557                        : ( ( FL_BUTTON_STRUCT * ) curobj->spec )->filename;
558     char buf[ 2048 ];
559     char *cwd;
560 
561     fl_use_fselector( XPM_FSELECTOR );
562     fl_set_fselector_placement( FL_PLACE_MOUSE );
563 
564     if ( curobj->objclass == FL_PIXMAPBUTTON )
565         fn = fl_show_fselector( "XPM file", "", "*.xpm", def );
566     else
567         fn = fl_show_fselector( "XBM file", "", "*.xbm", def );
568 
569     if ( ! fn )
570         return;
571 
572     cwd = fli_getcwd( buf, sizeof buf - 2 );
573     if ( cwd && strstr( fn, cwd ) )
574         fn += strlen( cwd ) + 1;
575 
576     ob = data ? bt_attrib->focus_filename : bt_attrib->filename;
577 
578     fl_set_input( ob, fn );
579     fl_call_object_callback( ob );
580 }
581 
582 
583 /***************************************
584  ***************************************/
585 
586 static FL_OBJECT *
create_default_button(FL_OBJECT * ob)587 create_default_button( FL_OBJECT * ob )
588 {
589     FL_OBJECT *defobj = NULL;
590 
591     /* Create a default object */
592 
593     if ( ob->objclass == FL_BUTTON )
594         defobj = fl_create_button( ob->type, 0, 0, 0, 0, "" );
595     else if ( ob->objclass == FL_BITMAPBUTTON )
596         defobj = fl_create_bitmapbutton( ob->type, 0, 0, 0, 0, "" );
597     else if ( ob->objclass == FL_PIXMAPBUTTON )
598         defobj = fl_create_pixmapbutton( ob->type, 0, 0, 0, 0, "" );
599     else if ( ob->objclass == FL_ROUNDBUTTON )
600         defobj = fl_create_roundbutton( ob->type, 0, 0, 0, 0, "" );
601     else if ( ob->objclass == FL_LABELBUTTON )
602         defobj = fl_create_labelbutton( ob->type, 0, 0, 0, 0, "" );
603     else if ( ob->objclass == FL_LIGHTBUTTON )
604         defobj = fl_create_lightbutton( ob->type, 0, 0, 0, 0, "" );
605     else if ( ob->objclass == FL_CHECKBUTTON )
606         defobj = fl_create_checkbutton( ob->type, 0, 0, 0, 0, "" );
607     else if ( ob->objclass == FL_ROUND3DBUTTON )
608         defobj = fl_create_round3dbutton( ob->type, 0, 0, 0, 0, "" );
609     else
610         fprintf( stderr, "Unknown Button Class: %d\n", ob->objclass );
611 
612     return defobj;
613 }
614 
615 
616 /***************************************
617  ***************************************/
618 
619 static void
get_data_name(FL_OBJECT * obj,IconInfo * info)620 get_data_name( FL_OBJECT * obj,
621                IconInfo  * info )
622 {
623     FILE *fp;
624 
625     if ( ! info->use_data )
626         return;
627 
628     if ( *info->filename )
629     {
630         if ( ( fp = fopen( info->filename, "r" ) ) )
631         {
632             if ( obj->objclass == FL_PIXMAPBUTTON )
633                 get_xpm_stuff( info->data, fp );
634             else
635                 get_xbm_stuff( info, fp );
636 
637             fclose( fp );
638         }
639 
640         if ( ! fp || ! *info->data )
641         {
642             fprintf( stderr, "Can't open or read '%s'\n", info->filename );
643             *info->filename = '\0';
644         }
645 
646     }
647 
648     if ( obj->objclass != FL_PIXMAPBUTTON || ! *info->focus_filename )
649         return;
650 
651     if ( ( fp = fopen( info->focus_filename, "r" ) ) )
652     {
653         get_xpm_stuff( info->focus_data, fp );
654         fclose( fp );
655     }
656 
657     if ( ! fp || ! *info->focus_data )
658     {
659         fprintf( stderr, "Can't open or read focusfile '%s'\n",
660                  info->focus_filename );
661         *info->focus_filename = '\0';
662     }
663 }
664 
665 
666 #include "spec/button_spec.c"
667 
668 
669 /*
670  * Local variables:
671  * tab-width: 4
672  * indent-tabs-mode: nil
673  * End:
674  */
675