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 fd_control.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  *  Form designer Control panel handling
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "fd_main.h"
34 #include "fd/ui_theforms.h"
35 #include "private/pmenu.h"
36 #include "private/pchoice.h"
37 
38 /* All control panel menus, File Object Options etc. have this
39  * common structures
40  */
41 
42 typedef struct {
43     const char * entry;     /* label     */
44     const char * sc;        /* shortcut  */
45     void         ( * callback )( FL_OBJECT *,   /* callback functions */
46                                  long );
47     int          n;         /* func_cb parameter */
48     int        * p;         /* binary value      */
49 } MenuEntry;
50 
51 extern void exit_cb( FL_OBJECT *,
52                      long );
53 extern void saveforms_cb( FL_OBJECT *,
54                           long );
55 
56 /**** FileMenu ******{*/
57 
58 static MenuEntry fmenu[ ] =
59 {
60     { " Open",       "Oo#o", loadforms_cb,    0, 0 },
61     { " Merge",      "Mm#m", mergeforms_cb,   0, 0 },
62     { " Save",       "Ss#s", saveforms_cb,    0, 0 },
63     { " Save As %l", "Aa#a", saveforms_as_cb, 0, 0 },
64     { " Exit",       "Ee#e", exit_cb,         0, 0 }
65 };
66 
67 #define NFM  ( sizeof fmenu / sizeof *fmenu )
68 
69 
70 /***************************************
71  ***************************************/
72 
73 void
filemenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)74 filemenu_callback( FL_OBJECT * ob,
75                    long        data  FL_UNUSED_ARG )
76 {
77     int n = fl_get_menu( ob ) - 1;
78 
79     if ( n >= 0 && fmenu[ n ].callback )
80         fmenu[ n ].callback( 0, 0 );
81 }
82 
83 
84 /***************************************
85  * Exit the program
86  ***************************************/
87 
88 void
exit_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)89 exit_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
90          long        arg  FL_UNUSED_ARG )
91 {
92     if ( changed )
93     {
94         int rep;
95 
96         fl_set_choices_shortcut( "Ss#s", "Ee#e", "Rr#r" );
97         rep = fl_show_choice( "WARNING", "", "Changes have not been saved.",
98                               3, "Save", "Exit", "Return", 1 );
99         if ( ( rep == 1 && ! save_forms( NULL ) ) || rep == 3 )
100             return;
101     }
102 
103     fl_finish( );
104     exit( 0 );
105 }
106 
107 
108 /***************************************
109  * Merge a set of forms with the current ones.
110  ***************************************/
111 
112 void
mergeforms_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)113 mergeforms_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
114                long        arg  FL_UNUSED_ARG )
115 {
116     load_forms( FL_TRUE, NULL );
117 }
118 
119 
120 /***************************************
121  * Save the current set of forms.
122  ***************************************/
123 
124 void
saveforms_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)125 saveforms_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
126               long        arg  FL_UNUSED_ARG )
127 {
128     changed = ! save_forms( loadedfile);
129 }
130 
131 
132 /***************************************
133  ***************************************/
134 
135 void
saveforms_as_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)136 saveforms_as_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
137                  long        arg  FL_UNUSED_ARG )
138 {
139     changed = ! save_forms( NULL );
140 }
141 
142 
143 /***************************************
144  * Load a new set of forms from a file
145  ***************************************/
146 
147 void
loadforms_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)148 loadforms_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
149               long        arg  FL_UNUSED_ARG )
150 {
151     if (    changed
152          && fl_show_question( "Forms have been changed!\n"
153                               "Should I save them?", 1 )
154          && ! save_forms( NULL ) )
155         return;
156 
157     load_forms( FL_FALSE, NULL );
158 }
159 
160 
161 /***** End of FileMenu *****/
162 
163 /* Group Menu entry */
164 
165 static MenuEntry gmenu[ ] =
166 {
167     { "New group",    "Nn#n", NULL,               7, 0 },
168     { "Delete Group", "Dd#d", NULL,               8, 0 },
169     { "Rename Group", "Rr#r", changegroupname_cb, 0, 0 }
170 };
171 
172 #define NGM ( sizeof gmenu / sizeof *gmenu )
173 
174 
175 /***************************************
176  ***************************************/
177 
178 void
groupmenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)179 groupmenu_callback( FL_OBJECT * ob,
180                     long        data  FL_UNUSED_ARG )
181 {
182     int n = fl_get_menu( ob ) - 1;
183 
184     if ( n >= 0 )
185     {
186         if ( gmenu[ n ].callback )
187             gmenu[ n ].callback( 0, 0 );
188         else
189             func_cb( 0, gmenu[ n ].n );
190     }
191 }
192 
193 
194 /* Object menu entry */
195 
196 static MenuEntry obmenu[ ] =
197 {
198     { "Object Attributes", "Oo#o", 0,  1, 0 },
199     { "Lower Object",      "Ll#l", 0,  2, 0 },
200     { "Raise Object",      "Rr#r", 0,  3, 0 },
201     { "Show Object",       "Ss#s", 0,  5, 0 },
202     { "Hide Object",       "Hh#h", 0,  6, 0 },
203     { "Cut Object",        "Cc#c", 0, 12, 0 },
204     { "Paste Object",      "Pp#p", 0, 10, 0 }
205 };
206 
207 #define NOBM  ( sizeof obmenu / sizeof *obmenu )
208 
209 
210 /***************************************
211  ***************************************/
212 
213 void
objectmenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)214 objectmenu_callback( FL_OBJECT * ob,
215                      long        data  FL_UNUSED_ARG )
216 {
217     int n = fl_get_menu( ob ) - 1;
218 
219     if ( n >= 0 )
220         func_cb( 0, obmenu[ n ].n );
221 }
222 
223 
224 /* form menu entry */
225 
226 static MenuEntry fmmenu[ ] =
227 {
228     { "New Form",    "Nn#n", addform_cb,    0, 0 },
229     { "Delete Form", "Dd#d", deleteform_cb, 0, 0 },
230     { "Rename Form", "Rr#r", changename_cb, 0, 0 },
231     { "Resize Form", "Ss#s", changesize_cb, 0, 0 }
232 };
233 
234 #define NFMM ( sizeof fmmenu / sizeof *fmmenu )
235 
236 
237 /***************************************
238  ***************************************/
239 
240 void
formmenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)241 formmenu_callback( FL_OBJECT * ob,
242                    long        data  FL_UNUSED_ARG )
243 {
244     int n = fl_get_menu( ob ) - 1;
245 
246     if ( n >= 0 && fmmenu[ n ].callback )
247         fmmenu[ n ].callback( 0, 0 );
248 }
249 
250 
251 /* Option menu */
252 
253 static MenuEntry opmenu[ ] =
254 {
255     { "Track Geometry",  "Gg#g", 0, 0, &fd_trackgeometry },
256     { "Show Pallette",   "Pp#p", 0, 0, &fd_show_palette  },
257     { "Emit %s UI code", "Ee#e", 0, 0, &fdopt.emit_code  },
258     { "Emit Callback",   "Cc#c", 0, 0, &fdopt.emit_cb    },
259     { "Emit Main",       "Mm#m", 0, 0, &fdopt.emit_main  },
260     { "Alt Format",      "Aa#a", 0, 0, &fdopt.altformat  },
261     { "FS Compensate ",  "Ff#f", 0, 0, &fdopt.compensate }
262 };
263 
264 #define NOPM ( sizeof opmenu / sizeof *opmenu )
265 
266 
267 /***************************************
268  ***************************************/
269 
270 void
optionmenu_callback(FL_OBJECT * ob,long data FL_UNUSED_ARG)271 optionmenu_callback( FL_OBJECT * ob,
272                      long        data  FL_UNUSED_ARG )
273 {
274     int n = fl_get_menu( ob ) - 1;
275     char buf[ 32 ];
276 
277     if ( n >= 0 )
278     {
279         *opmenu[ n ].p = ! *opmenu[ n ].p;
280         sprintf( buf, "%s%%%c", opmenu[ n ].entry,
281                  *opmenu[ n ].p ? 'B' : 'b' );
282         fl_replace_menu_item( fd_control->optionmenu, n + 1, buf );
283         ( fd_show_palette ? show_pallette : hide_pallette )( );
284     }
285 }
286 
287 
288 /***************************************
289  ***************************************/
290 
291 void
reset_pallette_menu_status(void)292 reset_pallette_menu_status( void)
293 {
294     fl_set_menu_item_mode( fd_control->optionmenu, 2, FL_PUP_BOX );
295     fd_show_palette = 0;
296 }
297 
298 
299 /***************************************
300  ***************************************/
301 
302 static void
deactivate_control(FL_FORM * form FL_UNUSED_ARG,void * data FL_UNUSED_ARG)303 deactivate_control( FL_FORM * form  FL_UNUSED_ARG,
304                     void    * data  FL_UNUSED_ARG )
305 {
306     fl_set_object_lcolor( fd_control->title, FL_SLATEBLUE );
307     fl_set_object_lcolor( fd_control->menubar_group, FL_INACTIVE );
308     fl_set_object_lcolor( fd_control->shortcut_group, FL_INACTIVE );
309     fl_set_object_lcolor( fd_control->fkey_group, FL_INACTIVE );
310 }
311 
312 
313 /***************************************
314  ***************************************/
315 
316 static void
activate_control(FL_FORM * form FL_UNUSED_ARG,void * data FL_UNUSED_ARG)317 activate_control( FL_FORM * form  FL_UNUSED_ARG,
318                   void    * data  FL_UNUSED_ARG )
319 {
320     fl_set_object_lcolor( fd_control->title, FL_BLUE );
321     fl_set_object_lcolor( fd_control->menubar_group, FL_BLACK );
322     fl_set_object_lcolor( fd_control->shortcut_group, FL_BLACK );
323     fl_set_object_lcolor( fd_control->fkey_group, FL_BLACK );
324 }
325 
326 
327 /***************************************
328  * Initialize the control panel by filling in the menu entries
329  ***************************************/
330 
331 void
control_init(FD_control * ui)332 control_init( FD_control * ui )
333 {
334     static int control_initialized;
335     MenuEntry *m,
336               *me;
337     char buf[ 32 ];
338     int i;
339 
340     if ( control_initialized )
341         return;
342 
343     control_initialized = 1;
344 
345 #ifdef __sgi
346     fl_set_object_lsize( ui->filemenu,   FL_SMALL_SIZE );
347     fl_set_object_lsize( ui->formmenu,   FL_SMALL_SIZE );
348     fl_set_object_lsize( ui->groupmenu,  FL_SMALL_SIZE );
349     fl_set_object_lsize( ui->objectmenu, FL_SMALL_SIZE );
350     fl_set_object_lsize( ui->optionmenu, FL_SMALL_SIZE );
351 #endif
352 
353     fl_set_form_atdeactivate( ui->control, deactivate_control, ui );
354     fl_set_form_atactivate( ui->control, activate_control, ui );
355 
356     fl_set_object_dblbuffer( ui->seltype,    1 );
357     fl_set_object_dblbuffer( ui->selname,    1 );
358     fl_set_object_dblbuffer( ui->selcb,      1 );
359     fl_set_object_dblbuffer( ui->sizestatus, 1 );
360     fl_set_object_dblbuffer( ui->oristatus,  1 );
361 
362     /* File menu */
363 
364     for ( m = fmenu, me = m + NFM, i = 1; m < me; m++, i++ )
365     {
366         fl_addto_menu( ui->filemenu, m->entry );
367         fl_set_menu_item_shortcut( ui->filemenu, i, m->sc );
368     }
369 
370     /* Form menu */
371 
372     for ( m = fmmenu, me = m + NFMM, i = 1; m < me; m++, i++ )
373     {
374         fl_addto_menu( ui->formmenu, m->entry );
375         fl_set_menu_item_shortcut( ui->formmenu, i, m->sc );
376     }
377 
378     /* Group menu */
379 
380     for ( m = gmenu, me = m + NGM, i = 1; m < me; m++, i++ )
381     {
382         fl_addto_menu( ui->groupmenu, m->entry );
383         fl_set_menu_item_shortcut( ui->groupmenu, i, m->sc );
384     }
385 
386     /* Object menu */
387 
388     for ( m = obmenu, me = m + NOBM, i = 1; m < me; m++, i++ )
389     {
390         fl_addto_menu( ui->objectmenu, m->entry );
391         fl_set_menu_item_shortcut( ui->objectmenu, i, m->sc );
392     }
393 
394     /* Option menu.  all are binary items */
395 
396     for ( m = opmenu, me = m + NOPM, i = 1; m < me; m++, i++ )
397     {
398         if ( strncmp( m->entry, "Emit %s", 7 ) == 0 )
399         {
400             static char tmpbuf[ 128 ];
401 
402             sprintf( tmpbuf, m->entry, convertor[ fdopt.language ].lang_name );
403             m->entry = tmpbuf;
404         }
405 
406         sprintf( buf, "%s%%%c", m->entry, * ( m->p ) ? 'B' : 'b' );
407         fl_addto_menu( ui->optionmenu, buf );
408         fl_set_menu_item_shortcut( ui->optionmenu, i, m->sc );
409     }
410 }
411 
412 
413 /* Misc. service routines */
414 
415 /***************************************
416  ***************************************/
417 
418 void
show_geometry(FL_Coord x,FL_Coord y,FL_Coord w,FL_Coord h)419 show_geometry( FL_Coord     x,
420                FL_Coord     y,
421                FL_Coord     w,
422                FL_Coord     h )
423 {
424     char buf[ 128 ];
425     static FL_Coord lx = -1,
426                     ly,
427                     lw = -1,
428                     lh;
429 
430     /* Canonicalize rectangle */
431 
432     if ( w < 0 )
433     {
434         x += w;
435         w = -w;
436     }
437 
438     if ( h < 0 )
439     {
440         y += h;
441         h = -h;
442     }
443 
444     if ( x != lx || y != ly )
445     {
446         sprintf( buf, "%dx%d", x, y );
447         fl_set_object_label( fd_control->oristatus, buf );
448         lx = x;
449         ly = y;
450     }
451 
452     if ( w != lw || h != lh )
453     {
454         sprintf( buf, "%dx%d", w, h );
455         fl_set_object_label( fd_control->sizestatus, buf );
456         lw = w;
457         lh = h;
458     }
459 }
460 
461 
462 /***************************************
463  ***************************************/
464 
465 void
show_selmessage(FL_OBJECT * sel[],int n)466 show_selmessage( FL_OBJECT * sel[ ],
467                  int         n )
468 {
469     char objname[ MAX_VAR_LEN ],
470          cbname[ MAX_VAR_LEN ],
471          argname[ MAX_VAR_LEN ];
472     char buf[ MAX_VAR_LEN ];
473 
474     get_object_name( sel[ 0 ], objname, cbname, argname );
475     *buf = '\0';
476 
477     if ( n == 1 )
478         sprintf( buf, "%s",
479                  find_type_name( sel[ 0 ]->objclass, sel[ 0 ]->type ) );
480     else
481     {
482         int cnt = n,
483             i;
484 
485         for ( i = 0; i < n; i++ )
486             if (    sel[ i ]->objclass == FL_BEGIN_GROUP
487                  || sel[ i ]->objclass == FL_END_GROUP )
488                 cnt--;
489 
490         sprintf( buf, "%d object selected", cnt );
491     }
492 
493     fl_set_object_label( fd_control->seltype, buf );
494 
495     if ( n == 1 )
496         sprintf( buf, "%s", *objname ? objname : "<no name>" );
497     else
498         *buf = '\0';
499 
500     fl_set_object_label( fd_control->selname, buf );
501 
502     if ( n == 1 )
503     {
504         if ( * cbname )
505             sprintf( buf, "%s(%s)", cbname, argname );
506         else
507             strcpy( buf, "<no callback>" );
508     }
509     else
510         *buf = '\0';
511 
512     fl_set_object_label( fd_control->selcb, buf );
513 }
514 
515 
516 /********* Callback routines for the control panel  ***************/
517 
518 /*
519  * Form designer itself does not use resource settings, but when testing
520  * the newly created forms, resources are turned on. At the moment we
521  * only allow button label size to be changed
522  */
523 
524 FL_FORM *thetestform;
525 
526 typedef struct {
527     int x,
528         y,
529         w,
530         h;
531 } GEOM;
532 
533 static short *osize = NULL;
534 static GEOM *oldgeom = NULL;
535 static FL_Coord formw,
536                 formh;           /* original form size */
537 
538 
539 /***************************************
540  ***************************************/
541 
542 static void
fix_button_label_size(FL_FORM * form,int save)543 fix_button_label_size( FL_FORM * form,
544                        int       save )
545 {
546     FL_OBJECT *ob;
547     int i;
548 
549     if ( fd_buttonLabelSize == 0 )
550         return;
551 
552     if ( save )
553     {
554         for ( i = 0, ob = form->first; ob; ob = ob->next )
555             if ( ob->objclass == FL_BUTTON )
556                 i++;
557 
558         osize = fl_realloc( osize, i * sizeof *osize );
559     }
560 
561     for ( i = 0, ob = form->first; ob; ob = ob->next )
562     {
563         if ( ob->objclass == FL_BUTTON )
564         {
565             if ( save )
566             {
567                 osize[ i++ ] = ob->lsize;
568                 if ( ob->lsize == FL_NORMAL_FONT )
569                     ob->lsize = fd_buttonLabelSize;
570             }
571             else
572                 ob->lsize = osize[ i++ ];
573         }
574     }
575 
576     if ( ! save )
577         fli_safe_free( osize );
578 }
579 
580 
581 /***************************************
582  ***************************************/
583 
584 static void
fix_menu_etc(FL_FORM * form,int save)585 fix_menu_etc( FL_FORM * form,
586               int       save )
587 {
588     FL_OBJECT *ob;
589     int i;
590 
591     for ( ob = form->first; ob; ob = ob->next )
592     {
593         if (    ob->objclass != FL_MENU
594              && ob->objclass != FL_CHOICE
595              && ob->objclass != FL_BROWSER
596              && ! ISBUTTON( ob->objclass ) )
597             continue;
598 
599         if ( ob->objclass == FL_MENU )
600         {
601             FLI_MENU_SPEC *sp = ob->spec;
602 
603             if ( save )
604             {
605                 if ( sp->numitems > 0 )
606                     for ( i = 1; i <= sp->numitems; i++ )
607                         fli_safe_free( sp->cb[ i ] );
608                 else
609                 {
610                     fl_addto_menu( ob, "menuitem 1" );
611                     fl_addto_menu( ob, "menuitem 2" );
612                     fl_addto_menu( ob, "menuitem 3" );
613                     fl_addto_menu( ob, "menuitem 4" );
614                 }
615             }
616             else
617             {
618                 SuperSPEC *ssp = get_superspec( ob );
619 
620                 if ( sp->numitems == ssp->nlines )
621                     for ( i = 1; i <= sp->numitems; i++ )
622                         if ( ssp->callback[ i ] )
623                             sp->cb[ i ] =
624                                   ( FL_PUP_CB ) fl_strdup( ssp->callback[ i ] );
625                         else
626                             sp->cb[ i ] = NULL;
627                 else
628                     fl_clear_menu( ob );
629             }
630         }
631         else if ( ob->objclass == FL_CHOICE )
632         {
633             FLI_CHOICE_SPEC *sp = ob->spec;
634 
635             if ( save )
636             {
637                 if ( sp->numitems == 0 )
638                 {
639                     fl_addto_choice( ob, "choice 1" );
640                     fl_addto_choice( ob, "choice 2" );
641                     fl_addto_choice( ob, "choice 3" );
642                     fl_addto_choice( ob, "choice 4" );
643                 }
644             }
645             else
646             {
647                 SuperSPEC *ssp = get_superspec( ob );
648 
649                 if ( sp->numitems != ssp->nlines )
650                     fl_clear_choice( ob );
651             }
652         }
653         else if ( ob->objclass == FL_BROWSER )
654         {
655             int nlines = fl_get_browser_maxline( ob );
656 
657             if ( save )
658             {
659                 if ( nlines == 0 )
660                 {
661                     char buf[ 100 ];
662 
663                     for ( i = 0; i < 20; i++ )
664                     {
665                         sprintf( buf, "browser line %d", i + 1 );
666                         fl_add_browser_line( ob, buf );
667                     }
668                 }
669             }
670             else
671             {
672                 SuperSPEC *ssp = get_superspec( ob );
673 
674                 if ( nlines != ssp->nlines )
675                     fl_clear_browser( ob );
676             }
677         }
678         else if ( ISBUTTON( ob->objclass ) )
679         {
680             if ( save )
681                 ob->u_ldata = ( ( FL_BUTTON_SPEC * ) ob->spec )->val;
682             else
683                 ( ( FL_BUTTON_SPEC * ) ob->spec )->val = ob->u_ldata;
684         }
685     }
686 }
687 
688 
689 /***************************************
690  * Start a test of the current form
691  ***************************************/
692 
693 void
test_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)694 test_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
695          long        arg  FL_UNUSED_ARG )
696 {
697     int i;
698     FL_OBJECT *ob;
699     GEOM *p;
700     int resizeable;
701 
702     if ( cur_form == NULL )
703         return;
704 
705     fl_deactivate_form( fd_control->control );
706     thetestform = cur_form;
707 
708     /* During test, accumulation error might result. Save the old size */
709 
710     formw = cur_form->w;
711     formh = cur_form->h;
712 
713     for ( i = 0, ob = cur_form->first; ob; ob = ob->next, i++ )
714         /* empty */ ;
715 
716     p = oldgeom = fl_realloc( oldgeom, i * sizeof *p );
717 
718     for ( ob = cur_form->first; ob; ob = ob->next, i++, p++ )
719     {
720         if ( ! ob->parent )
721             spec_to_superspec( ob );
722 
723         p->x = ob->x;
724         p->y = ob->y;
725         p->w = ob->w;
726         p->h = ob->h;
727     }
728 
729     /* Change button label size to the one requested */
730 
731     fix_button_label_size( thetestform, 1 );
732 
733     fix_menu_etc( thetestform, 1 );
734 
735     cur_form = NULL;
736     redraw_the_form( 1 );
737 
738     fl_clear_browser( fd_test->browser );
739 
740     resizeable = strstr( get_placement( thetestform ), "FREE" ) != NULL;
741 
742     if ( resizeable )
743     {
744         fl_set_form_minsize( thetestform, formw >= 10 ? formw / 2 : formw,
745                              formh >= 10 ? formh / 2 : formh );
746         fl_set_form_maxsize( thetestform, fl_scrw, fl_scrh );
747     }
748     else
749     {
750         fl_set_form_minsize( thetestform, formw, formh );
751         fl_set_form_maxsize( thetestform, formw, formh );
752     }
753 
754     fl_show_form( thetestform,
755                   resizeable ? FL_PLACE_CENTERFREE : FL_PLACE_CENTER,
756                   FL_FULLBORDER, "Test Form" );
757 
758     fl_show_form( fd_test->test, FL_PLACE_POSITION | FL_PLACE_FREE,
759                   FL_FULLBORDER, "Test" );
760 }
761 
762 
763 /***************************************
764  * Ends a testing session
765  ***************************************/
766 
767 void
stoptest_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)768 stoptest_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
769              long        arg  FL_UNUSED_ARG )
770 {
771     FL_OBJECT *ob;
772     GEOM *p = oldgeom;
773 
774     if ( thetestform == NULL )
775         return;
776 
777     fl_hide_form( fd_test->test );
778     fl_hide_form( thetestform );
779 
780     fix_button_label_size( thetestform, 0 );
781 
782     fix_menu_etc( thetestform, 0 );
783 
784     cur_form = thetestform;
785     thetestform = NULL;
786 
787     fl_set_form_size( cur_form, formw, formh );
788 
789     for ( ob = cur_form->first; ob; ob = ob->next, p++ )
790     {
791         if ( ! ob->parent )
792             superspec_to_spec( ob );
793 
794         ob->x = p->x;
795         ob->y = p->y;
796         ob->w = p->w;
797         ob->h = p->h;
798     }
799 
800     fli_safe_free( oldgeom );
801 
802     redraw_the_form( 0 );
803     fl_activate_form( fd_control->control );
804 }
805 
806 
807 /***************************************
808  * Shows the align form
809  ***************************************/
810 
811 void
align_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)812 align_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
813           long        arg  FL_UNUSED_ARG )
814 {
815     if ( fd_align->align->visible )
816         fl_hide_form( fd_align->align );
817     else
818     {
819         fl_show_form( fd_align->align, FL_PLACE_MOUSE, FL_FULLBORDER,
820                       "Alignments" );
821         XRaiseWindow( flx->display, fd_align->align->window );
822     }
823 }
824 
825 
826 /***************************************
827  * Stop showing the align window
828  ***************************************/
829 
830 void
exitalign_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)831 exitalign_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
832               long        arg  FL_UNUSED_ARG )
833 {
834     fl_hide_form( fd_align->align );
835 }
836 
837 
838 /***************************************
839  * Does some alignment action
840  ***************************************/
841 
842 void
doalign_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg)843 doalign_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
844             long        arg )
845 {
846     if ( fd_align->vdata )
847         free_dupped_selection( fd_align->vdata );
848     fd_align->vdata = dup_selection( );
849     align_selection( arg );
850 }
851 
852 
853 /***************************************
854  ***************************************/
855 
856 void
undoalign_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)857 undoalign_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
858               long        arg  FL_UNUSED_ARG )
859 {
860     if ( fd_align->vdata )
861     {
862         set_selection( fd_align->vdata );
863 
864         /* Only allow undo once */
865 
866         free_dupped_selection( fd_align->vdata );
867         fd_align->vdata = NULL;
868     }
869 }
870 
871 
872 /***************************************
873  ***************************************/
874 
875 void
snap_cb(FL_OBJECT * obj,long arg FL_UNUSED_ARG)876 snap_cb( FL_OBJECT * obj,
877          long        arg  FL_UNUSED_ARG )
878 {
879     set_step_size( fl_get_counter_value( obj ) );
880 }
881 
882 /***** End of alignment stuff */
883 
884 
885 /***************************************
886  * The user pressed one of the function keys while in the main form
887  ***************************************/
888 
889 void
func_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg)890 func_cb( FL_OBJECT * obj  FL_UNUSED_ARG,
891          long        arg )
892 {
893     switch ( arg )
894     {
895         case 1:
896             change_selection( );
897             redraw_the_form( 0 );
898             break;
899 
900         case 2:
901             lower_selection( );
902             redraw_the_form( 0 );
903             break;
904 
905         case 3:
906             raise_selection( );
907             redraw_the_form( 0 );
908             break;
909 
910         case 4:
911             select_all( );
912             redraw_the_form( 0 );
913             break;
914 
915         case 5:
916             show_selection( );
917             redraw_the_form( 0 );
918             break;
919 
920         case 6:
921             hide_selection( );
922             redraw_the_form( 0 );
923             break;
924 
925         case 7:
926             group_selection( );
927             break;
928 
929         case 8:
930             flatten_selection( );
931             break;
932 
933         case 9:
934             copy_selection( );
935             break;
936 
937         case 10:
938             paste_selection( );
939             redraw_the_form( 0 );
940             break;
941 
942         case 11:
943             next_selection( );
944             break;
945 
946         case 12:
947             cut_selection( );
948             redraw_the_form( 0 );
949             break;
950     }
951 }
952 
953 
954 /***************************************
955  ***************************************/
956 
957 static void
draw_centering_symbol(FL_Coord x,FL_Coord y,FL_Coord w,FL_Coord h,int angle,FL_COLOR col)958 draw_centering_symbol( FL_Coord x,
959                        FL_Coord y,
960                        FL_Coord w,
961                        FL_Coord h,
962                        int      angle,
963                        FL_COLOR col )
964 {
965     int delta = 4;
966 
967     if ( angle == 0 || angle == 180 )
968     {
969         fl_draw_symbol( "@->", x, y, w / 2 + delta, h, col );
970         fl_draw_symbol( "@<-", x + w / 2 - delta, y, w / 2 + delta, h, col );
971     }
972     else
973     {
974         fl_draw_symbol( "@2->", x, y + 1, w, h / 2 + delta, col );
975         fl_draw_symbol( "@8->", x, y + h / 2 - delta - 1,
976                         w, h / 2 + delta - 1, col );
977     }
978 }
979 
980 
981 /***************************************
982  ***************************************/
983 
984 void
init_align(void)985 init_align( void )
986 {
987     fl_add_symbol( "-><-", draw_centering_symbol, 0 );
988     fl_set_object_label( fd_align->hcenter, "@-><-" );
989     fl_set_object_label( fd_align->vcenter, "@8-><-" );
990 
991     fl_set_object_helper( fd_align->left,    "Flush left" );
992     fl_set_object_helper( fd_align->hcenter, "Center horizontally" );
993     fl_set_object_helper( fd_align->hequal,  "Equal horizontal distance" );
994     fl_set_object_helper( fd_align->right,   "Flush right" );
995     fl_set_object_helper( fd_align->top,     "Flush top" );
996     fl_set_object_helper( fd_align->bottom,  "Flush bottom" );
997     fl_set_object_helper( fd_align->vcenter, "Center vertically" );
998     fl_set_object_helper( fd_align->vequal,  "Equal vertical distance" );
999 }
1000 
1001 
1002 /*
1003  * Local variables:
1004  * tab-width: 4
1005  * indent-tabs-mode: nil
1006  * End:
1007  */
1008