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"
29 #include "BufferView.h"
30 #include "minibuffer.h"
33 #include "support/lstrings.h"
39 #include "math_panel.h"
40 #include "math_parser.h"
46 extern int greek_kb_flag;
48 extern BufferView * current_view;
59 /* Latex code for those bitmaps */
60 static char const * latex_greek[] = {
61 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
62 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
63 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
64 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
65 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
66 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
69 static char const * latex_brel[] = {
70 "leq", "geq", "equiv", "models",
71 "prec", "succ", "sim", "perp",
72 "preceq", "succeq", "simeq", "mid",
73 "ll", "gg", "asymp", "parallel",
74 "subset", "supset", "approx", "smile",
75 "subseteq", "supseteq", "cong", "frown",
76 "sqsubseteq", "sqsupseteq", "doteq", "neq",
77 "in", "ni", "propto", "notin",
78 "vdash", "dashv", "bowtie", ""
81 static char const * latex_arrow[] = {
82 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
83 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
84 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
85 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
86 "leftharpoondown", "rightharpoondown", "mapsto",
87 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
88 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
89 "nwarrow", "nearrow", "swarrow", "searrow", "",
92 char const * latex_varsz[] = {
94 "prod", "coprod", "bigsqcup",
95 "bigotimes", "bigodot", "bigoplus",
96 "bigcap", "bigcup", "biguplus",
97 "bigvee", "bigwedge", ""
100 static char const * latex_bop[] = {
101 "pm", "cap", "diamond", "oplus",
102 "mp", "cup", "bigtriangleup", "ominus",
103 "times", "uplus", "bigtriangledown", "otimes",
104 "div", "sqcap", "triangleright", "oslash",
105 "cdot", "sqcup", "triangleleft", "odot",
106 "star", "vee", "amalg", "bigcirc",
107 "setminus", "wedge", "dagger", "circ",
108 "bullet", "wr", "ddagger", ""
111 static char const * latex_misc[] = {
112 "nabla", "partial", "infty", "prime", "ell",
113 "emptyset", "exists", "forall", "imath", "jmath",
114 "Re", "Im", "aleph", "wp", "hbar",
115 "angle", "top", "bot", "Vert", "neg",
116 "flat", "natural", "sharp", "surd", "triangle",
117 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
120 static char const * latex_dots[] = {
121 "ldots", "cdots", "vdots", "ddots"
124 extern char const ** mathed_get_pixmap_from_icon(int d);
125 extern "C" void math_cb(FL_OBJECT*, long);
126 static char const ** pixmapFromBitmapData(char const *, int, int);
127 void math_insert_symbol(char const * s);
128 bool math_insert_greek(char c);
130 BitmapMenu * BitmapMenu::active = 0;
132 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
137 ww = 2 * FL_abs(FL_BOUND_WIDTH);
140 bitmap = new FL_OBJECTP[nb];
142 button->u_vdata = this;
150 BitmapMenu::~BitmapMenu()
153 if (form->visible) Hide();
159 void BitmapMenu::Hide()
162 fl_set_button(button, 0);
167 void BitmapMenu::Show()
172 // int x = button->form->x + button->x, y = button->form->y + button->y;
173 // fl_set_form_position(form, x, y + button->h);
174 fl_set_button(button, 1);
175 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
179 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh,
180 unsigned char const * data, Bool vert)
184 int wx = bw+ww/2, wy = bh+ww/2;
187 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
188 fl_set_object_callback(obj, math_cb, id);
189 fl_set_object_lcol(obj, FL_BLUE);
190 fl_set_object_boxtype(obj, FL_UP_BOX);
191 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
195 w = max(x + wx + ww, w);
199 h = max(y + wy + ww, h);
205 void BitmapMenu::Create()
208 lyxerr << "Error: Bitmaps not created!" << endl;
211 form = fl_bgn_form(FL_UP_BOX, w, h);
212 for (i = 0; i < nb; ++i) {
213 fl_add_object(form, bitmap[i]);
214 bitmap[i]->u_vdata = this;
217 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
220 int BitmapMenu::GetIndex(FL_OBJECT* ob)
222 if (active == this) {
224 for (i = 0; i < nb; ++i) {
226 return k+fl_get_bmtable(ob);
227 k += fl_get_bmtable_maxitems(bitmap[i]);
233 int peek_event(FL_FORM * /*form*/, void *xev)
235 if (BitmapMenu::active == 0)
238 if (static_cast<XEvent *>(xev)->type == ButtonPress)
240 BitmapMenu::active->Hide();
243 if (static_cast<XEvent *>(xev)->type == KeyPress)
247 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
248 if (keysym == XK_Left)
249 BitmapMenu::active->Prev(); else
250 if (keysym == XK_Right)
251 BitmapMenu::active->Next();
253 BitmapMenu::active->Hide();
259 // This is just a wrapper.
260 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
261 return peek_event(form, ptr);
265 extern "C" void math_cb(FL_OBJECT* ob, long data)
267 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
268 int i = menu->GetIndex(ob);
271 // lyxerr << "data[" << data << "]";
293 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
294 s = latex_dots[i-29];
299 if (current_view->available() && lyxrc.display_shortcuts) {
300 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
302 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
308 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
310 char const ** data = 0;
311 latexkeys * l = in_word_set (arg, strlen(arg));
317 data = mathed_get_pixmap_from_icon(MM_FRAC);
320 data = mathed_get_pixmap_from_icon(MM_SQRT);
324 // I have to use directly the bitmap data since the
325 // bitmap tables are not yet created when this
326 // function is called.
327 data = pixmapFromBitmapData(arg, wx, hx);
334 bool math_insert_greek(BufferView * bv, char c)
336 if (bv->available() &&
337 (('A' <= c && c <= 'Z') ||
338 ('a'<= c && c<= 'z'))) {
341 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
342 int greek_kb_flag_save = greek_kb_flag;
343 InsetFormula * new_inset = new InsetFormula();
345 if (!bv->insertInset(new_inset)) {
350 new_inset->Edit(bv, 0, 0, 0);
351 new_inset->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
352 if (greek_kb_flag_save < 2)
353 bv->unlockInset(new_inset); // bv->theLockingInset());
355 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
356 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
357 static_cast<InsetFormula*>(bv->theLockingInset())->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
359 lyxerr << "Math error: attempt to write on a wrong "
360 "class of inset." << endl;
367 void math_insert_symbol(BufferView * bv, string const & s)
369 if (bv->available()) {
370 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
371 InsetFormula * new_inset = new InsetFormula();
373 if (!bv->insertInset(new_inset)) {
378 new_inset->Edit(bv, 0, 0, 0);
379 new_inset->InsertSymbol(bv, s);
381 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
382 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
383 static_cast<InsetFormula*>(bv->theLockingInset())->InsertSymbol(bv, s);
385 lyxerr << "Math error: attempt to write on a wrong "
386 "class of inset." << endl;
391 BitmapMenu * sym_menu= 0;
393 void create_symbol_menues(FD_panel * symb_form)
398 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
399 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
401 fl_set_bmtable_maxitems(obj, 11);
402 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
406 menu = new BitmapMenu(1, symb_form->boperator, menu);
407 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
409 fl_set_bmtable_maxitems(obj, 31);
412 menu = new BitmapMenu(1, symb_form->brelats, menu);
413 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
415 fl_set_bmtable_maxitems(obj, 35);
418 menu = new BitmapMenu(3, symb_form->arrow, menu);
419 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
421 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
423 fl_set_bmtable_maxitems(obj, 7);
424 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
428 menu = new BitmapMenu(1, symb_form->varsize, menu);
429 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
431 fl_set_bmtable_maxitems(obj, 14);
434 menu = new BitmapMenu(2, symb_form->misc, menu);
435 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
437 fl_set_bmtable_maxitems(obj, 29);
438 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
444 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
447 char const ** data = 0;
451 for (i = 0; i < 6; ++i) {
452 char const ** latex_str = 0;
454 case 0: latex_str = latex_greek; break;
455 case 1: latex_str = latex_bop; break;
456 case 2: latex_str = latex_brel; break;
457 case 3: latex_str = latex_arrow; break;
458 case 4: latex_str = latex_varsz; break;
459 case 5: latex_str = latex_misc; break;
462 for (int k = 0; latex_str[k][0] > ' '; ++k) {
463 if (strcmp(latex_str[k], s) == 0) {
470 if (i < 6 && id >= 0) {
471 unsigned char const * bdata = 0;
472 int w = 0, h = 0, dw = 0, dh = 0;
474 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
535 int ww = w/dw, hh = h/dh, x, y;
537 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
538 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
539 xima->byte_order = LSBFirst;
540 xima->bitmap_bit_order = LSBFirst;
543 if (ww > wx) ww = wx;
544 if (hh > hx) hh = hx;
545 XImage * sbima = XSubImage(xima, x, y, ww, hh);
546 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
548 // Dirty hack to get blue symbols quickly
549 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
551 for (int k = 0; k < 8; ++k) sx[k] = '0';
554 // XDestroyImage(xima);