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"
40 #include "math_panel.h"
41 #include "math_parser.h"
47 extern int greek_kb_flag;
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 extern char const ** mathed_get_pixmap_from_icon(int d);
126 extern "C" void math_cb(FL_OBJECT*, long);
127 static char const ** pixmapFromBitmapData(char const *, int, int);
128 void math_insert_symbol(char const * s);
129 bool math_insert_greek(char c);
131 BitmapMenu * BitmapMenu::active = 0;
133 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx): nb(n)
138 ww = 2 * FL_abs(FL_BOUND_WIDTH);
141 bitmap = new FL_OBJECTP[nb];
143 button->u_vdata = this;
151 BitmapMenu::~BitmapMenu()
154 if (form->visible) Hide();
160 void BitmapMenu::Hide()
163 fl_set_button(button, 0);
168 void BitmapMenu::Show()
173 // int x = button->form->x + button->x, y = button->form->y + button->y;
174 // fl_set_form_position(form, x, y + button->h);
175 fl_set_button(button, 1);
176 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
180 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh,
181 unsigned char const * data, Bool vert)
185 int wx = bw+ww/2, wy = bh+ww/2;
188 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
189 fl_set_object_callback(obj, math_cb, id);
190 fl_set_object_lcol(obj, FL_BLUE);
191 fl_set_object_boxtype(obj, FL_UP_BOX);
192 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
196 w = max(x + wx + ww, w);
200 h = max(y + wy + ww, h);
206 void BitmapMenu::Create()
209 lyxerr << "Error: Bitmaps not created!" << endl;
212 form = fl_bgn_form(FL_UP_BOX, w, h);
213 for (i = 0; i < nb; ++i) {
214 fl_add_object(form, bitmap[i]);
215 bitmap[i]->u_vdata = this;
218 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
221 int BitmapMenu::GetIndex(FL_OBJECT* ob)
223 if (active == this) {
225 for (i = 0; i < nb; ++i) {
227 return k+fl_get_bmtable(ob);
228 k += fl_get_bmtable_maxitems(bitmap[i]);
234 int peek_event(FL_FORM * /*form*/, void *xev)
236 if (BitmapMenu::active == 0)
239 if (static_cast<XEvent *>(xev)->type == ButtonPress)
241 BitmapMenu::active->Hide();
244 if (static_cast<XEvent *>(xev)->type == KeyPress)
248 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
249 if (keysym == XK_Left)
250 BitmapMenu::active->Prev(); else
251 if (keysym == XK_Right)
252 BitmapMenu::active->Next();
254 BitmapMenu::active->Hide();
260 // This is just a wrapper.
261 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
262 return peek_event(form, ptr);
266 extern "C" void math_cb(FL_OBJECT* ob, long data)
268 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
269 int i = menu->GetIndex(ob);
272 // lyxerr << "data[" << data << "]";
294 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
295 s = latex_dots[i-29];
300 if (current_view->available() && lyxrc.display_shortcuts) {
301 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
303 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
309 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
311 char const ** data = 0;
312 latexkeys * l = in_word_set (arg, strlen(arg));
318 data = mathed_get_pixmap_from_icon(MM_FRAC);
321 data = mathed_get_pixmap_from_icon(MM_SQRT);
325 // I have to use directly the bitmap data since the
326 // bitmap tables are not yet created when this
327 // function is called.
328 data = pixmapFromBitmapData(arg, wx, hx);
335 bool math_insert_greek(BufferView * bv, char c)
337 if (bv->available() &&
338 (('A' <= c && c <= 'Z') ||
339 ('a'<= c && c<= 'z'))) {
342 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
343 int greek_kb_flag_save = greek_kb_flag;
344 InsetFormula * new_inset = new InsetFormula();
346 if (!bv->insertInset(new_inset)) {
351 new_inset->Edit(bv, 0, 0, 0);
352 new_inset->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
353 if (greek_kb_flag_save < 2) {
354 bv->unlockInset(new_inset); // bv->theLockingInset());
355 bv->text->CursorRight(bv, true);
358 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
359 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
360 static_cast<InsetFormula*>(bv->theLockingInset())->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
362 lyxerr << "Math error: attempt to write on a wrong "
363 "class of inset." << endl;
370 void math_insert_symbol(BufferView * bv, string const & s)
372 if (bv->available()) {
373 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
374 InsetFormula * new_inset = new InsetFormula();
376 if (!bv->insertInset(new_inset)) {
381 new_inset->Edit(bv, 0, 0, 0);
382 new_inset->InsertSymbol(bv, s);
384 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
385 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
386 static_cast<InsetFormula*>(bv->theLockingInset())->InsertSymbol(bv, s);
388 lyxerr << "Math error: attempt to write on a wrong "
389 "class of inset." << endl;
394 BitmapMenu * sym_menu= 0;
396 void create_symbol_menues(FD_panel * symb_form)
401 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
402 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
404 fl_set_bmtable_maxitems(obj, 11);
405 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
409 menu = new BitmapMenu(1, symb_form->boperator, menu);
410 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
412 fl_set_bmtable_maxitems(obj, 31);
415 menu = new BitmapMenu(1, symb_form->brelats, menu);
416 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
418 fl_set_bmtable_maxitems(obj, 35);
421 menu = new BitmapMenu(3, symb_form->arrow, menu);
422 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
424 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
426 fl_set_bmtable_maxitems(obj, 7);
427 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
431 menu = new BitmapMenu(1, symb_form->varsize, menu);
432 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
434 fl_set_bmtable_maxitems(obj, 14);
437 menu = new BitmapMenu(2, symb_form->misc, menu);
438 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
440 fl_set_bmtable_maxitems(obj, 29);
441 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
447 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
450 char const ** data = 0;
454 for (i = 0; i < 6; ++i) {
455 char const ** latex_str = 0;
457 case 0: latex_str = latex_greek; break;
458 case 1: latex_str = latex_bop; break;
459 case 2: latex_str = latex_brel; break;
460 case 3: latex_str = latex_arrow; break;
461 case 4: latex_str = latex_varsz; break;
462 case 5: latex_str = latex_misc; break;
465 for (int k = 0; latex_str[k][0] > ' '; ++k) {
466 if (strcmp(latex_str[k], s) == 0) {
473 if (i < 6 && id >= 0) {
474 unsigned char const * bdata = 0;
475 int w = 0, h = 0, dw = 0, dh = 0;
477 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
538 int ww = w/dw, hh = h/dh, x, y;
540 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
541 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
542 xima->byte_order = LSBFirst;
543 xima->bitmap_bit_order = LSBFirst;
546 if (ww > wx) ww = wx;
547 if (hh > hx) hh = hx;
548 XImage * sbima = XSubImage(xima, x, y, ww, hh);
549 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
551 // Dirty hack to get blue symbols quickly
552 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
554 for (int k = 0; k < 8; ++k) sx[k] = '0';
557 // XDestroyImage(xima);