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: 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"
40 #include "math_panel.h"
41 #include "math_parser.h"
43 extern short greek_kb_flag;
45 extern BufferView * current_view;
56 /* Latex code for those bitmaps */
57 static char const * latex_greek[] = {
58 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
59 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
60 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
61 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
62 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
63 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
66 static char const * latex_brel[] = {
67 "leq", "geq", "equiv", "models",
68 "prec", "succ", "sim", "perp",
69 "preceq", "succeq", "simeq", "mid",
70 "ll", "gg", "asymp", "parallel",
71 "subset", "supset", "approx", "smile",
72 "subseteq", "supseteq", "cong", "frown",
73 "sqsubseteq", "sqsupseteq", "doteq", "neq",
74 "in", "ni", "propto", "notin",
75 "vdash", "dashv", "bowtie", ""
78 static char const * latex_arrow[] = {
79 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
80 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
81 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
82 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
83 "leftharpoondown", "rightharpoondown", "mapsto",
84 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
85 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
86 "nwarrow", "nearrow", "swarrow", "searrow", "",
89 char const * latex_varsz[] = {
91 "prod", "coprod", "bigsqcup",
92 "bigotimes", "bigodot", "bigoplus",
93 "bigcap", "bigcup", "biguplus",
94 "bigvee", "bigwedge", ""
97 static char const * latex_bop[] = {
98 "pm", "cap", "diamond", "oplus",
99 "mp", "cup", "bigtriangleup", "ominus",
100 "times", "uplus", "bigtriangledown", "otimes",
101 "div", "sqcap", "triangleright", "oslash",
102 "cdot", "sqcup", "triangleleft", "odot",
103 "star", "vee", "amalg", "bigcirc",
104 "setminus", "wedge", "dagger", "circ",
105 "bullet", "wr", "ddagger", ""
108 static char const * latex_misc[] = {
109 "nabla", "partial", "infty", "prime", "ell",
110 "emptyset", "exists", "forall", "imath", "jmath",
111 "Re", "Im", "aleph", "wp", "hbar",
112 "angle", "top", "bot", "Vert", "neg",
113 "flat", "natural", "sharp", "surd", "triangle",
114 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
117 static char const * latex_dots[] = {
118 "ldots", "cdots", "vdots", "ddots"
121 static signed char latin2greek[] = {
122 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
123 19, 21, 22, 17, 27, 15, 26, 6
126 static signed char Latin2Greek[] = {
127 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
128 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
131 extern char const ** mathed_get_pixmap_from_icon(int d);
132 extern "C" void math_cb(FL_OBJECT*, long);
133 static char const ** pixmapFromBitmapData(char const *, int, int);
134 void math_insert_symbol(char const * s);
135 Bool math_insert_greek(char const c);
137 BitmapMenu * BitmapMenu::active = 0;
139 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
144 ww = 2 * FL_abs(FL_BOUND_WIDTH);
147 bitmap = new FL_OBJECTP[nb];
149 button->u_vdata = this;
157 BitmapMenu::~BitmapMenu()
160 if (form->visible) Hide();
166 void BitmapMenu::Hide()
169 fl_set_button(button, 0);
174 void BitmapMenu::Show()
179 // int x = button->form->x + button->x, y = button->form->y + button->y;
180 // fl_set_form_position(form, x, y + button->h);
181 fl_set_button(button, 1);
182 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
186 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
190 int wx = bw+ww/2, wy = bh+ww/2;
193 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
194 fl_set_object_callback(obj, math_cb, id);
195 fl_set_object_lcol(obj, FL_BLUE);
196 fl_set_object_boxtype(obj, FL_UP_BOX);
197 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
201 w = max(x + wx + ww, w);
205 h = max(y + wy + ww, h);
211 void BitmapMenu::Create()
214 lyxerr << "Error: Bitmaps not created!" << endl;
217 form = fl_bgn_form(FL_UP_BOX, w, h);
218 for (i = 0; i < nb; ++i) {
219 fl_add_object(form, bitmap[i]);
220 bitmap[i]->u_vdata = this;
223 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
226 int BitmapMenu::GetIndex(FL_OBJECT* ob)
228 if (active == this) {
230 for (i = 0; i < nb; ++i) {
232 return k+fl_get_bmtable(ob);
233 k += fl_get_bmtable_maxitems(bitmap[i]);
239 int peek_event(FL_FORM * /*form*/, void *xev)
241 if (BitmapMenu::active == 0)
244 if(static_cast<XEvent *>(xev)->type == ButtonPress)
246 BitmapMenu::active->Hide();
249 if(static_cast<XEvent *>(xev)->type == KeyPress)
253 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
254 if (keysym == XK_Left)
255 BitmapMenu::active->Prev(); else
256 if (keysym == XK_Right)
257 BitmapMenu::active->Next();
259 BitmapMenu::active->Hide();
265 // This is just a wrapper.
266 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
267 return peek_event(form, ptr);
271 extern "C" void math_cb(FL_OBJECT* ob, long data)
273 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
274 int i = menu->GetIndex(ob);
277 // lyxerr << "data[" << data << "]";
299 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
300 s = latex_dots[i-29];
305 if (current_view->available() && lyxrc.display_shortcuts) {
306 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
308 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
314 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
316 char const ** data = 0;
317 latexkeys * l = in_word_set (arg, strlen(arg));
323 data = mathed_get_pixmap_from_icon(MM_FRAC);
326 data = mathed_get_pixmap_from_icon(MM_SQRT);
330 // I have to use directly the bitmap data since the
331 // bitmap tables are not yet created when this
332 // function is called.
333 data = pixmapFromBitmapData(arg, wx, hx);
340 Bool math_insert_greek(char const c)
345 if ('A' <= c && c <= 'Z') {
346 if ((i = Latin2Greek[c - 'A']) >= 0)
349 if ('a'<= c && c<= 'z') {
350 if ((i= latin2greek[c - 'a'])>= 0)
351 s = latex_greek[i+11];
354 math_insert_symbol(s);
355 if (greek_kb_flag<2) {
357 current_view->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->insertInset(new_inset);
373 new_inset->Edit(current_view, 0, 0, 0);
374 new_inset->InsertSymbol(current_view, s);
376 if (current_view->the_locking_inset->LyxCode() == Inset::MATH_CODE)
377 static_cast<InsetFormula*>(current_view->the_locking_inset)->InsertSymbol(current_view, s);
379 lyxerr << "Math error: attempt to write on a wrong "
380 "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);