[project @ 4]
[mussa.git] / mussa_gui_conn.cc
1 #include "mussa_gui_conn.hh"
2
3
4
5 void
6 ConnView::setup(string name, int sq_num, int win_len,
7                 vector<Sequence> *some_seqs,
8                 Nway_Paths *some_paths)
9 {
10   int i;
11   Sequence a_seq;
12
13   ana_name = name;
14   seq_num = sq_num;
15   window = win_len;
16   S = some_seqs;
17   P = some_paths;
18
19   for(i = 0; i < seq_num; ++i)
20   {
21     a_seq = (*S)[i];
22     seq_lens.push_back(a_seq.len());
23   }
24
25   x_scale_factor = (float) seq_lens[0] / x_max;
26   cout << "scale factor is " << x_scale_factor << endl;
27   y_seq_incre = (y_max-20) / (seq_num - 1);
28
29   dragging = false;
30   selected = false;
31
32   highlight.clear();
33 }
34
35
36 void
37 ConnView::scale_paths()
38 {
39   vector<int> a_path;
40   list<vector<int> >::iterator pathz_i;
41   int i2;
42
43
44   scaled_pathz.clear();
45
46   for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
47   {
48     a_path = *pathz_i;
49     for(i2 = 0; i2 <= seq_num; i2++)
50       a_path[i2] = (int) (a_path[i2] / x_scale_factor);
51     scaled_pathz.push_back(a_path);
52   }
53 }
54
55
56
57
58 void
59 ConnView::draw()
60 {
61   list<vector<int> >::iterator i;
62   int i2, i3, y_loc, x_loc, x_start, x_end;
63   vector<int> a_path;
64   list<annot>::iterator annot_i;
65   int window_size;
66   bool rc_color;
67   int path_start, path_end;
68   list<bool>::iterator highlight_i;
69
70
71   // clear drawing area and set background to white
72   fl_color(FL_WHITE);
73   fl_rectf(x(), y(), w(), h());
74
75   // determine which paths to highlight
76   highlight.clear();
77   for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
78   {
79     a_path = *i;
80     // determine if path falls within the selected region and mark it for
81     // highlighted color
82     path_start = abs(a_path[1]);
83     path_end = path_start + a_path[0];
84     if ( ( (path_start >= drag_start) && (path_end <= drag_end) ) ||
85          ( (path_start < drag_start) && (path_end > drag_end) ) ||
86          ( (path_start < drag_start) && (path_end > drag_start) ) ||
87          ( (path_start < drag_end) && (path_end > drag_end) )          )
88       highlight.push_back(true);
89     else
90       highlight.push_back(false);
91   }
92
93   fl_line_style(FL_SOLID, 1, NULL);
94   // draw non-highlight paths (ie not in the selection box)
95   highlight_i = highlight.begin();
96   for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
97   {
98     a_path = *i;
99     y_loc = 10;
100
101     // get window size to determine line width
102     window_size = a_path[0];
103     // make sure width is at least 1  - might be zero to my slack rounding
104     if (window_size == 0)
105       window_size = 1;
106
107     if (!(*highlight_i))
108       for(i2 = seq_num; i2 > 1; i2--)
109       {
110         // RC case handling
111         // ugh, an xor...only want blue if one of the nodes is rc
112         if ( ((a_path[i2] < 0) || (a_path[i2-1] < 0)) &&
113              !((a_path[i2] < 0) && (a_path[i2-1] < 0)) )
114           fl_color(FL_CYAN);
115         else
116           fl_color(FL_MAGENTA);
117           
118         fl_polygon((int)abs(a_path[i2]), y_loc + 3,
119                    (int)abs(a_path[i2])+window_size, y_loc + 3,
120                    (int)abs(a_path[i2-1])+window_size, y_loc + y_seq_incre - 3,
121                    (int)abs(a_path[i2-1]), y_loc + y_seq_incre - 3);
122
123         y_loc += y_seq_incre;
124       }
125     ++highlight_i;
126   }
127
128   // draw highlighted paths (ie in or partially in selection)
129   // drawing these separately and after other paths so they are on top
130   highlight_i = highlight.begin();
131   for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
132   {
133     a_path = *i;
134     y_loc = 10;
135
136     // get window size to determine line width
137     window_size = a_path[0];
138     // make sure width is at least 1  - might be zero to my slack rounding
139     if (window_size == 0)
140       window_size = 1;
141
142     if (*highlight_i)
143       for(i2 = seq_num; i2 > 1; i2--)
144       {
145         // RC case handling
146         // ugh, an xor...only want blue if one of the nodes is rc
147         if ( ((a_path[i2] < 0) || (a_path[i2-1] < 0)) &&
148              !((a_path[i2] < 0) && (a_path[i2-1] < 0)) )
149           fl_color(FL_BLUE);
150         else
151           fl_color(FL_RED);
152           
153         fl_polygon((int)abs(a_path[i2]), y_loc + 3,
154                    (int)abs(a_path[i2])+window_size, y_loc + 3,
155                    (int)abs(a_path[i2-1])+window_size, y_loc + y_seq_incre - 3,
156                    (int)abs(a_path[i2-1]), y_loc + y_seq_incre - 3);
157
158         y_loc += y_seq_incre;
159       }
160     ++highlight_i;
161   }
162
163   // draw sequence representation lines
164   fl_color(FL_BLACK);
165   fl_line_style(FL_SOLID, 3, NULL);
166   y_loc = 10;
167   for(i2 = seq_num - 1; i2 >= 0; i2--)
168   {
169     x_loc = (int)(seq_lens[i2] / x_scale_factor);
170     fl_line(0,y_loc,x_loc,y_loc);
171     y_loc += y_seq_incre;
172   }
173
174   // draw annotations
175   fl_color(FL_GREEN);
176   fl_line_style(FL_SOLID, 9, NULL);
177   y_loc = 10;
178   for(i2 = seq_num - 1; i2 >= 0; i2--)
179   {
180     for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
181     {
182       x_start = (int)(annot_i->start / x_scale_factor);
183       x_end = (int)(annot_i->end / x_scale_factor);
184       fl_line(x_start,y_loc,x_end,y_loc);
185     }
186     y_loc += y_seq_incre;
187   }
188
189   // draw selection box
190   if (selected)
191   {
192     fl_color(FL_BLACK);
193     fl_line_style(FL_SOLID, 2, NULL);
194     fl_rect(drag_start, y_loc - y_seq_incre-8, drag_end-drag_start, 16);
195   }
196 }
197
198
199
200 int
201 ConnView::handle(int e)
202 {
203   int return_value;
204
205   switch(e)
206   {
207   case FL_PUSH:
208     if (Fl::event_button3())
209     {
210       spawnSeq();
211       return_value = 1;
212     }
213     break;
214   case FL_DRAG:
215     if (!dragging)
216     {
217       drag_start = Fl::event_x() -x();
218       dragging = true;
219       selected = false;
220       return_value = 1;
221     }
222     fl_color(FL_CYAN);
223     fl_line_style(FL_SOLID, 1, NULL);
224     fl_overlay_rect(drag_start, y_seq_incre*(seq_num-1), Fl::event_x()-drag_start, 16);
225     
226     break;
227   case FL_RELEASE:
228     if (dragging)
229     {
230       drag_end = Fl::event_x() - x();
231       dragging = false;
232       selected = true;
233       redraw();
234       return_value = 1;
235     }
236     break;
237   default:
238     return_value = Fl_Widget::handle(e);
239   }
240
241   return return_value;
242 }
243
244
245 void
246 ConnView::spawnSeq()
247 {
248   list<vector<int> > selected_paths;
249   list<vector<int> >::iterator pathz_i;
250   int i2, i3, y_loc, x_loc, x_start, x_end;
251   vector<int> a_path;
252   list<bool>::iterator highlight_i;
253
254   // make new list of connections that are highlighted
255   selected_paths.clear();
256   highlight_i = highlight.begin();
257   for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
258   {
259     if (*highlight_i)
260     {
261       a_path = *pathz_i;
262       selected_paths.push_back(a_path);
263       //cout << "bing ";
264     }
265     /*
266     else
267       cout << "bang ";
268     */
269     ++highlight_i;
270   }
271
272   //cout << endl;
273
274   Fl_Window *seq_window = new Fl_Window(x_max, y_max, "Mussa Sequence");
275
276
277   SeqView *seq_box = new SeqView(0, 0, x_max, y_max);
278   seq_box->setup(ana_name, seq_num, S, selected_paths, seq_lens);
279   seq_box->debug_draw();
280
281   seq_window->end();
282   seq_window->show();
283 }
284
285