root/trunk/FRII/gui/AlignedPairSequenceView.cc

Revision 10, 6.2 kB (checked in by t, 3 years ago)

Tailorization
Import of the upstream sources from

Repository: :pserver:anonymous@cvs.sf.net:/cvsroot/familyjewels

Kind: cvs

Module: FRII

Revision: 2005-12-09 09:00:54 by titus

Original author: tailor@vallista.idyll.org
Date: 2005-12-09 09:00:54

Line 
1 /*
2  * This file is part of the FamilyRelations II source distribution.
3  *
4  * FamilyRelations II is part of the FamilyJewels package for comparative
5  * sequence analysis: http://family.caltech.edu/.
6  *
7  * Contact author: C. Titus Brown, titus@caltech.edu.
8  *
9  * This program and all associated source code files are Copyright (C) 2003,
10  * 2004 the California Institute of Technology, Pasadena, CA, 91125 USA.  It
11  * is under the Lesser GNU Public License; please see the included
12  * LICENSE.txt file for more information, or contact Titus directly.
13  *
14  */
15
16 #include <iostream>
17 #include "AlignedPairSequenceView.hh"
18 #include "math.h"
19
20 #define ARROW_SCROLL_BY 5
21
22 using namespace gui;
23
24 AlignedPairSequenceView::AlignedPairSequenceView(int _x, int _y,
25                                                  unsigned int _w,
26                                                  std::string top_aln,
27                                                  std::string bot_aln) :
28   SequenceView(_x, _y, _w, height, top_aln.length()),
29   _top_aln(top_aln), _bot_aln(bot_aln)
30 {
31   // get character width
32   fl_font(FL_COURIER, font_size);
33   ch_width = fl_width('A');
34
35   set_visible_bases(0, 50);
36   fgcolor(FL_RED);
37 }
38
39 //
40 // _resize_view -- make sure that the view size is sensible.
41 //
42
43 void AlignedPairSequenceView::_resize_view(unsigned int& start,
44                                            unsigned int& end)
45 {
46   int new_start, new_end;
47
48   // width of drawing field, in characters
49   unsigned int half_draw_width = (unsigned int) \
50                     ((float)get_width() / ch_width / 2.);
51
52 #ifdef _DEBUG_TEXT_DRAW
53   printf("half draw width: %d\n", half_draw_width);
54 #endif // _DEBUG_TEXT_DRAW
55
56   //
57   // pick the substring to draw:
58   //
59
60   new_start = start;
61   new_end = end;
62
63   new_end = new_start + 2*half_draw_width;
64   if ((unsigned int) new_end >= _top_aln.length()) {
65     new_end = _top_aln.length();
66     new_start = new_end - 2*half_draw_width;
67
68     if (new_start < 0) { new_start = 0; }
69   }
70
71   start = new_start;
72   end = new_end;
73 }
74
75 void AlignedPairSequenceView::draw()
76 {
77   // clear any overlay...
78   fl_overlay_clear();
79
80   // draw background
81   fl_color(color());
82   fl_rectf(x(), y(), w(), h());
83
84   fl_push_clip(x(), y(), w(), h());
85
86   fl_font(FL_COURIER, font_size);
87   fl_color(_fg_color);
88
89   // draw the two strings centered vertically.
90   int y_pos_a = height / 2 + fl_descent() + y() - fl_height();
91   int y_pos_b = height / 2 + fl_descent() + y() + 6;
92
93   std::string sub = _top_aln.substr(_start, _end - _start);
94   fl_draw(sub.c_str(), border, y_pos_a);
95
96   sub = _bot_aln.substr(_start, _end - _start);
97   fl_draw(sub.c_str(), border, y_pos_b);
98
99   //
100   // Now draw features.
101   //
102
103   FeaturesContainer * c;
104   const FeatureList * list;
105   Fl_Color color;
106   char tmp[5000];
107   assert((_end - _start) < 4999); // put an absurd upper bound on things.
108
109   for (unsigned int i = 0; i < _featureLists.size(); i++) {
110     c = _featureLists[i];
111
112     if (!c->visible()) { continue; }
113
114     list = c->getFeatureList();
115     color = c->color();
116
117     fl_color(color);
118
119     for (unsigned int j = 0; j < list->n_features(); j++) {
120       const Feature * f;
121
122       f = list->get(j);
123       if (f->start < _end && f->end > _start) { // draw it
124         int start_base = f->start > _start ? f->start : _start;
125         int end_base = f->end < _end ? f->end : _end;
126
127         // figure out where to start it!
128         std::string tst = sub.substr(0, start_base - _start);
129
130         int w = 0, h = 0;
131         fl_measure(tst.c_str(), w, h); // width --> w
132
133         // get new substr
134         int len = end_base - start_base;
135         strncpy(tmp, _top_aln.c_str() + start_base, len);
136         tmp[len] = 0;
137
138         // now draw!
139         fl_draw(tmp, border + w, y_pos_a);
140
141         strncpy(tmp, _bot_aln.c_str() + start_base, len);
142         tmp[len] = 0;
143         fl_draw(tmp, border + w, y_pos_b);
144       }
145     }
146   } 
147
148   // handle other stuff: labels.
149   draw_labels();
150
151   fl_pop_clip();
152
153   return;
154 }
155
156 //
157 // handle -- deal with events
158 //
159
160 int AlignedPairSequenceView::handle(int event)
161 {
162   int key, ret;
163
164   switch(event) {
165   case FL_FOCUS:
166   case FL_UNFOCUS:
167     return 1;
168   case FL_KEYDOWN:              // scroll left/right given arrow key.
169     key = Fl::event_key();
170     if (key == FL_Left) {
171       scroll_left(ARROW_SCROLL_BY);
172       ret = 1;
173     } else if (key == FL_Right) {
174       scroll_right(ARROW_SCROLL_BY);
175       ret = 1;
176     }
177     break;
178   default:
179     // pass the event on up the widget stack.
180     ret = Fl_Widget::handle(event);
181   }
182   return ret;
183 }
184
185 //
186 // base_to_pos -- convert base coordinates to canvas positions.
187 //
188
189 unsigned int AlignedPairSequenceView::base_to_pos(int base)
190 {
191   float seq_width = (_end - _start);
192   float canvas_width = (float) get_width();
193
194   base = constrain_base(base);
195
196   float convert = canvas_width / seq_width * (float) (base - _start);
197
198   return (int) (convert + border + (ch_width / 2.) + 0.5);
199 }
200
201 //
202 // pos_to_base -- convert canvas positions to base locations.
203 //
204
205 unsigned int AlignedPairSequenceView::pos_to_base(int pos)
206 {
207   float seq_width = (_end - _start);
208   float canvas_width = w() - 2*border;
209
210   if (pos < (int) border) pos = border;
211   float convert = seq_width / canvas_width * (float) (pos - border - ch_width);
212
213   return constrain_base((int) (convert + _start + 0.5));
214 }
215
216 //
217 // get_left -- get the left-most part of the sequence line
218 //
219
220 unsigned int AlignedPairSequenceView::get_left()
221 {
222   return x() + border;
223 }
224
225 //
226 // get_width -- get the width of the sequence line
227 //
228
229 unsigned int AlignedPairSequenceView::get_width()
230 {
231   return w() - 2*border;
232 }
233
234 //
235 // get_mid -- get the midline of the sequence line.
236 //
237
238 unsigned int AlignedPairSequenceView::get_mid()
239 {
240   return (unsigned int) (y() + ((float)(h() / 2.) + .5));
241 }
242
243 //
244 // draw_labels -- draw start/end labels.
245 //
246
247 void AlignedPairSequenceView::draw_labels()
248 {
249   fl_color(FL_BLACK);
250   fl_font(FL_TIMES, 2*half_label_height);
251
252   std::string left, right;
253   _round_coords_for_display(left, right);
254
255   // left label
256   fl_draw((const char *)left.c_str(),
257           x(),
258           get_mid() - half_label_height + 4, label_width,
259           2*half_label_height, FL_ALIGN_CENTER);
260
261   // right label
262   fl_draw((const char*)right.c_str(),
263           x() + w() - border,
264           get_mid() - half_label_height + 6, label_width,
265           2*half_label_height, FL_ALIGN_CENTER);
266  
267 }
268
269 void AlignedPairSequenceView::scroll_left(unsigned int n)
270 {
271   if (_start != 0) {
272     if (_start >= n) {
273       _start -= n;
274     } else {
275       _start = 0;
276     }
277     notify_view();
278     _resize_view(_start, _end);
279     redraw();
280   }
281 }
282
283 void AlignedPairSequenceView::scroll_right(unsigned int n)
284 {
285   _start += n;
286   _resize_view(_start, _end);
287   notify_view();
288   redraw();
289 }
Note: See TracBrowser for help on using the browser.