Edges are clickable now.
[av.git] / gtk / src / tree_model.cpp
blobb713df8b5a14a37c08feb09cfd12302bd3954cef
1 #include "tree_model.hpp"
3 TreeModel::TreeModel(GtkDrawingArea *cobject, Glib::RefPtr<Gnome::Glade::Xml> &glade) :
4 Gtk::DrawingArea(cobject),
5 _SENTENCE_SPACING(100),
6 _WORD_SPACING(15),
7 _alignment(NULL),
8 _selected(NULL)
13 TreeModel::~TreeModel(void)
15 std::vector<Vertex *>::iterator viter;
16 std::vector<Edge *>::iterator eiter;
18 for (viter = _source.begin(); viter != _source.end(); viter++) {
19 delete *viter;
21 for (viter = _target.begin(); viter != _target.end(); viter++) {
22 delete *viter;
25 for (eiter = _edges.begin(); eiter != _edges.end(); eiter++) {
26 delete *eiter;
30 void TreeModel::add_alignment(Alignment &alignment)
32 if (!_alignment) {
33 _alignment = &alignment;
36 _add_source();
37 _add_target();
38 _add_edges();
40 _invalidate_window();
43 bool TreeModel::on_expose_event(GdkEventExpose *event)
45 double x, y;
46 std::vector<Vertex *>::iterator viter;
47 std::vector<Edge *>::iterator eiter;
48 Glib::RefPtr<Gdk::Window> window = get_window();
50 if (window) {
51 _cr = window->create_cairo_context();
53 Gtk::Allocation allocation = get_allocation();
54 _xc = allocation.get_width() / 2;
55 _yc = allocation.get_height() / 2;
57 // Only redraw the region which has changed
58 if (event) {
59 _cr->rectangle(event->area.x, event->area.y,
60 event->area.width, event->area.height);
61 _cr->clip();
64 _cr->translate(_xc, _yc);
66 // Paint background
67 _cr->save();
68 _cr->set_source_rgb(1, 1, 1); // white
69 _cr->paint();
70 _cr->restore();
72 // Calculate left and right bearings to center the sentence
73 _BEARING = 0;
74 for (viter = _source.begin(); viter != _source.end(); viter++) {
75 _BEARING += (*viter)->get_width() + _WORD_SPACING;
77 _BEARING = (_xc * 2 - _BEARING + _WORD_SPACING) / 2;
79 // Draw all children vertices
80 x = _d2c_x(_BEARING);
81 y = _d2c_y(_yc - _SENTENCE_SPACING / 2);
82 for (viter = _source.begin(); viter != _source.end(); viter++) {
83 (*viter)->set_coordinates(x, y - (*viter)->get_height());
84 (*viter)->draw(_cr);
86 x += (*viter)->get_width() + _WORD_SPACING;
89 // Calculate left and right bearings to center the sentence
90 _BEARING = 0;
91 for (viter = _target.begin(); viter != _target.end(); viter++) {
92 _BEARING += (*viter)->get_width() + _WORD_SPACING;
94 _BEARING = (_xc * 2 - _BEARING + _WORD_SPACING) / 2;
96 x = _d2c_x(_BEARING);
97 y = _d2c_y(_yc + _SENTENCE_SPACING / 2);
98 for (viter = _target.begin(); viter != _target.end(); viter++) {
99 (*viter)->set_coordinates(x, y);
100 (*viter)->draw(_cr);
102 x += (*viter)->get_width() + _WORD_SPACING;
105 // Draw all edges
106 for (eiter = _edges.begin(); eiter != _edges.end(); eiter++) {
107 (*eiter)->draw(_cr);
111 return true;
114 bool TreeModel::on_button_press_event(GdkEventButton *event)
116 gdouble x = _d2c_x(event->x);
117 gdouble y = _d2c_y(event->y);
119 if (_button_press_event_cb<Vertex *>(_source, x, y) ||
120 _button_press_event_cb<Vertex *>(_target, x, y) ||
121 _button_press_event_cb<Edge *>(_edges, x, y)) {
122 return true;
125 return true;
128 void TreeModel::_add_source(void)
130 const std::vector<Word *> &words = _alignment->get_source().get_words();
131 std::vector<Word *>::const_iterator iter;
133 for (iter = words.begin(); iter != words.end(); iter++) {
134 _add_word(**iter, true);
138 void TreeModel::_add_target(void)
140 const std::vector<Word *> &words = _alignment->get_target().get_words();
141 std::vector<Word *>::const_iterator iter;
143 for (iter = words.begin(); iter != words.end(); iter++) {
144 _add_word(**iter, false);
148 void TreeModel::_add_word(const Word &word, bool source)
150 Vertex *v = new Vertex(*this, word);
152 v->get_changed_signal().connect(sigc::mem_fun(*this, &TreeModel::_invalidate_vertex));
154 if (source) {
155 _source.push_back(v);
156 } else {
157 _target.push_back(v);
161 void TreeModel::_add_edges(void)
163 Edge *e = NULL;
164 Vertex *s = NULL;
165 Vertex *t = NULL;
166 const alignment_t *source = NULL;
167 const alignment_t *target = NULL;
168 alignment_t::const_iterator iter;
170 _alignment->get_alignment(&source, &target);
172 for (iter = source->begin(); iter != source->end(); iter++) {
173 if (iter->first < 0 || iter->second < 0) {
174 continue;
177 s = _source[iter->second];
178 t = _target[iter->first];
180 if (!t->is_friend(*s)) {
181 e = new Edge(*s, *t);
182 _edges.push_back(e);
186 for (iter = target->begin(); iter != target->end(); iter++) {
187 if (iter->first < 0 || iter->second < 0) {
188 continue;
191 s = _source[iter->second];
192 t = _target[iter->first];
194 if (!t->is_friend(*s)) {
195 e = new Edge(*s, *t);
196 _edges.push_back(e);
201 void TreeModel::_invalidate_window(void)
203 _invalidate_rect(0, 0, get_allocation().get_width(),
204 get_allocation().get_height());
207 void TreeModel::_invalidate_vertex(Vertex *v)
209 if (_selected) {
210 _selected->deselect();
213 _selected = v;
215 _invalidate_rect(_c2d_x(gint(v->get_x())), _c2d_y(gint(v->get_y())),
216 gint(v->get_width()), gint(v->get_height()));
219 void TreeModel::_invalidate_rect(gint x, gint y, gint width, gint height)
221 Glib::RefPtr<Gdk::Window> window = get_window();
222 if (window) {
223 Gdk::Rectangle invalid(x, y, width, height);
224 window->invalidate_rect(invalid, false);
228 template <typename T>
229 bool TreeModel::_button_press_event_cb(std::vector<T> &obj, gdouble x, gdouble y)
231 typename std::vector<T>::iterator iter;
233 for (iter = obj.begin(); iter != obj.end(); iter++) {
234 if ((*iter)->select(_cr, x, y)) {
235 return true;
239 return false;