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 SmallUpdate(signed char);
43 extern void BeforeChange();
44 extern void Update(signed char);
45 extern int UnlockInset(UpdatableInset *);
46 extern short 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 static signed char latin2greek[] = {
125 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
126 19, 21, 22, 17, 27, 15, 26, 6
129 static signed char Latin2Greek[] = {
130 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
131 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
134 extern char const ** mathed_get_pixmap_from_icon(int d);
135 extern "C" void math_cb(FL_OBJECT*, long);
136 static char const ** pixmapFromBitmapData(char const *, int, int);
137 void math_insert_symbol(char const * s);
138 Bool math_insert_greek(char const c);
140 BitmapMenu * BitmapMenu::active = 0;
142 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
147 ww = 2 * FL_abs(FL_BOUND_WIDTH);
150 bitmap = new FL_OBJECTP[nb];
152 button->u_vdata = this;
160 BitmapMenu::~BitmapMenu()
162 if (next) delete next;
163 if (form->visible) Hide();
169 void BitmapMenu::Hide()
172 fl_set_button(button, 0);
177 void BitmapMenu::Show()
182 // int x = button->form->x + button->x, y = button->form->y + button->y;
183 // fl_set_form_position(form, x, y + button->h);
184 fl_set_button(button, 1);
185 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
189 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
193 int wx = bw+ww/2, wy = bh+ww/2;
196 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
197 fl_set_object_callback(obj, math_cb, id);
198 fl_set_object_lcol(obj, FL_BLUE);
199 fl_set_object_boxtype(obj, FL_UP_BOX);
200 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
204 w = max(x + wx + ww, w);
208 h = max(y + wy + ww, h);
214 void BitmapMenu::Create()
217 lyxerr << "Error: Bitmaps not created!" << endl;
220 form = fl_bgn_form(FL_UP_BOX, w, h);
221 for (i= 0; i<nb; i++) {
222 fl_add_object(form, bitmap[i]);
223 bitmap[i]->u_vdata = this;
226 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
229 int BitmapMenu::GetIndex(FL_OBJECT* ob)
231 if (active == this) {
233 for (i= 0; i<nb; i++) {
235 return k+fl_get_bmtable(ob);
236 k += fl_get_bmtable_maxitems(bitmap[i]);
242 int peek_event(FL_FORM * /*form*/, void *xev)
244 if (BitmapMenu::active == 0)
247 if(static_cast<XEvent *>(xev)->type == ButtonPress)
249 BitmapMenu::active->Hide();
252 if(static_cast<XEvent *>(xev)->type == KeyPress)
256 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
257 if (keysym == XK_Left)
258 BitmapMenu::active->Prev(); else
259 if (keysym == XK_Right)
260 BitmapMenu::active->Next();
262 BitmapMenu::active->Hide();
268 // This is just a wrapper.
269 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
270 return peek_event(form, ptr);
274 extern "C" void math_cb(FL_OBJECT* ob, long data)
276 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
277 int i = menu->GetIndex(ob);
280 // lyxerr << "data[" << data << "]";
302 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
303 s = latex_dots[i-29];
308 if (current_view->available() && lyxrc->display_shortcuts) {
309 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
311 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
317 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
319 char const ** data = 0;
320 latexkeys * l = in_word_set (arg, strlen(arg));
326 data = mathed_get_pixmap_from_icon(MM_FRAC);
329 data = mathed_get_pixmap_from_icon(MM_SQRT);
333 // I have to use directly the bitmap data since the
334 // bitmap tables are not yet created when this
335 // function is called.
336 data = pixmapFromBitmapData(arg, wx, hx);
343 Bool math_insert_greek(char const c)
348 if ('A' <= c && c <= 'Z') {
349 if ((i = Latin2Greek[c - 'A']) >= 0)
352 if ('a'<= c && c<= 'z') {
353 if ((i= latin2greek[c - 'a'])>= 0)
354 s = latex_greek[i+11];
357 math_insert_symbol(s);
358 if (greek_kb_flag<2) {
360 UnlockInset(current_view->buffer()->the_locking_inset);
367 void math_insert_symbol(char const* s)
369 if (current_view->available()) {
370 if (!current_view->buffer()->the_locking_inset) {
371 InsetFormula * new_inset = new InsetFormula();
373 current_view->buffer()->insertInset(new_inset);
375 new_inset->Edit(0, 0);
376 new_inset->InsertSymbol(s);
378 if (current_view->buffer()->the_locking_inset->LyxCode() == Inset::MATH_CODE)
379 static_cast<InsetFormula*>(current_view->buffer()->the_locking_inset)->InsertSymbol(s);
381 lyxerr << "Math error: attempt to write on a wrong "
382 "class of inset." << endl;
386 BitmapMenu * sym_menu= 0;
388 void create_symbol_menues(FD_panel * symb_form)
393 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
394 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
396 fl_set_bmtable_maxitems(obj, 11);
397 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
401 menu = new BitmapMenu(1, symb_form->boperator, menu);
402 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
404 fl_set_bmtable_maxitems(obj, 31);
407 menu = new BitmapMenu(1, symb_form->brelats, menu);
408 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
410 fl_set_bmtable_maxitems(obj, 35);
413 menu = new BitmapMenu(3, symb_form->arrow, menu);
414 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
416 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
418 fl_set_bmtable_maxitems(obj, 7);
419 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
423 menu = new BitmapMenu(1, symb_form->varsize, menu);
424 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
426 fl_set_bmtable_maxitems(obj, 14);
429 menu = new BitmapMenu(2, symb_form->misc, menu);
430 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
432 fl_set_bmtable_maxitems(obj, 29);
433 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
439 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
442 char const ** data = 0;
446 for (i = 0; i < 6; ++i) {
447 char const ** latex_str = 0;
449 case 0: latex_str = latex_greek; break;
450 case 1: latex_str = latex_bop; break;
451 case 2: latex_str = latex_brel; break;
452 case 3: latex_str = latex_arrow; break;
453 case 4: latex_str = latex_varsz; break;
454 case 5: latex_str = latex_misc; break;
457 for (int k = 0; latex_str[k][0]>' '; k++) {
458 if (strcmp(latex_str[k], s) == 0) {
465 if (i < 6 && id >= 0) {
466 unsigned char const * bdata = 0;
467 int w = 0, h = 0, dw = 0, dh = 0;
469 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
530 int ww = w/dw, hh = h/dh, x, y;
532 XImage * xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
533 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
534 xima->byte_order = LSBFirst;
535 xima->bitmap_bit_order = LSBFirst;
538 if (ww > wx) ww = wx;
539 if (hh > hx) hh = hx;
540 XImage * sbima = XSubImage(xima, x, y, ww, hh);
541 XpmCreateDataFromImage(fl_display, const_cast<char***>(&data), sbima, sbima, 0);
543 // Dirty hack to get blue symbols quickly
544 char * sx = strstr(data[2], "FFFFFFFF");
546 for (int k = 0; k < 8; ++k) sx[k] = '0';
549 // XDestroyImage(xima);