]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormMathsBitmap.C
* Kill the math deco dialog; it's just another bitmap dialog so no need to
[lyx.git] / src / frontends / xforms / FormMathsBitmap.C
1 /**
2  * \file FormMathsBitmap.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author John Levon
8  * \author Angus Leeming
9  *
10  * Full author contact details are available in file CREDITS
11  */
12
13 #include <config.h>
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19 #include "FormMathsBitmap.h"
20 #include "ControlMath.h"
21 #include "xformsBC.h"
22
23 #include "bmtable.h"
24 #include "forms_gettext.h"
25 #include "gettext.h"
26 #include "support/LAssert.h"
27
28 #include XPM_H_LOCATION
29
30 #include <algorithm>
31
32 extern  "C" void C_FormBaseCancelCB(FL_OBJECT *, long);
33 extern  "C" void C_FormBaseInputCB(FL_OBJECT *, long);
34
35 using std::vector;
36 using std::max;
37
38
39 FD_maths_bitmap::~FD_maths_bitmap()
40 {
41         if (form->visible) fl_hide_form(form);
42         fl_free_form(form);
43 }
44
45
46 typedef FormCB<ControlMathSub, FormDB<FD_maths_bitmap> > base_class;
47
48
49 FormMathsBitmap::FormMathsBitmap(string const & t, vector<string> const & l)
50         : base_class(t, false),
51           latex_(l), ww_(0), x_(0), y_(0), w_(0), h_(0)
52 {
53         ww_ = 2 * FL_abs(FL_BOUND_WIDTH);
54         x_ = y_ = ww_;
55         y_ += 8;
56 }
57
58
59 void FormMathsBitmap::addBitmap(int nt, int nx, int ny, int bw, int bh,
60                                 unsigned char const * data, bool vert)
61 {
62         bitmaps_.push_back(BitmapStore(nt, nx, ny, bw, bh, data, vert));
63
64         int wx = bw + ww_ / 2;
65         int wy = bh + ww_ / 2;
66         wx += (wx % nx);
67         wy += (wy % ny);
68
69         if (vert) {
70                 y_ += wy + 8;
71                 h_ = max(y_, h_);
72                 w_ = max(x_ + wx + ww_, w_);
73         } else  {
74                 x_ += wx + 8;
75                 w_ = max(x_, w_);
76                 h_ = max(y_ + wy + ww_, h_);
77         }
78 }
79
80
81 void FormMathsBitmap::build()
82 {
83         lyx::Assert(bitmaps_.size() > 0);
84
85         h_+= 42; // Allow room for a Close button
86
87         FD_maths_bitmap * fdui = new FD_maths_bitmap;
88
89         fdui->form = fl_bgn_form(FL_UP_BOX, w_, h_);
90         fdui->form->u_vdata = this;
91
92         fl_add_box(FL_UP_BOX, 0, 0, w_, h_, "");
93
94         x_ = y_ = ww_;
95         y_ += 8;
96
97         int y_close = 0;
98         for (vector<BitmapStore>::const_iterator it = bitmaps_.begin();
99              it < bitmaps_.end(); ++it) {
100                 FL_OBJECT * obj = buildBitmap(*it);
101
102                 bc().addReadOnly(obj);
103                 y_close = max(y_close, obj->y + obj->h);
104         }
105         bitmaps_.clear();
106
107         x_ = (fdui->form->w - 90) / 2;
108         y_ = y_close + 10;
109
110         char const * const label = _("Close|^[");
111         fdui->button_close = fl_add_button(FL_NORMAL_BUTTON, x_, y_, 90, 30,
112                                            idex(label).c_str());
113         fl_set_button_shortcut(fdui->button_close, scex(label).c_str(), 1);
114         fl_set_object_lsize(fdui->button_close, FL_NORMAL_SIZE);
115         fl_set_object_callback(fdui->button_close, C_FormBaseCancelCB, 0);
116
117         fl_end_form();
118
119         fdui->form->fdui = fdui;
120
121         dialog_.reset(fdui);
122         bc().setCancel(dialog_->button_close);
123 }
124
125
126
127 FL_OBJECT * FormMathsBitmap::buildBitmap(BitmapStore const & bmstore)
128 {
129         // Add a bitmap to a button panel: one bitmap per panel.
130         // nt is the number of buttons and nx, ny the nr. of buttons
131         // in x and y direction.
132         // bw, bh and data are the bitmap dimensions width, height and
133         // bit pattern; these come directly from an .xbm file included
134         // as source.
135         // vert indicates whether the next button panel within this
136         // window will be below (true, default) or next to this one.
137         //
138         // The scaling of the bitmap on top of the buttons will be
139         // correct if the nx, ny values are given correctly.
140         int wx = bmstore.bw + ww_ / 2;
141         int wy = bmstore.bh + ww_ / 2;
142         wx += (wx % bmstore.nx);
143         wy += (wy % bmstore.ny);
144
145         FL_OBJECT * obj = fl_add_bmtable(1, x_, y_, wx, wy, "");
146         fl_set_object_lcol(obj, FL_BLUE);
147         fl_set_object_boxtype(obj, FL_UP_BOX);
148         fl_set_bmtable_data(obj, bmstore.nx, bmstore.ny, bmstore.bw, bmstore.bh,
149                             bmstore.data);
150         fl_set_bmtable_maxitems(obj, bmstore.nt);
151         fl_set_object_callback(obj, C_FormBaseInputCB, 0);
152
153         if (bmstore.vert) {
154                 y_ += wy + 8;
155         } else  {
156                 x_ += wx + 8;
157         }
158
159         return obj;
160 }
161
162
163 int FormMathsBitmap::GetIndex(FL_OBJECT * ob_in)
164 {
165         int k = 0;
166
167         for (FL_OBJECT * ob = form()->first; ob; ob = ob->next) {
168                 if (ob->objclass != FL_BMTABLE)
169                         continue;
170
171                 if (ob == ob_in)
172                         return k + fl_get_bmtable(ob);
173                 else
174                         k += fl_get_bmtable_maxitems(ob);
175         }
176
177         return -1;
178 }
179
180
181 void FormMathsBitmap::apply()
182 {
183         string::size_type const i = latex_chosen_.find(' ');
184         if (i != string::npos) {
185                 controller().dispatchFunc(LFUN_MATH_MODE);
186                 controller().insertSymbol(latex_chosen_.substr(0,i));
187                 controller().insertSymbol(latex_chosen_.substr(i + 1), false);
188         } else
189                 controller().insertSymbol(latex_chosen_);
190 }
191
192
193 ButtonPolicy::SMInput FormMathsBitmap::input(FL_OBJECT * ob, long)
194 {
195         int const i = GetIndex(ob);
196
197         if (i < 0)
198                 return ButtonPolicy::SMI_INVALID;
199
200         latex_chosen_ = latex_[i];
201         apply();
202         return ButtonPolicy::SMI_VALID;
203 }