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, unsigned char const * data, Bool vert)
183 int wx = bw+ww/2, wy = bh+ww/2;
186 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
187 fl_set_object_callback(obj, math_cb, id);
188 fl_set_object_lcol(obj, FL_BLUE);
189 fl_set_object_boxtype(obj, FL_UP_BOX);
190 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
194 w = max(x + wx + ww, w);
198 h = max(y + wy + ww, h);
204 void BitmapMenu::Create()
207 lyxerr << "Error: Bitmaps not created!" << endl;
210 form = fl_bgn_form(FL_UP_BOX, w, h);
211 for (i = 0; i < nb; ++i) {
212 fl_add_object(form, bitmap[i]);
213 bitmap[i]->u_vdata = this;
216 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
219 int BitmapMenu::GetIndex(FL_OBJECT* ob)
221 if (active == this) {
223 for (i = 0; i < nb; ++i) {
225 return k+fl_get_bmtable(ob);
226 k += fl_get_bmtable_maxitems(bitmap[i]);
232 int peek_event(FL_FORM * /*form*/, void *xev)
234 if (BitmapMenu::active == 0)
237 if(static_cast<XEvent *>(xev)->type == ButtonPress)
239 BitmapMenu::active->Hide();
242 if(static_cast<XEvent *>(xev)->type == KeyPress)
246 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
247 if (keysym == XK_Left)
248 BitmapMenu::active->Prev(); else
249 if (keysym == XK_Right)
250 BitmapMenu::active->Next();
252 BitmapMenu::active->Hide();
258 // This is just a wrapper.
259 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
260 return peek_event(form, ptr);
264 extern "C" void math_cb(FL_OBJECT* ob, long data)
266 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
267 int i = menu->GetIndex(ob);
270 // lyxerr << "data[" << data << "]";
292 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
293 s = latex_dots[i-29];
298 if (current_view->available() && lyxrc.display_shortcuts) {
299 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
301 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
307 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
309 char const ** data = 0;
310 latexkeys * l = in_word_set (arg, strlen(arg));
316 data = mathed_get_pixmap_from_icon(MM_FRAC);
319 data = mathed_get_pixmap_from_icon(MM_SQRT);
323 // I have to use directly the bitmap data since the
324 // bitmap tables are not yet created when this
325 // function is called.
326 data = pixmapFromBitmapData(arg, wx, hx);
333 bool math_insert_greek(char c)
335 if (current_view->available() &&
336 (('A' <= c && c <= 'Z') ||
337 ('a'<= c && c<= 'z'))) {
340 if (!current_view->the_locking_inset) {
341 int greek_kb_flag_save = greek_kb_flag;
342 InsetFormula * new_inset = new InsetFormula();
343 current_view->beforeChange();
344 current_view->insertInset(new_inset);
346 new_inset->Edit(current_view, 0, 0, 0);
347 new_inset->LocalDispatch(current_view, LFUN_SELFINSERT, tmp);
348 if (greek_kb_flag_save < 2)
349 current_view->unlockInset(current_view->the_locking_inset);
351 if (current_view->the_locking_inset->LyxCode() == Inset::MATH_CODE)
352 static_cast<InsetFormula*>(current_view->the_locking_inset)->LocalDispatch(current_view, LFUN_SELFINSERT, tmp);
354 lyxerr << "Math error: attempt to write on a wrong "
355 "class of inset." << endl;
362 void math_insert_symbol(char const * s)
364 if (current_view->available()) {
365 if (!current_view->the_locking_inset) {
366 InsetFormula * new_inset = new InsetFormula();
367 current_view->beforeChange();
368 current_view->insertInset(new_inset);
370 new_inset->Edit(current_view, 0, 0, 0);
371 new_inset->InsertSymbol(current_view, s);
373 if (current_view->the_locking_inset->LyxCode() == Inset::MATH_CODE)
374 static_cast<InsetFormula*>(current_view->the_locking_inset)->InsertSymbol(current_view, s);
376 lyxerr << "Math error: attempt to write on a wrong "
377 "class of inset." << endl;
382 BitmapMenu * sym_menu= 0;
384 void create_symbol_menues(FD_panel * symb_form)
389 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
390 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
392 fl_set_bmtable_maxitems(obj, 11);
393 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
397 menu = new BitmapMenu(1, symb_form->boperator, menu);
398 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
400 fl_set_bmtable_maxitems(obj, 31);
403 menu = new BitmapMenu(1, symb_form->brelats, menu);
404 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
406 fl_set_bmtable_maxitems(obj, 35);
409 menu = new BitmapMenu(3, symb_form->arrow, menu);
410 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
412 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
414 fl_set_bmtable_maxitems(obj, 7);
415 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
419 menu = new BitmapMenu(1, symb_form->varsize, menu);
420 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
422 fl_set_bmtable_maxitems(obj, 14);
425 menu = new BitmapMenu(2, symb_form->misc, menu);
426 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
428 fl_set_bmtable_maxitems(obj, 29);
429 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
435 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
438 char const ** data = 0;
442 for (i = 0; i < 6; ++i) {
443 char const ** latex_str = 0;
445 case 0: latex_str = latex_greek; break;
446 case 1: latex_str = latex_bop; break;
447 case 2: latex_str = latex_brel; break;
448 case 3: latex_str = latex_arrow; break;
449 case 4: latex_str = latex_varsz; break;
450 case 5: latex_str = latex_misc; break;
453 for (int k = 0; latex_str[k][0] > ' '; ++k) {
454 if (strcmp(latex_str[k], s) == 0) {
461 if (i < 6 && id >= 0) {
462 unsigned char const * bdata = 0;
463 int w = 0, h = 0, dw = 0, dh = 0;
465 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
526 int ww = w/dw, hh = h/dh, x, y;
528 XImage * xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
529 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
530 xima->byte_order = LSBFirst;
531 xima->bitmap_bit_order = LSBFirst;
534 if (ww > wx) ww = wx;
535 if (hh > hx) hh = hx;
536 XImage * sbima = XSubImage(xima, x, y, ww, hh);
537 XpmCreateDataFromImage(fl_display, const_cast<char***>(&data), sbima, sbima, 0);
539 // Dirty hack to get blue symbols quickly
540 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
542 for (int k = 0; k < 8; ++k) sx[k] = '0';
545 // XDestroyImage(xima);