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