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"
29 #include "BufferView.h"
30 #include "minibuffer.h"
33 #include "support/lstrings.h"
38 #include "math_panel.h"
39 #include "math_parser.h"
41 extern void SmallUpdate(signed char);
42 extern void BeforeChange();
43 extern void Update(signed char);
44 extern int UnlockInset(UpdatableInset*);
45 extern short greek_kb_flag;
46 extern MiniBuffer *minibuffer;
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** mathed_get_pixmap_from_icon(int d);
135 static void math_cb(FL_OBJECT*, long);
136 static char** 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) {
146 ww = 2*FL_abs(FL_BOUND_WIDTH);
149 bitmap = new FL_OBJECTP[nb];
151 button->u_vdata = this;
158 BitmapMenu::~BitmapMenu() {
159 if (next) delete next;
160 if (form->visible) Hide();
165 void BitmapMenu::Hide() {
167 fl_set_button(button, 0);
171 void BitmapMenu::Show() {
175 // int x = button->form->x + button->x, y = button->form->y + button->y;
176 // fl_set_form_position(form, x, y + button->h);
177 fl_set_button(button, 1);
178 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
182 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, char* data, Bool vert)
186 int wx=bw+ww/2, wy=bh+ww/2;
189 FL_OBJECT *obj = fl_create_bmtable(1, x, y, wx, wy, "");
190 fl_set_object_callback(obj, math_cb, id);
191 fl_set_object_lcol(obj, FL_BLUE);
192 fl_set_object_boxtype(obj, FL_UP_BOX);
193 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
197 w = max(x + wx + ww, w);
201 h = max(y + wy + ww, h);
207 void BitmapMenu::Create()
210 lyxerr << "Error: Bitmaps not created!" << endl;
213 form = fl_bgn_form(FL_UP_BOX, w, h);
214 for (i=0; i<nb; i++) {
215 fl_add_object(form, bitmap[i]);
216 bitmap[i]->u_vdata = this;
219 fl_register_raw_callback(form, KeyPressMask, peek_event);
222 int BitmapMenu::GetIndex(FL_OBJECT* ob)
226 for (i=0; i<nb; i++) {
228 return k+fl_get_bmtable(ob);
229 k += fl_get_bmtable_maxitems(bitmap[i]);
236 int peek_event(FL_FORM * /*form*/, void *xev)
238 if (BitmapMenu::active==0)
241 if(((XEvent *)xev)->type == ButtonPress)
243 BitmapMenu::active->Hide();
246 if(((XEvent *)xev)->type == KeyPress)
250 XLookupString(&((XEvent *)xev)->xkey, &c[0], 5, &keysym, 0);
252 BitmapMenu::active->Prev(); else
253 if (keysym==XK_Right)
254 BitmapMenu::active->Next();
256 BitmapMenu::active->Hide();
263 static void math_cb(FL_OBJECT* ob, long data)
265 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
266 int i = menu->GetIndex(ob);
269 // lyxerr << "data[" << data << "]";
291 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
292 s = latex_dots[i-29];
297 if (current_view->available() && lyxrc->display_shortcuts) {
298 minibuffer->Set("Inserting symbol ", s);
300 current_view->getOwner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
306 char** get_pixmap_from_symbol(char const *arg, int wx, int hx)
309 latexkeys *l = in_word_set (arg, strlen(arg));
315 data = mathed_get_pixmap_from_icon(MM_FRAC);
318 data = mathed_get_pixmap_from_icon(MM_SQRT);
322 // I have to use directly the bitmap data since the
323 // bitmap tables are not yet created when this
324 // function is called.
325 data = pixmapFromBitmapData(arg, wx, hx);
332 Bool math_insert_greek(char const c)
337 if ('A'<=c && c<='Z') {
338 if ((i=Latin2Greek[c - 'A'])>=0)
341 if ('a'<=c && c<='z') {
342 if ((i=latin2greek[c - 'a'])>=0)
343 s = latex_greek[i+11];
346 math_insert_symbol(s);
347 if (greek_kb_flag<2) {
349 UnlockInset(current_view->currentBuffer()->the_locking_inset);
356 void math_insert_symbol(char const* s)
358 if (current_view->available()) {
359 if (!current_view->currentBuffer()->the_locking_inset) {
360 InsetFormula* new_inset = new InsetFormula();
362 current_view->currentBuffer()->insertInset(new_inset);
364 new_inset->Edit(0,0);
365 new_inset->InsertSymbol(s);
367 if (current_view->currentBuffer()->the_locking_inset->LyxCode()==Inset::MATH_CODE)
368 ((InsetFormula*)current_view->currentBuffer()->the_locking_inset)->InsertSymbol(s);
370 lyxerr << "Math error: attempt to write on a wrong "
371 "class of inset." << endl;
375 BitmapMenu* sym_menu=0;
377 void create_symbol_menues(FD_panel *symb_form)
382 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
383 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
385 fl_set_bmtable_maxitems(obj, 11);
386 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
390 menu = new BitmapMenu(1, symb_form->boperator, menu);
391 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
393 fl_set_bmtable_maxitems(obj, 31);
396 menu = new BitmapMenu(1, symb_form->brelats, menu);
397 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
399 fl_set_bmtable_maxitems(obj, 35);
402 menu = new BitmapMenu(3, symb_form->arrow, menu);
403 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
405 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
407 fl_set_bmtable_maxitems(obj, 7);
408 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
412 menu = new BitmapMenu(1, symb_form->varsize, menu);
413 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
415 fl_set_bmtable_maxitems(obj, 14);
418 menu = new BitmapMenu(2, symb_form->misc, menu);
419 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
421 fl_set_bmtable_maxitems(obj, 29);
422 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
428 char** pixmapFromBitmapData(char const *s, int wx, int hx)
435 for (i=0; i<6; i++) {
436 char const **latex_str = 0;
438 case 0: latex_str = latex_greek; break;
439 case 1: latex_str = latex_bop; break;
440 case 2: latex_str = latex_brel; break;
441 case 3: latex_str = latex_arrow; break;
442 case 4: latex_str = latex_varsz; break;
443 case 5: latex_str = latex_misc; break;
446 for (int k = 0; latex_str[k][0]>' '; k++) {
447 if (strcmp(latex_str[k], s)==0) {
456 int w = 0, h = 0, dw = 0, dh = 0;
458 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
519 int ww = w/dw, hh = h/dh, x, y;
521 XImage *xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
523 xima->byte_order = LSBFirst;
524 xima->bitmap_bit_order = LSBFirst;
529 XImage *sbima = XSubImage(xima, x, y, ww, hh);
530 XpmCreateDataFromImage(fl_display, &data, sbima, sbima, 0);
532 // Dirty hack to get blue symbols quickly
533 char *sx = strstr(data[2], "FFFFFFFF");
535 for (int k=0; k<8; k++) sx[k] = '0';
538 // XDestroyImage(xima);