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"
39 #include "math_panel.h"
40 #include "math_parser.h"
42 extern short greek_kb_flag;
44 extern BufferView * current_view;
55 /* Latex code for those bitmaps */
56 static char const * latex_greek[] = {
57 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
58 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
59 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
60 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
61 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
62 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
65 static char const * latex_brel[] = {
66 "leq", "geq", "equiv", "models",
67 "prec", "succ", "sim", "perp",
68 "preceq", "succeq", "simeq", "mid",
69 "ll", "gg", "asymp", "parallel",
70 "subset", "supset", "approx", "smile",
71 "subseteq", "supseteq", "cong", "frown",
72 "sqsubseteq", "sqsupseteq", "doteq", "neq",
73 "in", "ni", "propto", "notin",
74 "vdash", "dashv", "bowtie", ""
77 static char const * latex_arrow[] = {
78 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
79 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
80 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
81 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
82 "leftharpoondown", "rightharpoondown", "mapsto",
83 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
84 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
85 "nwarrow", "nearrow", "swarrow", "searrow", "",
88 char const * latex_varsz[] = {
90 "prod", "coprod", "bigsqcup",
91 "bigotimes", "bigodot", "bigoplus",
92 "bigcap", "bigcup", "biguplus",
93 "bigvee", "bigwedge", ""
96 static char const * latex_bop[] = {
97 "pm", "cap", "diamond", "oplus",
98 "mp", "cup", "bigtriangleup", "ominus",
99 "times", "uplus", "bigtriangledown", "otimes",
100 "div", "sqcap", "triangleright", "oslash",
101 "cdot", "sqcup", "triangleleft", "odot",
102 "star", "vee", "amalg", "bigcirc",
103 "setminus", "wedge", "dagger", "circ",
104 "bullet", "wr", "ddagger", ""
107 static char const * latex_misc[] = {
108 "nabla", "partial", "infty", "prime", "ell",
109 "emptyset", "exists", "forall", "imath", "jmath",
110 "Re", "Im", "aleph", "wp", "hbar",
111 "angle", "top", "bot", "Vert", "neg",
112 "flat", "natural", "sharp", "surd", "triangle",
113 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
116 static char const * latex_dots[] = {
117 "ldots", "cdots", "vdots", "ddots"
120 static signed char latin2greek[] = {
121 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
122 19, 21, 22, 17, 27, 15, 26, 6
125 static signed char Latin2Greek[] = {
126 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
127 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
130 extern char const ** mathed_get_pixmap_from_icon(int d);
131 extern "C" void math_cb(FL_OBJECT*, long);
132 static char const ** pixmapFromBitmapData(char const *, int, int);
133 void math_insert_symbol(char const * s);
134 Bool math_insert_greek(char const c);
136 BitmapMenu * BitmapMenu::active = 0;
138 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
143 ww = 2 * FL_abs(FL_BOUND_WIDTH);
146 bitmap = new FL_OBJECTP[nb];
148 button->u_vdata = this;
156 BitmapMenu::~BitmapMenu()
159 if (form->visible) Hide();
165 void BitmapMenu::Hide()
168 fl_set_button(button, 0);
173 void BitmapMenu::Show()
178 // int x = button->form->x + button->x, y = button->form->y + button->y;
179 // fl_set_form_position(form, x, y + button->h);
180 fl_set_button(button, 1);
181 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
185 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
189 int wx = bw+ww/2, wy = bh+ww/2;
192 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
193 fl_set_object_callback(obj, math_cb, id);
194 fl_set_object_lcol(obj, FL_BLUE);
195 fl_set_object_boxtype(obj, FL_UP_BOX);
196 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
200 w = max(x + wx + ww, w);
204 h = max(y + wy + ww, h);
210 void BitmapMenu::Create()
213 lyxerr << "Error: Bitmaps not created!" << endl;
216 form = fl_bgn_form(FL_UP_BOX, w, h);
217 for (i = 0; i < nb; ++i) {
218 fl_add_object(form, bitmap[i]);
219 bitmap[i]->u_vdata = this;
222 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
225 int BitmapMenu::GetIndex(FL_OBJECT* ob)
227 if (active == this) {
229 for (i = 0; i < nb; ++i) {
231 return k+fl_get_bmtable(ob);
232 k += fl_get_bmtable_maxitems(bitmap[i]);
238 int peek_event(FL_FORM * /*form*/, void *xev)
240 if (BitmapMenu::active == 0)
243 if(static_cast<XEvent *>(xev)->type == ButtonPress)
245 BitmapMenu::active->Hide();
248 if(static_cast<XEvent *>(xev)->type == KeyPress)
252 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
253 if (keysym == XK_Left)
254 BitmapMenu::active->Prev(); else
255 if (keysym == XK_Right)
256 BitmapMenu::active->Next();
258 BitmapMenu::active->Hide();
264 // This is just a wrapper.
265 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
266 return peek_event(form, ptr);
270 extern "C" void math_cb(FL_OBJECT* ob, long data)
272 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
273 int i = menu->GetIndex(ob);
276 // lyxerr << "data[" << data << "]";
298 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
299 s = latex_dots[i-29];
304 if (current_view->available() && lyxrc->display_shortcuts) {
305 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
307 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
313 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
315 char const ** data = 0;
316 latexkeys * l = in_word_set (arg, strlen(arg));
322 data = mathed_get_pixmap_from_icon(MM_FRAC);
325 data = mathed_get_pixmap_from_icon(MM_SQRT);
329 // I have to use directly the bitmap data since the
330 // bitmap tables are not yet created when this
331 // function is called.
332 data = pixmapFromBitmapData(arg, wx, hx);
339 Bool math_insert_greek(char const c)
344 if ('A' <= c && c <= 'Z') {
345 if ((i = Latin2Greek[c - 'A']) >= 0)
348 if ('a'<= c && c<= 'z') {
349 if ((i= latin2greek[c - 'a'])>= 0)
350 s = latex_greek[i+11];
353 math_insert_symbol(s);
354 if (greek_kb_flag<2) {
356 current_view->unlockInset(current_view->the_locking_inset);
364 void math_insert_symbol(char const * s)
366 if (current_view->available()) {
367 if (!current_view->the_locking_inset) {
368 InsetFormula * new_inset = new InsetFormula();
369 current_view->beforeChange();
370 current_view->insertInset(new_inset);
372 new_inset->Edit(current_view, 0, 0, 0);
373 new_inset->InsertSymbol(current_view, s);
375 if (current_view->the_locking_inset->LyxCode() == Inset::MATH_CODE)
376 static_cast<InsetFormula*>(current_view->the_locking_inset)->InsertSymbol(current_view, s);
378 lyxerr << "Math error: attempt to write on a wrong "
379 "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);