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