]> git.lyx.org Git - features.git/blob - src/mathed/math_panel.C
3cfdf86f47e258b62b9d9972c03f1216ac481bb9
[features.git] / src / mathed / math_panel.C
1 /*
2  *  File:        math_panel.C
3  *  Purpose:     Mathed GUI for lyx
4  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5  *  Created:     March 28, 1996
6  * 
7  *  Dependencies: Xlib, Xpm, XForms, Lyx
8  *
9  *  Copyright: (c) 1996, Alejandro Aguilar Sierra 
10  *
11  *   You are free to use and modify it under the terms of
12  *   the GNU General Public Licence version 2 or later.
13  */
14
15 #include <config.h>
16
17 #include FORMS_H_LOCATION
18 #include <cstdio>
19 #include <cstdlib>
20
21 #include "lyx_gui_misc.h" 
22 #include "math_panel.h"
23 #include "symbol_def.h"
24 #include "formula.h"
25 #include "lyxfunc.h"
26 #include "gettext.h"
27
28 /* Bitmaps */
29 #include "delim.xbm"
30 #include "delim0.xpm"
31 #include "delim.xpm"
32 #include "deco.xbm"
33 #include "deco.xpm"
34 #include "space.xpm"
35 #include "sqrt.xpm"
36 #include "frac.xpm"
37 #include "matrix.xpm"
38 #include "equation.xpm"
39
40 static LyXFunc * lyxfunc= 0;
41
42 //static FD_panel* symb_form= 0;
43
44 FD_panel  * fd_panel;
45 FD_delim  * fd_delim;
46 FD_deco   * fd_deco;
47 FD_space  * fd_space;
48 FD_matrix * fd_matrix;
49
50 int delim_code[] = {   
51    '(', ')', LM_lceil,  LM_rceil,  LM_uparrow,  LM_Uparrow,
52    '[', ']', LM_lfloor,  LM_rfloor,  LM_updownarrow, LM_Updownarrow,
53    '{', '}',  '/', LM_backslash,  LM_downarrow,  LM_Downarrow,
54    LM_langle,  LM_rangle, '|', LM_Vert, '.', 0
55 };
56
57 // indexes to get the left and right versions of each delimiter
58 // Contributed by Pablo De Napoli (pdenapo@dm.uba.ar)
59 int delim_lversion[] = { 0,0,2,2,4,5,
60                          6,6,8,8,10,11,
61                          12,12,14,15,16,17,
62                          18,18,20,21,22,23 };
63
64 int delim_rversion[] = { 1,1,3,3,4,5,
65                         7,7,9,9,10,11,
66                         13,13,14,15,16,17,
67                         19,19,20,21,22,23 };
68
69
70 static char const * deco_code[] = {
71    "widehat", "widetilde", "overbrace", "overleftarrow", "overrightarrow", 
72    "overline", "underbrace", "underline"
73 };
74
75
76 static char const * func_code[] = {
77     "arccos", "arcsin", "arctan", "arg", "bmod",
78     "cos", "cosh", "cot", "coth", "csc", "deg",
79     "det", "dim", "exp", "gcd", "hom", "inf", "ker",
80     "lg", "lim", "liminf", "limsup", "ln", "log",
81     "max", "min", "sec", "sin", "sinh", "sup",
82     "tan", "tanh"
83 };
84
85 static char h_align_str[80] = "c";
86
87 /* callbacks for form panel */
88 void button_cb(FL_OBJECT * ob, long data)
89 {   
90    extern void free_symbols_form();
91    switch (data)  {
92     case MM_GREEK:
93     case MM_VARSIZE:
94     case MM_BRELATS:
95     case MM_ARROW:
96     case MM_BOP:
97     case MM_MISC: 
98       {    
99          BitmapMenu * menu = static_cast<BitmapMenu *>(ob->u_vdata);
100          menu->Show();  
101          break;
102       }
103     case MM_FRAC:
104        lyxfunc->Dispatch(LFUN_INSERT_MATH, "frac");
105       break;
106     case MM_SQRT:
107        lyxfunc->Dispatch(LFUN_INSERT_MATH, "sqrt");
108       break;
109     case MM_DELIM:
110       fl_show_form(fd_delim->delim, FL_PLACE_MOUSE, FL_FULLBORDER, _("Delimiter"));
111        fl_set_form_atclose(fd_delim->delim, CancelCloseBoxCB, 0);
112       break;
113     case MM_DECO:
114       fl_show_form(fd_deco->deco, FL_PLACE_MOUSE, FL_FULLBORDER, _("Decoration"));
115        fl_set_form_atclose(fd_deco->deco, CancelCloseBoxCB, 0);
116       break;
117     case MM_SPACE:
118       fl_show_form(fd_space->space, FL_PLACE_MOUSE, FL_FULLBORDER, _("Spacing"));
119        fl_set_form_atclose(fd_space->space, CancelCloseBoxCB, 0);
120       break;
121     case MM_MATRIX:
122       fl_show_form(fd_matrix->matrix, FL_PLACE_MOUSE, FL_FULLBORDER, _("Matrix"));
123        fl_set_form_atclose(fd_matrix->matrix, CancelCloseBoxCB, 0);
124       break;
125     case MM_EQU:
126        lyxfunc->Dispatch(LFUN_MATH_DISPLAY);
127       break;
128     case MM_FUNC:
129       {
130           int i = fl_get_browser(fd_panel->func_browse) - 1;
131           lyxfunc->Dispatch(LFUN_INSERT_MATH, func_code[i]);
132           break;
133       }
134     case 100:
135       free_symbols_form();
136       break;
137    }
138 }
139
140
141 /* callbacks for form delim */
142 void delim_cb(FL_OBJECT *, long data)
143 {
144    int left= fd_delim->left->u_ldata, right= fd_delim->right->u_ldata;
145    int side= (fl_get_button(fd_delim->right)!= 0);
146    Pixmap p1, p2;
147    
148    switch (data) {
149     case MM_APPLY:
150     case MM_OK:
151       {
152          char s[80];
153          sprintf(s, "%d %d", delim_code[left], delim_code[right]); 
154          lyxfunc->Dispatch(LFUN_MATH_DELIM, s);
155          if (data == MM_APPLY) break;
156       }
157     case MM_CLOSE: fl_hide_form(fd_delim->delim); break;
158     case 2: 
159       {
160           int i = fl_get_bmtable(fd_delim->menu);
161           int button = fl_get_bmtable_numb(fd_delim->menu);
162           bool both = (button==FL_MIDDLE_MOUSE);
163           
164           if (i>= 0) {
165
166               if (side || (button== FL_RIGHT_MOUSE)) {
167                   right = i;
168               } else {
169                   left = i;
170                   if (both)
171                     right = delim_rversion[i];
172               }   
173           }
174           p1 = fl_get_pixmap_pixmap(fd_delim->pix, &p1, &p2);
175           fl_draw_bmtable_item(fd_delim->menu, left, p1, 0, 0);
176           fl_draw_bmtable_item(fd_delim->menu, right, p1, 16, 0);
177           fl_redraw_object(fd_delim->pix);
178           
179           fd_delim->left->u_ldata = left;
180           fd_delim->right->u_ldata = right;
181
182           break;
183       }
184     case 3: break;
185     case 4: break;
186    }
187 }
188
189 /* callbacks for form matrix */
190 void matrix_cb(FL_OBJECT *, long data)
191 {
192    int nx, ny;
193    static char v_align_c[] = "tcb";
194  
195    switch (data) {
196     case MM_APPLY:
197     case MM_OK: 
198       {
199          char s[80];
200          char c = v_align_c[fl_get_choice(fd_matrix->valign)-1];
201          char const * sh = fl_get_input(fd_matrix->halign);
202          nx = int(fl_get_slider_value(fd_matrix->columns)+0.5);
203          ny = int(fl_get_slider_value(fd_matrix->rows)+0.5);
204          sprintf(s, "%d %d %c%s", nx, ny, c, sh);      
205          if (data == MM_OK) fl_hide_form(fd_matrix->matrix);
206          lyxfunc->Dispatch(LFUN_INSERT_MATRIX, s);
207          break;
208       }
209     case MM_CLOSE: fl_hide_form(fd_matrix->matrix); break;
210     case 2: 
211       {
212          nx = int(fl_get_slider_value(fd_matrix->columns)+0.5);
213          for (int i= 0; i<nx; i++) h_align_str[i] = 'c';
214          //memset(h_align_str, 'c', nx);
215          h_align_str[nx] = '\0';
216 //       fl_freeze_form(fd_form_main->form_main);
217 //      fl_addto_form(fd_form_main->form_main);
218
219          fl_set_input(fd_matrix->halign, h_align_str);  
220          fl_redraw_object(fd_matrix->halign);    
221          break;
222       }
223    }
224 }
225
226 /* callbacks for form deco */
227 void deco_cb(FL_OBJECT *, long data)
228 {
229    switch (data) {
230     case MM_APPLY:
231     case MM_OK:
232       { 
233          int i = fl_get_bmtable(fd_deco->menu);
234          lyxfunc->Dispatch(LFUN_INSERT_MATH, deco_code[i]);
235          if (data == MM_APPLY) break;
236       }
237     case MM_CLOSE: fl_hide_form(fd_deco->deco); break;
238    }
239 }
240
241
242 /* callbacks for form space */
243 void space_cb(FL_OBJECT *, long data)
244 {
245    static short sp = -1;
246    extern char * latex_mathspace[];
247    
248    if (data >= 0 && data < 6) 
249       sp = short(data);
250    else
251    switch (data) {
252     case MM_APPLY:
253     case MM_OK:
254       { 
255           if (sp>= 0) 
256             lyxfunc->Dispatch(LFUN_INSERT_MATH, latex_mathspace[sp]);
257          if (data == MM_APPLY) break;
258       }
259     case MM_CLOSE: fl_hide_form(fd_space->space); break;
260    }
261 }
262
263
264 extern "C" int align_filter(FL_OBJECT *, char const *, char const * cur, int c)
265 {
266    int n = int(fl_get_slider_value(fd_matrix->columns)+0.5) - strlen(cur);
267    return ((c == 'c'||c == 'l'||c == 'r') && n>= 0) ? FL_VALID: FL_INVALID;
268 }
269
270
271 char ** mathed_get_pixmap_from_icon(int d)
272 {
273    switch (d) {
274     case MM_FRAC: return frac;
275     case MM_SQRT: return sqrt;
276     case MM_DELIM: return delim;
277     case MM_MATRIX: return matrix;
278     case MM_EQU: return equation; 
279     case MM_DECO: return deco; 
280     case MM_SPACE: return space_xpm; 
281     default: return 0;
282    }
283 }
284
285
286 FD_panel * create_math_panel( )
287 {
288    fd_panel = create_form_panel();
289    fd_delim = create_form_delim();
290    fd_deco = create_form_deco();
291    fd_space = create_form_space();
292    fd_matrix = create_form_matrix();
293
294    /* fill-in form initialization code */
295    fl_set_button(fd_delim->left, 1);
296    fl_set_pixmap_data(fd_delim->pix, delim0);
297    fl_set_bmtable_data(fd_delim->menu, 6, 4, delim_width, delim_height,
298                        delim_bits);
299    fl_set_bmtable_maxitems(fd_delim->menu, 23);
300    
301    fl_set_pixmap_data(fd_panel->sqrt, sqrt);
302    fl_set_pixmap_data(fd_panel->frac, frac);
303    fl_set_pixmap_data(fd_panel->delim, delim);
304    fl_set_pixmap_data(fd_panel->deco, deco);
305    fl_set_pixmap_data(fd_panel->space, space_xpm);
306    fl_set_pixmap_data(fd_panel->matrix, matrix);
307    fl_set_pixmap_data(fd_panel->equation, equation);
308
309    for (int i= 0; i<32; i++) {
310        fl_add_browser_line(fd_panel->func_browse, func_code[i]);
311    }
312     
313    fl_addto_choice(fd_matrix->valign, _("Top | Center | Bottom"));
314    fl_set_choice(fd_matrix->valign, 2);
315    fl_set_input(fd_matrix->halign, h_align_str);
316    fl_set_input_filter(fd_matrix->halign, align_filter);
317    
318    fl_set_bmtable_data(fd_deco->menu, 3, 3, deco_width, deco_height,
319                        deco_bits);
320    fl_set_bmtable_maxitems(fd_deco->menu, 8);
321
322    fd_delim->left->u_ldata = 0;
323    fd_delim->right->u_ldata = 1;
324     
325    return fd_panel;
326 }
327
328 extern BitmapMenu* sym_menu;
329 extern void  create_symbol_menues(FD_panel *);
330
331
332 void free_symbols_form()
333 {
334    if (fd_panel) {
335       fl_hide_form(fd_panel->panel);
336       fl_free_form(fd_panel->panel);
337       delete sym_menu;
338       delete fd_panel;
339       fd_panel = 0;  
340    }
341 }
342
343
344 extern "C" int AtClose_symbols_form(FL_FORM *, void *)
345 {
346   free_symbols_form();
347   return FL_IGNORE;
348 }
349
350
351 void show_symbols_form(LyXFunc * lf)
352 {
353     lyxfunc = lf;
354     if (!fd_panel) {
355         fd_panel = create_math_panel();
356         fl_register_raw_callback(fd_panel->panel, 
357                                  ButtonPressMask|KeyPressMask, C_peek_event);
358         create_symbol_menues(fd_panel); 
359         fl_set_form_atclose(fd_panel->panel, AtClose_symbols_form, 0);
360     }
361     if (fd_panel->panel->visible) {
362         fl_raise_form(fd_panel->panel);
363     } else {
364       fl_show_form(fd_panel->panel, FL_PLACE_MOUSE,
365                    FL_FULLBORDER, _("Math Panel"));
366     }
367 }