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;
47 extern MiniBuffer * minibuffer;
49 extern BufferView * current_view;
60 /* Latex code for those bitmaps */
61 static char const * latex_greek[] = {
62 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
63 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
64 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
65 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
66 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
67 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
70 static char const * latex_brel[] = {
71 "leq", "geq", "equiv", "models",
72 "prec", "succ", "sim", "perp",
73 "preceq", "succeq", "simeq", "mid",
74 "ll", "gg", "asymp", "parallel",
75 "subset", "supset", "approx", "smile",
76 "subseteq", "supseteq", "cong", "frown",
77 "sqsubseteq", "sqsupseteq", "doteq", "neq",
78 "in", "ni", "propto", "notin",
79 "vdash", "dashv", "bowtie", ""
82 static char const * latex_arrow[] = {
83 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
84 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
85 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
86 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
87 "leftharpoondown", "rightharpoondown", "mapsto",
88 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
89 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
90 "nwarrow", "nearrow", "swarrow", "searrow", "",
93 char const * latex_varsz[] = {
95 "prod", "coprod", "bigsqcup",
96 "bigotimes", "bigodot", "bigoplus",
97 "bigcap", "bigcup", "biguplus",
98 "bigvee", "bigwedge", ""
101 static char const * latex_bop[] = {
102 "pm", "cap", "diamond", "oplus",
103 "mp", "cup", "bigtriangleup", "ominus",
104 "times", "uplus", "bigtriangledown", "otimes",
105 "div", "sqcap", "triangleright", "oslash",
106 "cdot", "sqcup", "triangleleft", "odot",
107 "star", "vee", "amalg", "bigcirc",
108 "setminus", "wedge", "dagger", "circ",
109 "bullet", "wr", "ddagger", ""
112 static char const * latex_misc[] = {
113 "nabla", "partial", "infty", "prime", "ell",
114 "emptyset", "exists", "forall", "imath", "jmath",
115 "Re", "Im", "aleph", "wp", "hbar",
116 "angle", "top", "bot", "Vert", "neg",
117 "flat", "natural", "sharp", "surd", "triangle",
118 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
121 static char const * latex_dots[] = {
122 "ldots", "cdots", "vdots", "ddots"
125 static signed char latin2greek[] = {
126 0, 1, 25, 3, 4, 23, 2, 7, 10, 24, 11, 12, 13, 14, -1, 16, 8, 18,
127 19, 21, 22, 17, 27, 15, 26, 6
130 static signed char Latin2Greek[] = {
131 -1, -1, -1, 1, -1, 8, 0, -1, -1, -1, -1, 3, -1, -1, -1,
132 5, 2, -1, 6, -1, 7, -1, 10, 4, 9, -1
135 extern char const ** mathed_get_pixmap_from_icon(int d);
136 extern "C" void math_cb(FL_OBJECT*, long);
137 static char const ** pixmapFromBitmapData(char const *, int, int);
138 void math_insert_symbol(char const * s);
139 Bool math_insert_greek(char const c);
141 BitmapMenu * BitmapMenu::active = 0;
143 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
148 ww = 2 * FL_abs(FL_BOUND_WIDTH);
151 bitmap = new FL_OBJECTP[nb];
153 button->u_vdata = this;
161 BitmapMenu::~BitmapMenu()
163 if (next) delete next;
164 if (form->visible) Hide();
170 void BitmapMenu::Hide()
173 fl_set_button(button, 0);
178 void BitmapMenu::Show()
183 // int x = button->form->x + button->x, y = button->form->y + button->y;
184 // fl_set_form_position(form, x, y + button->h);
185 fl_set_button(button, 1);
186 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
190 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char const * data, Bool vert)
194 int wx = bw+ww/2, wy = bh+ww/2;
197 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
198 fl_set_object_callback(obj, math_cb, id);
199 fl_set_object_lcol(obj, FL_BLUE);
200 fl_set_object_boxtype(obj, FL_UP_BOX);
201 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
205 w = max(x + wx + ww, w);
209 h = max(y + wy + ww, h);
215 void BitmapMenu::Create()
218 lyxerr << "Error: Bitmaps not created!" << endl;
221 form = fl_bgn_form(FL_UP_BOX, w, h);
222 for (i= 0; i<nb; i++) {
223 fl_add_object(form, bitmap[i]);
224 bitmap[i]->u_vdata = this;
227 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
230 int BitmapMenu::GetIndex(FL_OBJECT* ob)
232 if (active == this) {
234 for (i= 0; i<nb; i++) {
236 return k+fl_get_bmtable(ob);
237 k += fl_get_bmtable_maxitems(bitmap[i]);
243 int peek_event(FL_FORM * /*form*/, void *xev)
245 if (BitmapMenu::active == 0)
248 if(static_cast<XEvent *>(xev)->type == ButtonPress)
250 BitmapMenu::active->Hide();
253 if(static_cast<XEvent *>(xev)->type == KeyPress)
257 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
258 if (keysym == XK_Left)
259 BitmapMenu::active->Prev(); else
260 if (keysym == XK_Right)
261 BitmapMenu::active->Next();
263 BitmapMenu::active->Hide();
269 // This is just a wrapper.
270 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
271 return peek_event(form, ptr);
275 extern "C" void math_cb(FL_OBJECT* ob, long data)
277 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
278 int i = menu->GetIndex(ob);
281 // lyxerr << "data[" << data << "]";
303 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
304 s = latex_dots[i-29];
309 if (current_view->available() && lyxrc->display_shortcuts) {
310 minibuffer->Set("Inserting symbol ", s);
312 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
318 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
320 char const ** data = 0;
321 latexkeys * l = in_word_set (arg, strlen(arg));
327 data = mathed_get_pixmap_from_icon(MM_FRAC);
330 data = mathed_get_pixmap_from_icon(MM_SQRT);
334 // I have to use directly the bitmap data since the
335 // bitmap tables are not yet created when this
336 // function is called.
337 data = pixmapFromBitmapData(arg, wx, hx);
344 Bool math_insert_greek(char const c)
349 if ('A' <= c && c <= 'Z') {
350 if ((i = Latin2Greek[c - 'A']) >= 0)
353 if ('a'<= c && c<= 'z') {
354 if ((i= latin2greek[c - 'a'])>= 0)
355 s = latex_greek[i+11];
358 math_insert_symbol(s);
359 if (greek_kb_flag<2) {
361 UnlockInset(current_view->buffer()->the_locking_inset);
368 void math_insert_symbol(char const* s)
370 if (current_view->available()) {
371 if (!current_view->buffer()->the_locking_inset) {
372 InsetFormula * new_inset = new InsetFormula();
374 current_view->buffer()->insertInset(new_inset);
376 new_inset->Edit(0, 0);
377 new_inset->InsertSymbol(s);
379 if (current_view->buffer()->the_locking_inset->LyxCode() == Inset::MATH_CODE)
380 static_cast<InsetFormula*>(current_view->buffer()->the_locking_inset)->InsertSymbol(s);
382 lyxerr << "Math error: attempt to write on a wrong "
383 "class of inset." << endl;
387 BitmapMenu * sym_menu= 0;
389 void create_symbol_menues(FD_panel * symb_form)
394 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
395 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
397 fl_set_bmtable_maxitems(obj, 11);
398 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
402 menu = new BitmapMenu(1, symb_form->boperator, menu);
403 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
405 fl_set_bmtable_maxitems(obj, 31);
408 menu = new BitmapMenu(1, symb_form->brelats, menu);
409 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
411 fl_set_bmtable_maxitems(obj, 35);
414 menu = new BitmapMenu(3, symb_form->arrow, menu);
415 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
417 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
419 fl_set_bmtable_maxitems(obj, 7);
420 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
424 menu = new BitmapMenu(1, symb_form->varsize, menu);
425 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
427 fl_set_bmtable_maxitems(obj, 14);
430 menu = new BitmapMenu(2, symb_form->misc, menu);
431 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
433 fl_set_bmtable_maxitems(obj, 29);
434 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
440 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
443 char const ** data = 0;
447 for (i = 0; i < 6; ++i) {
448 char const ** latex_str = 0;
450 case 0: latex_str = latex_greek; break;
451 case 1: latex_str = latex_bop; break;
452 case 2: latex_str = latex_brel; break;
453 case 3: latex_str = latex_arrow; break;
454 case 4: latex_str = latex_varsz; break;
455 case 5: latex_str = latex_misc; break;
458 for (int k = 0; latex_str[k][0]>' '; k++) {
459 if (strcmp(latex_str[k], s) == 0) {
466 if (i < 6 && id >= 0) {
467 unsigned char const * bdata = 0;
468 int w = 0, h = 0, dw = 0, dh = 0;
470 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
531 int ww = w/dw, hh = h/dh, x, y;
533 XImage * xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
534 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
535 xima->byte_order = LSBFirst;
536 xima->bitmap_bit_order = LSBFirst;
539 if (ww > wx) ww = wx;
540 if (hh > hx) hh = hx;
541 XImage * sbima = XSubImage(xima, x, y, ww, hh);
542 XpmCreateDataFromImage(fl_display, const_cast<char***>(&data), sbima, sbima, 0);
544 // Dirty hack to get blue symbols quickly
545 char * sx = strstr(data[2], "FFFFFFFF");
547 for (int k = 0; k < 8; ++k) sx[k] = '0';
550 // XDestroyImage(xima);