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]);
235 int peek_event(FL_FORM * /*form*/, void *xev)
237 if (BitmapMenu::active==0)
240 if(((XEvent *)xev)->type == ButtonPress)
242 BitmapMenu::active->Hide();
245 if(((XEvent *)xev)->type == KeyPress)
249 XLookupString(&((XEvent *)xev)->xkey, &c[0], 5, &keysym, 0);
251 BitmapMenu::active->Prev(); else
252 if (keysym==XK_Right)
253 BitmapMenu::active->Next();
255 BitmapMenu::active->Hide();
261 static void math_cb(FL_OBJECT* ob, long data)
263 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
264 int i = menu->GetIndex(ob);
267 // lyxerr << "data[" << data << "]";
289 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
290 s = latex_dots[i-29];
295 if (current_view->available() && lyxrc->display_shortcuts) {
296 minibuffer->Set("Inserting symbol ", s);
298 current_view->getOwner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
304 char** get_pixmap_from_symbol(char const *arg, int wx, int hx)
307 latexkeys *l = in_word_set (arg, strlen(arg));
313 data = mathed_get_pixmap_from_icon(MM_FRAC);
316 data = mathed_get_pixmap_from_icon(MM_SQRT);
320 // I have to use directly the bitmap data since the
321 // bitmap tables are not yet created when this
322 // function is called.
323 data = pixmapFromBitmapData(arg, wx, hx);
330 Bool math_insert_greek(char const c)
335 if ('A'<=c && c<='Z') {
336 if ((i=Latin2Greek[c - 'A'])>=0)
339 if ('a'<=c && c<='z') {
340 if ((i=latin2greek[c - 'a'])>=0)
341 s = latex_greek[i+11];
344 math_insert_symbol(s);
345 if (greek_kb_flag<2) {
347 UnlockInset(current_view->currentBuffer()->the_locking_inset);
354 void math_insert_symbol(char const* s)
356 if (current_view->available()) {
357 if (!current_view->currentBuffer()->the_locking_inset) {
358 InsetFormula* new_inset = new InsetFormula();
360 current_view->currentBuffer()->insertInset(new_inset);
362 new_inset->Edit(0,0);
363 new_inset->InsertSymbol(s);
365 if (current_view->currentBuffer()->the_locking_inset->LyxCode()==Inset::MATH_CODE)
366 ((InsetFormula*)current_view->currentBuffer()->the_locking_inset)->InsertSymbol(s);
368 lyxerr << "Math error: attempt to write on a wrong "
369 "class of inset." << endl;
373 BitmapMenu* sym_menu=0;
375 void create_symbol_menues(FD_panel *symb_form)
380 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
381 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
383 fl_set_bmtable_maxitems(obj, 11);
384 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
388 menu = new BitmapMenu(1, symb_form->boperator, menu);
389 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
391 fl_set_bmtable_maxitems(obj, 31);
394 menu = new BitmapMenu(1, symb_form->brelats, menu);
395 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
397 fl_set_bmtable_maxitems(obj, 35);
400 menu = new BitmapMenu(3, symb_form->arrow, menu);
401 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
403 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
405 fl_set_bmtable_maxitems(obj, 7);
406 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
410 menu = new BitmapMenu(1, symb_form->varsize, menu);
411 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
413 fl_set_bmtable_maxitems(obj, 14);
416 menu = new BitmapMenu(2, symb_form->misc, menu);
417 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
419 fl_set_bmtable_maxitems(obj, 29);
420 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
426 char** pixmapFromBitmapData(char const *s, int wx, int hx)
433 for (i=0; i<6; i++) {
434 char const **latex_str = 0;
436 case 0: latex_str = latex_greek; break;
437 case 1: latex_str = latex_bop; break;
438 case 2: latex_str = latex_brel; break;
439 case 3: latex_str = latex_arrow; break;
440 case 4: latex_str = latex_varsz; break;
441 case 5: latex_str = latex_misc; break;
444 for (int k = 0; latex_str[k][0]>' '; k++) {
445 if (strcmp(latex_str[k], s)==0) {
454 int w = 0, h = 0, dw = 0, dh = 0;
456 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
517 int ww = w/dw, hh = h/dh, x, y;
519 XImage *xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
521 xima->byte_order = LSBFirst;
522 xima->bitmap_bit_order = LSBFirst;
527 XImage *sbima = XSubImage(xima, x, y, ww, hh);
528 XpmCreateDataFromImage(fl_display, &data, sbima, sbima, 0);
530 // Dirty hack to get blue symbols quickly
531 char *sx = strstr(data[2], "FFFFFFFF");
533 for (int k=0; k<8; k++) sx[k] = '0';
536 // XDestroyImage(xima);