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 BeforeChange();
43 extern void Update(signed char);
44 extern int UnlockInset(UpdatableInset *);
45 extern short greek_kb_flag;
47 extern BufferView * current_view;
58 /* Latex code for those bitmaps */
59 static char const * latex_greek[] = {
60 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
61 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
62 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
63 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
64 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
65 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
68 static char const * latex_brel[] = {
69 "leq", "geq", "equiv", "models",
70 "prec", "succ", "sim", "perp",
71 "preceq", "succeq", "simeq", "mid",
72 "ll", "gg", "asymp", "parallel",
73 "subset", "supset", "approx", "smile",
74 "subseteq", "supseteq", "cong", "frown",
75 "sqsubseteq", "sqsupseteq", "doteq", "neq",
76 "in", "ni", "propto", "notin",
77 "vdash", "dashv", "bowtie", ""
80 static char const * latex_arrow[] = {
81 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
82 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
83 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
84 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
85 "leftharpoondown", "rightharpoondown", "mapsto",
86 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
87 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
88 "nwarrow", "nearrow", "swarrow", "searrow", "",
91 char const * latex_varsz[] = {
93 "prod", "coprod", "bigsqcup",
94 "bigotimes", "bigodot", "bigoplus",
95 "bigcap", "bigcup", "biguplus",
96 "bigvee", "bigwedge", ""
99 static char const * latex_bop[] = {
100 "pm", "cap", "diamond", "oplus",
101 "mp", "cup", "bigtriangleup", "ominus",
102 "times", "uplus", "bigtriangledown", "otimes",
103 "div", "sqcap", "triangleright", "oslash",
104 "cdot", "sqcup", "triangleleft", "odot",
105 "star", "vee", "amalg", "bigcirc",
106 "setminus", "wedge", "dagger", "circ",
107 "bullet", "wr", "ddagger", ""
110 static char const * latex_misc[] = {
111 "nabla", "partial", "infty", "prime", "ell",
112 "emptyset", "exists", "forall", "imath", "jmath",
113 "Re", "Im", "aleph", "wp", "hbar",
114 "angle", "top", "bot", "Vert", "neg",
115 "flat", "natural", "sharp", "surd", "triangle",
116 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
119 static char const * latex_dots[] = {
120 "ldots", "cdots", "vdots", "ddots"
123 static signed char latin2greek[] = {
124 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
125 19, 21, 22, 17, 27, 15, 26, 6
128 static signed char Latin2Greek[] = {
129 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
130 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
133 extern char const ** mathed_get_pixmap_from_icon(int d);
134 extern "C" void math_cb(FL_OBJECT*, long);
135 static char const ** pixmapFromBitmapData(char const *, int, int);
136 void math_insert_symbol(char const * s);
137 Bool math_insert_greek(char const c);
139 BitmapMenu * BitmapMenu::active = 0;
141 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
146 ww = 2 * FL_abs(FL_BOUND_WIDTH);
149 bitmap = new FL_OBJECTP[nb];
151 button->u_vdata = this;
159 BitmapMenu::~BitmapMenu()
161 if (next) delete next;
162 if (form->visible) Hide();
168 void BitmapMenu::Hide()
171 fl_set_button(button, 0);
176 void BitmapMenu::Show()
181 // int x = button->form->x + button->x, y = button->form->y + button->y;
182 // fl_set_form_position(form, x, y + button->h);
183 fl_set_button(button, 1);
184 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
188 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
192 int wx = bw+ww/2, wy = bh+ww/2;
195 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
196 fl_set_object_callback(obj, math_cb, id);
197 fl_set_object_lcol(obj, FL_BLUE);
198 fl_set_object_boxtype(obj, FL_UP_BOX);
199 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
203 w = max(x + wx + ww, w);
207 h = max(y + wy + ww, h);
213 void BitmapMenu::Create()
216 lyxerr << "Error: Bitmaps not created!" << endl;
219 form = fl_bgn_form(FL_UP_BOX, w, h);
220 for (i= 0; i<nb; i++) {
221 fl_add_object(form, bitmap[i]);
222 bitmap[i]->u_vdata = this;
225 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
228 int BitmapMenu::GetIndex(FL_OBJECT* ob)
230 if (active == this) {
232 for (i= 0; i<nb; i++) {
234 return k+fl_get_bmtable(ob);
235 k += fl_get_bmtable_maxitems(bitmap[i]);
241 int peek_event(FL_FORM * /*form*/, void *xev)
243 if (BitmapMenu::active == 0)
246 if(static_cast<XEvent *>(xev)->type == ButtonPress)
248 BitmapMenu::active->Hide();
251 if(static_cast<XEvent *>(xev)->type == KeyPress)
255 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
256 if (keysym == XK_Left)
257 BitmapMenu::active->Prev(); else
258 if (keysym == XK_Right)
259 BitmapMenu::active->Next();
261 BitmapMenu::active->Hide();
267 // This is just a wrapper.
268 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
269 return peek_event(form, ptr);
273 extern "C" void math_cb(FL_OBJECT* ob, long data)
275 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
276 int i = menu->GetIndex(ob);
279 // lyxerr << "data[" << data << "]";
301 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
302 s = latex_dots[i-29];
307 if (current_view->available() && lyxrc->display_shortcuts) {
308 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
310 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
316 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
318 char const ** data = 0;
319 latexkeys * l = in_word_set (arg, strlen(arg));
325 data = mathed_get_pixmap_from_icon(MM_FRAC);
328 data = mathed_get_pixmap_from_icon(MM_SQRT);
332 // I have to use directly the bitmap data since the
333 // bitmap tables are not yet created when this
334 // function is called.
335 data = pixmapFromBitmapData(arg, wx, hx);
342 Bool math_insert_greek(char const c)
347 if ('A' <= c && c <= 'Z') {
348 if ((i = Latin2Greek[c - 'A']) >= 0)
351 if ('a'<= c && c<= 'z') {
352 if ((i= latin2greek[c - 'a'])>= 0)
353 s = latex_greek[i+11];
356 math_insert_symbol(s);
357 if (greek_kb_flag<2) {
359 UnlockInset(current_view->buffer()->the_locking_inset);
366 void math_insert_symbol(char const* s)
368 if (current_view->available()) {
369 if (!current_view->buffer()->the_locking_inset) {
370 InsetFormula * new_inset = new InsetFormula();
372 current_view->buffer()->insertInset(new_inset);
374 new_inset->Edit(0, 0);
375 new_inset->InsertSymbol(s);
377 if (current_view->buffer()->the_locking_inset->LyxCode() == Inset::MATH_CODE)
378 static_cast<InsetFormula*>(current_view->buffer()->the_locking_inset)->InsertSymbol(s);
380 lyxerr << "Math error: attempt to write on a wrong "
381 "class of inset." << endl;
385 BitmapMenu * sym_menu= 0;
387 void create_symbol_menues(FD_panel * symb_form)
392 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
393 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
395 fl_set_bmtable_maxitems(obj, 11);
396 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
400 menu = new BitmapMenu(1, symb_form->boperator, menu);
401 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
403 fl_set_bmtable_maxitems(obj, 31);
406 menu = new BitmapMenu(1, symb_form->brelats, menu);
407 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
409 fl_set_bmtable_maxitems(obj, 35);
412 menu = new BitmapMenu(3, symb_form->arrow, menu);
413 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
415 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
417 fl_set_bmtable_maxitems(obj, 7);
418 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
422 menu = new BitmapMenu(1, symb_form->varsize, menu);
423 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
425 fl_set_bmtable_maxitems(obj, 14);
428 menu = new BitmapMenu(2, symb_form->misc, menu);
429 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
431 fl_set_bmtable_maxitems(obj, 29);
432 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
438 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
441 char const ** data = 0;
445 for (i = 0; i < 6; ++i) {
446 char const ** latex_str = 0;
448 case 0: latex_str = latex_greek; break;
449 case 1: latex_str = latex_bop; break;
450 case 2: latex_str = latex_brel; break;
451 case 3: latex_str = latex_arrow; break;
452 case 4: latex_str = latex_varsz; break;
453 case 5: latex_str = latex_misc; break;
456 for (int k = 0; latex_str[k][0]>' '; k++) {
457 if (strcmp(latex_str[k], s) == 0) {
464 if (i < 6 && id >= 0) {
465 unsigned char const * bdata = 0;
466 int w = 0, h = 0, dw = 0, dh = 0;
468 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
529 int ww = w/dw, hh = h/dh, x, y;
531 XImage * xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
532 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
533 xima->byte_order = LSBFirst;
534 xima->bitmap_bit_order = LSBFirst;
537 if (ww > wx) ww = wx;
538 if (hh > hx) hh = hx;
539 XImage * sbima = XSubImage(xima, x, y, ww, hh);
540 XpmCreateDataFromImage(fl_display, const_cast<char***>(&data), sbima, sbima, 0);
542 // Dirty hack to get blue symbols quickly
543 char * sx = strstr(data[2], "FFFFFFFF");
545 for (int k = 0; k < 8; ++k) sx[k] = '0';
548 // XDestroyImage(xima);