3 * Purpose: User interface to math symbols
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: November 1995
6 * Version: 0.8 28/03/96
7 * Description: Provides a GUI to introduce mathematical
10 * Dependencies: Xlib, XForms, Lyx
12 * Copyright: (c) 1995, 1996, Alejandro Aguilar Sierra
14 * You are free to use and modify it under the terms of
15 * the GNU General Public Licence version 2 or later.
19 #include XPM_H_LOCATION
22 #pragma implementation "math_panel.h"
30 #include "BufferView.h"
31 #include "minibuffer.h"
34 #include "support/lstrings.h"
39 #include "math_panel.h"
40 #include "math_parser.h"
42 extern void Update(signed char);
43 extern int UnlockInset(UpdatableInset *);
44 extern short greek_kb_flag;
46 extern BufferView * current_view;
57 /* Latex code for those bitmaps */
58 static char const * latex_greek[] = {
59 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
60 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
61 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
62 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
63 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
64 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
67 static char const * latex_brel[] = {
68 "leq", "geq", "equiv", "models",
69 "prec", "succ", "sim", "perp",
70 "preceq", "succeq", "simeq", "mid",
71 "ll", "gg", "asymp", "parallel",
72 "subset", "supset", "approx", "smile",
73 "subseteq", "supseteq", "cong", "frown",
74 "sqsubseteq", "sqsupseteq", "doteq", "neq",
75 "in", "ni", "propto", "notin",
76 "vdash", "dashv", "bowtie", ""
79 static char const * latex_arrow[] = {
80 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
81 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
82 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
83 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
84 "leftharpoondown", "rightharpoondown", "mapsto",
85 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
86 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
87 "nwarrow", "nearrow", "swarrow", "searrow", "",
90 char const * latex_varsz[] = {
92 "prod", "coprod", "bigsqcup",
93 "bigotimes", "bigodot", "bigoplus",
94 "bigcap", "bigcup", "biguplus",
95 "bigvee", "bigwedge", ""
98 static char const * latex_bop[] = {
99 "pm", "cap", "diamond", "oplus",
100 "mp", "cup", "bigtriangleup", "ominus",
101 "times", "uplus", "bigtriangledown", "otimes",
102 "div", "sqcap", "triangleright", "oslash",
103 "cdot", "sqcup", "triangleleft", "odot",
104 "star", "vee", "amalg", "bigcirc",
105 "setminus", "wedge", "dagger", "circ",
106 "bullet", "wr", "ddagger", ""
109 static char const * latex_misc[] = {
110 "nabla", "partial", "infty", "prime", "ell",
111 "emptyset", "exists", "forall", "imath", "jmath",
112 "Re", "Im", "aleph", "wp", "hbar",
113 "angle", "top", "bot", "Vert", "neg",
114 "flat", "natural", "sharp", "surd", "triangle",
115 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
118 static char const * latex_dots[] = {
119 "ldots", "cdots", "vdots", "ddots"
122 static signed char latin2greek[] = {
123 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
124 19, 21, 22, 17, 27, 15, 26, 6
127 static signed char Latin2Greek[] = {
128 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
129 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
132 extern char const ** mathed_get_pixmap_from_icon(int d);
133 extern "C" void math_cb(FL_OBJECT*, long);
134 static char const ** pixmapFromBitmapData(char const *, int, int);
135 void math_insert_symbol(char const * s);
136 Bool math_insert_greek(char const c);
138 BitmapMenu * BitmapMenu::active = 0;
140 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
145 ww = 2 * FL_abs(FL_BOUND_WIDTH);
148 bitmap = new FL_OBJECTP[nb];
150 button->u_vdata = this;
158 BitmapMenu::~BitmapMenu()
160 if (next) delete next;
161 if (form->visible) Hide();
167 void BitmapMenu::Hide()
170 fl_set_button(button, 0);
175 void BitmapMenu::Show()
180 // int x = button->form->x + button->x, y = button->form->y + button->y;
181 // fl_set_form_position(form, x, y + button->h);
182 fl_set_button(button, 1);
183 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
187 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
191 int wx = bw+ww/2, wy = bh+ww/2;
194 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
195 fl_set_object_callback(obj, math_cb, id);
196 fl_set_object_lcol(obj, FL_BLUE);
197 fl_set_object_boxtype(obj, FL_UP_BOX);
198 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
202 w = max(x + wx + ww, w);
206 h = max(y + wy + ww, h);
212 void BitmapMenu::Create()
215 lyxerr << "Error: Bitmaps not created!" << endl;
218 form = fl_bgn_form(FL_UP_BOX, w, h);
219 for (i= 0; i<nb; i++) {
220 fl_add_object(form, bitmap[i]);
221 bitmap[i]->u_vdata = this;
224 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
227 int BitmapMenu::GetIndex(FL_OBJECT* ob)
229 if (active == this) {
231 for (i= 0; i<nb; i++) {
233 return k+fl_get_bmtable(ob);
234 k += fl_get_bmtable_maxitems(bitmap[i]);
240 int peek_event(FL_FORM * /*form*/, void *xev)
242 if (BitmapMenu::active == 0)
245 if(static_cast<XEvent *>(xev)->type == ButtonPress)
247 BitmapMenu::active->Hide();
250 if(static_cast<XEvent *>(xev)->type == KeyPress)
254 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
255 if (keysym == XK_Left)
256 BitmapMenu::active->Prev(); else
257 if (keysym == XK_Right)
258 BitmapMenu::active->Next();
260 BitmapMenu::active->Hide();
266 // This is just a wrapper.
267 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
268 return peek_event(form, ptr);
272 extern "C" void math_cb(FL_OBJECT* ob, long data)
274 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
275 int i = menu->GetIndex(ob);
278 // lyxerr << "data[" << data << "]";
300 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
301 s = latex_dots[i-29];
306 if (current_view->available() && lyxrc->display_shortcuts) {
307 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
309 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
315 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
317 char const ** data = 0;
318 latexkeys * l = in_word_set (arg, strlen(arg));
324 data = mathed_get_pixmap_from_icon(MM_FRAC);
327 data = mathed_get_pixmap_from_icon(MM_SQRT);
331 // I have to use directly the bitmap data since the
332 // bitmap tables are not yet created when this
333 // function is called.
334 data = pixmapFromBitmapData(arg, wx, hx);
341 Bool math_insert_greek(char const c)
346 if ('A' <= c && c <= 'Z') {
347 if ((i = Latin2Greek[c - 'A']) >= 0)
350 if ('a'<= c && c<= 'z') {
351 if ((i= latin2greek[c - 'a'])>= 0)
352 s = latex_greek[i+11];
355 math_insert_symbol(s);
356 if (greek_kb_flag<2) {
358 UnlockInset(current_view->the_locking_inset);
365 void math_insert_symbol(char const* s)
367 if (current_view->available()) {
368 if (!current_view->the_locking_inset) {
369 InsetFormula * new_inset = new InsetFormula();
370 current_view->beforeChange();
371 current_view->buffer()->insertInset(new_inset);
373 new_inset->Edit(0, 0);
374 new_inset->InsertSymbol(s);
376 if (current_view->the_locking_inset->LyxCode() == Inset::MATH_CODE)
377 static_cast<InsetFormula*>(current_view->the_locking_inset)->InsertSymbol(s);
379 lyxerr << "Math error: attempt to write on a wrong "
380 "class of inset." << endl;
384 BitmapMenu * sym_menu= 0;
386 void create_symbol_menues(FD_panel * symb_form)
391 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
392 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
394 fl_set_bmtable_maxitems(obj, 11);
395 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
399 menu = new BitmapMenu(1, symb_form->boperator, menu);
400 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
402 fl_set_bmtable_maxitems(obj, 31);
405 menu = new BitmapMenu(1, symb_form->brelats, menu);
406 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
408 fl_set_bmtable_maxitems(obj, 35);
411 menu = new BitmapMenu(3, symb_form->arrow, menu);
412 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
414 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
416 fl_set_bmtable_maxitems(obj, 7);
417 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
421 menu = new BitmapMenu(1, symb_form->varsize, menu);
422 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
424 fl_set_bmtable_maxitems(obj, 14);
427 menu = new BitmapMenu(2, symb_form->misc, menu);
428 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
430 fl_set_bmtable_maxitems(obj, 29);
431 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
437 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
440 char const ** data = 0;
444 for (i = 0; i < 6; ++i) {
445 char const ** latex_str = 0;
447 case 0: latex_str = latex_greek; break;
448 case 1: latex_str = latex_bop; break;
449 case 2: latex_str = latex_brel; break;
450 case 3: latex_str = latex_arrow; break;
451 case 4: latex_str = latex_varsz; break;
452 case 5: latex_str = latex_misc; break;
455 for (int k = 0; latex_str[k][0]>' '; k++) {
456 if (strcmp(latex_str[k], s) == 0) {
463 if (i < 6 && id >= 0) {
464 unsigned char const * bdata = 0;
465 int w = 0, h = 0, dw = 0, dh = 0;
467 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
528 int ww = w/dw, hh = h/dh, x, y;
530 XImage * xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
531 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
532 xima->byte_order = LSBFirst;
533 xima->bitmap_bit_order = LSBFirst;
536 if (ww > wx) ww = wx;
537 if (hh > hx) hh = hx;
538 XImage * sbima = XSubImage(xima, x, y, ww, hh);
539 XpmCreateDataFromImage(fl_display, const_cast<char***>(&data), sbima, sbima, 0);
541 // Dirty hack to get blue symbols quickly
542 char * sx = strstr(data[2], "FFFFFFFF");
544 for (int k = 0; k < 8; ++k) sx[k] = '0';
547 // XDestroyImage(xima);