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