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