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 */
62 char const * latex_greek[] = {
63 "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
64 "Sigma", "Upsilon", "Phi", "Psi", "Omega",
65 "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
66 "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
67 "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
68 "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
73 char const * latex_brel[] = {
74 "leq", "geq", "equiv", "models",
75 "prec", "succ", "sim", "perp",
76 "preceq", "succeq", "simeq", "mid",
77 "ll", "gg", "asymp", "parallel",
78 "subset", "supset", "approx", "smile",
79 "subseteq", "supseteq", "cong", "frown",
80 "sqsubseteq", "sqsupseteq", "doteq", "neq",
81 "in", "ni", "propto", "notin",
82 "vdash", "dashv", "bowtie", ""
87 char const * latex_arrow[] = {
88 "downarrow", "leftarrow", "Downarrow", "Leftarrow",
89 "hookleftarrow", "rightarrow", "uparrow", "Rightarrow", "Uparrow",
90 "hookrightarrow", "updownarrow", "Leftrightarrow", "leftharpoonup",
91 "rightharpoonup", "rightleftharpoons", "leftrightarrow", "Updownarrow",
92 "leftharpoondown", "rightharpoondown", "mapsto",
93 "Longleftarrow", "Longrightarrow", "Longleftrightarrow",
94 "longleftrightarrow", "longleftarrow", "longrightarrow", "longmapsto",
95 "nwarrow", "nearrow", "swarrow", "searrow", "",
99 char const * latex_varsz[] = {
100 "sum", "int", "oint",
101 "prod", "coprod", "bigsqcup",
102 "bigotimes", "bigodot", "bigoplus",
103 "bigcap", "bigcup", "biguplus",
104 "bigvee", "bigwedge", ""
109 char const * latex_bop[] = {
110 "pm", "cap", "diamond", "oplus",
111 "mp", "cup", "bigtriangleup", "ominus",
112 "times", "uplus", "bigtriangledown", "otimes",
113 "div", "sqcap", "triangleright", "oslash",
114 "cdot", "sqcup", "triangleleft", "odot",
115 "star", "vee", "amalg", "bigcirc",
116 "setminus", "wedge", "dagger", "circ",
117 "bullet", "wr", "ddagger", ""
122 char const * latex_misc[] = {
123 "nabla", "partial", "infty", "prime", "ell",
124 "emptyset", "exists", "forall", "imath", "jmath",
125 "Re", "Im", "aleph", "wp", "hbar",
126 "angle", "top", "bot", "Vert", "neg",
127 "flat", "natural", "sharp", "surd", "triangle",
128 "diamondsuit", "heartsuit", "clubsuit", "spadesuit", ""
133 char const * latex_dots[] = {
134 "ldots", "cdots", "vdots", "ddots"
138 extern char const ** mathed_get_pixmap_from_icon(int d);
139 extern "C" void math_cb(FL_OBJECT*, long);
140 static char const ** pixmapFromBitmapData(char const *, int, int);
141 void math_insert_symbol(char const * s);
142 bool math_insert_greek(char c);
144 BitmapMenu * BitmapMenu::active = 0;
146 BitmapMenu::BitmapMenu(int n, FL_OBJECT * bt, BitmapMenu * prevx)
147 : current_(0), bitmaps_(n)
151 ww = 2 * FL_abs(FL_BOUND_WIDTH);
155 button->u_vdata = this;
163 BitmapMenu::~BitmapMenu()
166 if (form->visible) Hide();
171 void BitmapMenu::Hide()
174 fl_set_button(button, 0);
179 void BitmapMenu::Show()
184 // int x = button->form->x + button->x, y = button->form->y + button->y;
185 // fl_set_form_position(form, x, y + button->h);
186 fl_set_button(button, 1);
187 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
192 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh,
193 unsigned char const * data, Bool vert)
195 if (current_ >= bitmaps_.size())
197 int wx = bw + ww / 2;
198 int wy = bh + ww / 2;
201 FL_OBJECT * obj = fl_create_bmtable(1, x, y, wx, wy, "");
202 fl_set_object_callback(obj, math_cb, id);
203 fl_set_object_lcol(obj, FL_BLUE);
204 fl_set_object_boxtype(obj, FL_UP_BOX);
205 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
209 w = max(x + wx + ww, w);
213 h = max(y + wy + ww, h);
215 bitmaps_[current_++] = obj;
220 void BitmapMenu::Create()
222 if (current_ < bitmaps_.size()) {
223 lyxerr << "Error: Bitmaps not created!" << endl;
226 form = fl_bgn_form(FL_UP_BOX, w, h);
227 for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
228 fl_add_object(form, bitmaps_[current_]);
229 bitmaps_[current_]->u_vdata = this;
232 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
236 int BitmapMenu::GetIndex(FL_OBJECT* ob)
238 if (active == this) {
240 for (current_ = 0; current_ < bitmaps_.size(); ++current_) {
241 if (bitmaps_[current_] == ob)
242 return k+fl_get_bmtable(ob);
243 k += fl_get_bmtable_maxitems(bitmaps_[current_]);
250 int peek_event(FL_FORM * /*form*/, void *xev)
252 if (BitmapMenu::active == 0)
255 if (static_cast<XEvent *>(xev)->type == ButtonPress) {
256 BitmapMenu::active->Hide();
259 if (static_cast<XEvent *>(xev)->type == KeyPress) {
262 XLookupString(&static_cast<XEvent *>(xev)->xkey, &c[0], 5, &keysym, 0);
263 if (keysym == XK_Left)
264 BitmapMenu::active->Prev(); else
265 if (keysym == XK_Right)
266 BitmapMenu::active->Next();
268 BitmapMenu::active->Hide();
275 // This is just a wrapper.
276 extern "C" int C_peek_event(FL_FORM *form, void *ptr)
278 return peek_event(form, ptr);
282 extern "C" void math_cb(FL_OBJECT* ob, long data)
284 BitmapMenu * menu = static_cast<BitmapMenu*>(ob->u_vdata);
285 int i = menu->GetIndex(ob);
288 // lyxerr << "data[" << data << "]";
310 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
311 s = latex_dots[i-29];
316 if (current_view->available() && lyxrc.display_shortcuts) {
317 current_view->owner()->getMiniBuffer()->Set("Inserting symbol ", s);
319 current_view->owner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
326 char const ** get_pixmap_from_symbol(char const * arg, int wx, int hx)
328 char const ** data = 0;
329 latexkeys const * l = in_word_set (arg, strlen(arg));
335 data = mathed_get_pixmap_from_icon(MM_FRAC);
338 data = mathed_get_pixmap_from_icon(MM_SQRT);
342 // I have to use directly the bitmap data since the
343 // bitmap tables are not yet created when this
344 // function is called.
345 data = pixmapFromBitmapData(arg, wx, hx);
353 bool math_insert_greek(BufferView * bv, char c)
355 if (bv->available() &&
356 (('A' <= c && c <= 'Z') ||
357 ('a'<= c && c<= 'z'))) {
360 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
361 int greek_kb_flag_save = greek_kb_flag;
362 InsetFormula * new_inset = new InsetFormula();
363 bv->beforeChange(bv->text);
364 if (!bv->insertInset(new_inset)) {
369 new_inset->Edit(bv, 0, 0, 0);
370 new_inset->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
371 if (greek_kb_flag_save < 2) {
372 bv->unlockInset(new_inset); // bv->theLockingInset());
373 bv->text->CursorRight(bv, true);
376 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
377 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
378 static_cast<InsetFormula*>(bv->theLockingInset())->LocalDispatch(bv, LFUN_SELFINSERT, tmp);
380 lyxerr << "Math error: attempt to write on a wrong "
381 "class of inset." << endl;
388 void math_insert_symbol(BufferView * bv, string const & s)
390 if (bv->available()) {
391 if (!bv->theLockingInset() || bv->theLockingInset()->IsTextInset()) {
392 InsetFormula * new_inset = new InsetFormula();
393 bv->beforeChange(bv->text);
394 if (!bv->insertInset(new_inset)) {
398 new_inset->Edit(bv, 0, 0, 0);
399 new_inset->InsertSymbol(bv, s);
401 if (bv->theLockingInset()->LyxCode() == Inset::MATH_CODE ||
402 bv->theLockingInset()->LyxCode() == Inset::MATHMACRO_CODE)
403 static_cast<InsetFormula*>(bv->theLockingInset())->InsertSymbol(bv, s);
405 lyxerr << "Math error: attempt to write on a wrong "
406 "class of inset." << endl;
411 BitmapMenu * sym_menu = 0;
413 void create_symbol_menues(FD_panel * symb_form)
418 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
419 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
421 fl_set_bmtable_maxitems(obj, 11);
422 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
426 menu = new BitmapMenu(1, symb_form->boperator, menu);
427 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
429 fl_set_bmtable_maxitems(obj, 31);
432 menu = new BitmapMenu(1, symb_form->brelats, menu);
433 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
435 fl_set_bmtable_maxitems(obj, 35);
438 menu = new BitmapMenu(3, symb_form->arrow, menu);
439 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
441 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
443 fl_set_bmtable_maxitems(obj, 7);
444 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
448 menu = new BitmapMenu(1, symb_form->varsize, menu);
449 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
451 fl_set_bmtable_maxitems(obj, 14);
454 menu = new BitmapMenu(2, symb_form->misc, menu);
455 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
457 fl_set_bmtable_maxitems(obj, 29);
458 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
465 char const ** pixmapFromBitmapData(char const * s, int wx, int hx)
467 char const ** data = 0;
473 char const ** latex_str = 0;
475 case 0: latex_str = latex_greek; break;
476 case 1: latex_str = latex_bop; break;
477 case 2: latex_str = latex_brel; break;
478 case 3: latex_str = latex_arrow; break;
479 case 4: latex_str = latex_varsz; break;
480 case 5: latex_str = latex_misc; break;
483 for (int k = 0; latex_str[k][0] > ' '; ++k) {
484 if (compare(latex_str[k], s) == 0) {
491 if (i < 6 && id >= 0) {
492 unsigned char const * bdata = 0;
498 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
537 } else if (id > 28) {
571 XImage * xima = XCreateImage(fl_get_display(), 0, 1, XYBitmap, 0,
572 const_cast<char*>(reinterpret_cast<char const *>(bdata)), w, h, 8, 0);
573 xima->byte_order = LSBFirst;
574 xima->bitmap_bit_order = LSBFirst;
575 int x = (id % dw) * ww;
576 int y = (id/dw) * hh;
577 if (ww > wx) ww = wx;
578 if (hh > hx) hh = hx;
579 XImage * sbima = XSubImage(xima, x, y, ww, hh);
580 XpmCreateDataFromImage(fl_get_display(), const_cast<char***>(&data), sbima, sbima, 0);
582 // Dirty hack to get blue symbols quickly
583 char * sx = const_cast<char*>(strstr(data[2], "FFFFFFFF"));
585 for (int k = 0; k < 8; ++k) sx[k] = '0';
588 // XDestroyImage(xima);