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** mathed_get_pixmap_from_icon(int d);
136 extern "C" void math_cb(FL_OBJECT*, long);
137 static char** 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) {
147 ww = 2*FL_abs(FL_BOUND_WIDTH);
150 bitmap = new FL_OBJECTP[nb];
152 button->u_vdata = this;
159 BitmapMenu::~BitmapMenu() {
160 if (next) delete next;
161 if (form->visible) Hide();
166 void BitmapMenu::Hide() {
168 fl_set_button(button, 0);
172 void BitmapMenu::Show() {
176 // int x = button->form->x + button->x, y = button->form->y + button->y;
177 // fl_set_form_position(form, x, y + button->h);
178 fl_set_button(button, 1);
179 fl_show_form(form, FL_PLACE_MOUSE, FL_NOBORDER, "");
183 BitmapMenu::AddBitmap(int id, int nx, int ny, int bw, int bh, unsigned char* data, Bool vert)
187 int wx=bw+ww/2, wy=bh+ww/2;
190 FL_OBJECT *obj = fl_create_bmtable(1, x, y, wx, wy, "");
191 fl_set_object_callback(obj, math_cb, id);
192 fl_set_object_lcol(obj, FL_BLUE);
193 fl_set_object_boxtype(obj, FL_UP_BOX);
194 fl_set_bmtable_data(obj, nx, ny, bw, bh, data);
198 w = max(x + wx + ww, w);
202 h = max(y + wy + ww, h);
208 void BitmapMenu::Create()
211 lyxerr << "Error: Bitmaps not created!" << endl;
214 form = fl_bgn_form(FL_UP_BOX, w, h);
215 for (i=0; i<nb; i++) {
216 fl_add_object(form, bitmap[i]);
217 bitmap[i]->u_vdata = this;
220 fl_register_raw_callback(form, KeyPressMask, C_peek_event);
223 int BitmapMenu::GetIndex(FL_OBJECT* ob)
227 for (i=0; i<nb; i++) {
229 return k+fl_get_bmtable(ob);
230 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();
262 // This is just a wrapper.
263 extern "C" int C_peek_event(FL_FORM *form, void *ptr) {
264 return peek_event(form,ptr);
268 extern "C" void math_cb(FL_OBJECT* ob, long data)
270 BitmapMenu* menu = (BitmapMenu*)ob->u_vdata;
271 int i = menu->GetIndex(ob);
274 // lyxerr << "data[" << data << "]";
296 // lyxerr << "dots[" << latex_dots[i] << " " << i << "]";
297 s = latex_dots[i-29];
302 if (current_view->available() && lyxrc->display_shortcuts) {
303 minibuffer->Set("Inserting symbol ", s);
305 current_view->getOwner()->getLyXFunc()->Dispatch(LFUN_INSERT_MATH, s);
311 char** get_pixmap_from_symbol(char const *arg, int wx, int hx)
314 latexkeys *l = in_word_set (arg, strlen(arg));
320 data = mathed_get_pixmap_from_icon(MM_FRAC);
323 data = mathed_get_pixmap_from_icon(MM_SQRT);
327 // I have to use directly the bitmap data since the
328 // bitmap tables are not yet created when this
329 // function is called.
330 data = pixmapFromBitmapData(arg, wx, hx);
337 Bool math_insert_greek(char const c)
342 if ('A'<=c && c<='Z') {
343 if ((i=Latin2Greek[c - 'A'])>=0)
346 if ('a'<=c && c<='z') {
347 if ((i=latin2greek[c - 'a'])>=0)
348 s = latex_greek[i+11];
351 math_insert_symbol(s);
352 if (greek_kb_flag<2) {
354 UnlockInset(current_view->currentBuffer()->the_locking_inset);
361 void math_insert_symbol(char const* s)
363 if (current_view->available()) {
364 if (!current_view->currentBuffer()->the_locking_inset) {
365 InsetFormula* new_inset = new InsetFormula();
367 current_view->currentBuffer()->insertInset(new_inset);
369 new_inset->Edit(0,0);
370 new_inset->InsertSymbol(s);
372 if (current_view->currentBuffer()->the_locking_inset->LyxCode()==Inset::MATH_CODE)
373 ((InsetFormula*)current_view->currentBuffer()->the_locking_inset)->InsertSymbol(s);
375 lyxerr << "Math error: attempt to write on a wrong "
376 "class of inset." << endl;
380 BitmapMenu* sym_menu=0;
382 void create_symbol_menues(FD_panel *symb_form)
387 sym_menu = menu = new BitmapMenu(2, symb_form->greek);
388 obj = menu->AddBitmap(MM_GREEK, 6, 2, Greek_width, Greek_height,
390 fl_set_bmtable_maxitems(obj, 11);
391 obj = menu->AddBitmap(MM_GREEK, 7, 4, greek_width, greek_height,
395 menu = new BitmapMenu(1, symb_form->boperator, menu);
396 obj = menu->AddBitmap(MM_BOP, 4, 8, bop_width, bop_height,
398 fl_set_bmtable_maxitems(obj, 31);
401 menu = new BitmapMenu(1, symb_form->brelats, menu);
402 obj = menu->AddBitmap(MM_BRELATS, 4, 9, brel_width, brel_height,
404 fl_set_bmtable_maxitems(obj, 35);
407 menu = new BitmapMenu(3, symb_form->arrow, menu);
408 obj = menu->AddBitmap(MM_ARROW, 5, 4, arrow_width, arrow_height,
410 obj = menu->AddBitmap(MM_ARROW, 2, 4, larrow_width, larrow_height,
412 fl_set_bmtable_maxitems(obj, 7);
413 obj = menu->AddBitmap(MM_ARROW, 2, 2, darrow_width, darrow_height,
417 menu = new BitmapMenu(1, symb_form->varsize, menu);
418 obj = menu->AddBitmap(MM_VARSIZE, 3, 5, varsz_width, varsz_height,
420 fl_set_bmtable_maxitems(obj, 14);
423 menu = new BitmapMenu(2, symb_form->misc, menu);
424 obj = menu->AddBitmap(MM_MISC, 5, 6, misc_width, misc_height,
426 fl_set_bmtable_maxitems(obj, 29);
427 obj = menu->AddBitmap(MM_DOTS, 4, 1, dots_width, dots_height,
433 char** pixmapFromBitmapData(char const *s, int wx, int hx)
440 for (i=0; i<6; i++) {
441 char const **latex_str = 0;
443 case 0: latex_str = latex_greek; break;
444 case 1: latex_str = latex_bop; break;
445 case 2: latex_str = latex_brel; break;
446 case 3: latex_str = latex_arrow; break;
447 case 4: latex_str = latex_varsz; break;
448 case 5: latex_str = latex_misc; break;
451 for (int k = 0; latex_str[k][0]>' '; k++) {
452 if (strcmp(latex_str[k], s)==0) {
460 unsigned char *bdata = 0;
461 int w = 0, h = 0, dw = 0, dh = 0;
463 lyxerr[Debug::MATHED] << "Imando " << i << ", " << id << endl;
524 int ww = w/dw, hh = h/dh, x, y;
526 XImage *xima = XCreateImage(fl_display, 0, 1, XYBitmap, 0,
527 reinterpret_cast<char*>(bdata), w, h, 8, 0);
528 xima->byte_order = LSBFirst;
529 xima->bitmap_bit_order = LSBFirst;
534 XImage *sbima = XSubImage(xima, x, y, ww, hh);
535 XpmCreateDataFromImage(fl_display, &data, sbima, sbima, 0);
537 // Dirty hack to get blue symbols quickly
538 char *sx = strstr(data[2], "FFFFFFFF");
540 for (int k=0; k<8; k++) sx[k] = '0';
543 // XDestroyImage(xima);