]> git.lyx.org Git - lyx.git/blob - src/frontends/gtk/GMathDelim.C
Extracted from r14281
[lyx.git] / src / frontends / gtk / GMathDelim.C
1 /**
2  * \file GMathDelim.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Huang Ying
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCXX_CONCEPT_CHECKS
15 #undef _GLIBCXX_CONCEPT_CHECKS
16 #endif
17 #ifdef _GLIBCPP_CONCEPT_CHECKS
18 #undef _GLIBCPP_CONCEPT_CHECKS
19 #endif
20
21 #include "ControlMath.h"
22 #include "GMathDelim.h"
23 #include "ghelpers.h"
24
25 #include "support/lstrings.h"
26
27 #include <libglademm.h>
28
29 #include <sstream>
30
31 #include "delim.xbm"
32 #include "delim0.xpm"
33
34 using std::string;
35
36 namespace lyx {
37 namespace frontend {
38
39 // FIXME: Implement fixed size delimiters (see qt3 frontend)
40
41 namespace
42 {
43
44 enum enumDelimType {LEFT, RIGHT, SINGLE};
45
46
47 int const delimType[] = {
48         //row 1
49         LEFT, RIGHT, LEFT, RIGHT, SINGLE, SINGLE, LEFT, RIGHT,LEFT, RIGHT,
50         SINGLE, SINGLE,
51         //row 2
52         LEFT, RIGHT, LEFT, RIGHT, SINGLE, SINGLE, LEFT, RIGHT, SINGLE, SINGLE,
53         SINGLE
54 };
55
56
57 int const delimRevert[] = {
58         1,0,3,2,4,5,7,6,9,8,10,11,
59         13,12,15,14,16,17,19,18,20,21,22
60 };
61
62
63 char const * delimValues[] = {
64         "(", ")", "lceil",  "rceil",  "uparrow",  "Uparrow",
65         "[", "]", "lfloor", "rfloor", "updownarrow", "Updownarrow",
66         "{", "}",  "/", "backslash",  "downarrow",  "Downarrow",
67         "langle",  "rangle", "|", "Vert", ".", 0
68 };
69
70 int const delimTblRows = 2;
71
72 int const delimTblCols = 12;
73
74 int const delimMax = 23;
75
76
77 GXpmBtnTbl::XbmData xbm =
78 {
79         delim_bits,
80         delim_width,
81         delim_height,
82         {0, 0, 0, 65535}
83 };
84
85
86 inline int index(int row, int col)
87 {
88         return row * delimTblCols + col;
89 }
90
91
92 inline int indexToRow(int index)
93 {
94         return index / delimTblCols;
95 }
96
97
98 inline int indexToCol(int index)
99 {
100         return index % delimTblCols;
101 }
102
103 }
104
105
106 GMathDelim::GMathDelim(Dialog & parent) :
107         GViewCB<ControlMath, GViewGladeB>(parent, _("Math Delimiters")),
108         delimTbl_(delimTblRows, delimTblCols, xbm)
109 {
110 }
111
112
113 void GMathDelim::doBuild()
114 {
115         string const gladeName = findGladeFile("mathDelim");
116         xml_ = Gnome::Glade::Xml::create(gladeName);
117         Gtk::Button * ok;
118         Gtk::Button * apply;
119         Gtk::Button * close;
120         Gtk::Box * box;
121         xml_->get_widget("Left", left_);
122         xml_->get_widget("Right", right_);
123         xml_->get_widget("Both", both_);
124         xml_->get_widget("OK", ok);
125         xml_->get_widget("Apply", apply);
126         xml_->get_widget("Close", close);
127         xml_->get_widget("Demo", demo_);
128         setOK(ok);
129         setApply(apply);
130         setCancel(close);
131         // Initialize demo button pixmap to "()" as found in images/delim0.xpm
132         setDemoPixmap();
133         leftSel_ = 0;
134         rightSel_ = 1;
135         xml_->get_widget("Box", box);
136         delimTbl_.signalClicked().connect(
137                 sigc::mem_fun(*this, &GMathDelim::onDelimTblClicked));
138         delimTbl_.show();
139         box->children().push_back(
140                 Gtk::Box_Helpers::Element(delimTbl_));
141         bcview().addReadOnly(&delimTbl_);
142         bcview().addReadOnly(left_);
143         bcview().addReadOnly(right_);
144         bcview().addReadOnly(both_);
145         bcview().addReadOnly(demo_);
146         left_->signal_clicked().connect(
147                 sigc::mem_fun(*this, &GMathDelim::onRadioClicked));
148         right_->signal_clicked().connect(
149                 sigc::mem_fun(*this, &GMathDelim::onRadioClicked));
150         both_->signal_clicked().connect(
151                 sigc::mem_fun(*this, &GMathDelim::onRadioClicked));
152 }
153
154
155 void GMathDelim::setDemoPixmap()
156 {
157         Gtk::Image * image;
158         pixmap_ = Gdk::Pixmap::create_from_xpm(demo_->get_colormap(),
159                                                mask_,
160                                                delim0);
161         image = Gtk::manage(new Gtk::Image(pixmap_, mask_));
162         image->show();
163         demo_->add(*image);
164         gcMask_ = Gdk::GC::create(mask_);
165 }
166
167
168 void GMathDelim::apply()
169 {
170         std::ostringstream os;
171         os << delimValues[leftSel_] << ' ' << delimValues[rightSel_];
172         controller().dispatchDelim(os.str());
173 }
174
175
176 void GMathDelim::update()
177 {
178         bc().valid();
179 }
180
181
182 void GMathDelim::onDelimTblClicked(int row, int col)
183 {
184         int const sel = index(row, col);
185         if (sel >= delimMax)
186                 return;
187         bool left = left_->get_active();
188         bool right = right_->get_active();
189         bool both = both_->get_active();
190         if (left)
191                 leftSel_ = sel;
192         else if (right)
193                 rightSel_ = sel;
194         else if (both)
195                 if (delimType[sel] == LEFT) {
196                         leftSel_ = sel;
197                         rightSel_ = delimRevert[sel];
198                 } else if (delimType[sel] == RIGHT) {
199                         rightSel_ = sel;
200                         leftSel_ = delimRevert[sel];
201                 } else {
202                         leftSel_ = rightSel_ = sel;
203                 }
204         updateDemoPixmap();
205 }
206
207
208 void GMathDelim::updateDemoPixmap()
209 {
210         int const delimWidth = delim_width / delimTblCols;
211         Glib::RefPtr<Gdk::Pixmap> pixmap;
212         Glib::RefPtr<Gdk::Bitmap> mask;
213         GXpmBtnTbl::GXpmBtn * btn =  delimTbl_.getBtn(indexToRow(leftSel_),
214                                                        indexToCol(leftSel_));
215         pixmap = btn->getPixmap();
216         mask = btn->getMask();
217         pixmap_->draw_drawable(left_->get_style()->get_black_gc(),
218                                pixmap,
219                                0, 0,
220                                0, 0);
221         mask_->draw_drawable(gcMask_,
222                              mask,
223                              0, 0,
224                              0, 0);
225         btn =  delimTbl_.getBtn(indexToRow(rightSel_),
226                                 indexToCol(rightSel_));
227         pixmap = btn->getPixmap();
228         mask = btn->getMask();
229         pixmap_->draw_drawable(left_->get_style()->get_black_gc(),
230                                pixmap,
231                                0, 0,
232                                delimWidth, 0);
233         mask_->draw_drawable(gcMask_,
234                              mask,
235                              0, 0,
236                              delimWidth, 0);
237         int x, y, width, height, depth;
238         demo_->get_window()->get_geometry(x, y, width, height, depth);
239         demo_->get_window()->invalidate_rect(
240                 Gdk::Rectangle(x, y, width, height), true);
241         bc().valid();
242 }
243
244
245 void GMathDelim::onRadioClicked()
246 {
247         bc().valid();
248 }
249
250 } // namespace frontend
251 } // namespace lyx