Implement UI for subanalysis mode
[mussa.git] / alg / glseqbrowser.hpp
1 #ifndef _GLTRACKS_H_
2 #define _GLTRACKS_H_
3 #include <boost/shared_ptr.hpp>
4
5 #include <map>
6 #include <set>
7 #include <vector>
8
9 #include "alg/annotation_colors.hpp"
10 #include "alg/sequence.hpp"
11 #include "alg/glsequence.hpp"
12 #include "alg/sequence_location.hpp"
13 #include "alg/track_region.hpp"
14
15 //! Manage rendering a collection of glSequences
16 class GlSeqBrowser
17 {
18 public:
19   GlSeqBrowser();
20   GlSeqBrowser(const GlSeqBrowser&);
21
22   //! setup the opengl canvas
23   void initializeGL();
24   //! called when our screen canvas is resized
25   void resizeGL(int width, int height);
26   //! render our scene
27   void paintGL() const;
28
29   //! select a region (using canvas coordinates)
30   void selectRegion(int top, int left, int bottom, int right);
31
32   //! border size
33   float border() const;
34
35   //! max world left coordinate
36   float left() const;
37   //! max world right coordinate
38   float right() const;
39
40   void setViewportCenter(float x);
41   //! return world coordinate of the left side of the viewport
42   float viewportLeft() const;
43   //! return world coordinate of the center of the viewport
44   float viewportCenter() const;
45   //! return world coordinate of the right side of the viewport
46   float viewportRight() const;
47   //! return height of the viewport in world coordinates
48   float viewportHeight() const;
49   //! return width of the viewport in world coordinates
50   float viewportWidth() const;
51
52   //! zoom out far enough to show the full size of the sequence
53   double zoomOut();
54   //! zoom in to a reasonable sequence view
55   double zoomToSequence();
56   //! set the current zoom level in (base pairs / pix )
57   //! its a double as zoom levels of [0.01, 1.0] make nice sequence views
58   void setZoom(double zoom_level);
59   //! returns the current zoom level as basepairs per pixel
60   double zoom() const;
61   //! center the provided path in the current viewport
62   void centerOnPath(const std::vector<int>&);
63
64   void setColorMapper(boost::shared_ptr<AnnotationColors> cm);
65   const AnnotationColors& colorMapper();
66
67   //! clear our tracks and connections
68   void clear();
69   //! clear everything related to a selection
70   void clear_selection();
71
72   //! add a sequence to the back of our track container (makes copy of s)
73   void push_sequence(const Sequence& s);
74   //! add a sequence to the back of our track container
75   void push_sequence(boost::shared_ptr<Sequence> s);
76   //! add a glsequence to the back of our track container
77   void push_sequence(GlSequence s);
78   //! return our track container
79   const std::vector<GlSequence>& sequences() const;
80
81   //! clear all the line segments between all the sequences
82   void clear_links();
83   //! define a path
84   void link(const std::vector<int>& path, const std::vector<bool>& isRC, int length);
85   //! set selected paths (it'd be nice if this could be a templated function)
86   void setSelectedPaths(std::vector<int> c);
87   //! returns the index of pathids based on order added by link
88   const std::set<int>& selectedPaths() const;
89
90   //! set selected tracks (it'd be nice if this could be a templated function)
91   void appendSelectedTrack(GLuint track_index, int left, int right);
92
93   //! return list of selected tracks
94   std::list<TrackRegion> selectedTracks() const;
95
96   //! copy sequence from selected track using formating function
97   template<class Item>
98   void copySelectedTracks(std::list<Item>& result, 
99              Item (*format_track)(const Sequence& s, int left, int right));
100   //! copy sequence from selected tracks as FASTA sequences
101   void copySelectedTracksAsFasta(std::string& copy_buffer);
102   //! copy sequence from selected tracks as a list of sequences
103   void copySelectedTracksAsSequences(std::list<Sequence>& result);
104   //! copy sequence from selected tracks as plain sequences
105   void copySelectedTracksAsString(std::string& copy_buffer);
106
107   //! copy tracks as a sequence and its coordinates
108   void copySelectedTracksAsSeqLocation(std::list<SequenceLocation>& result);
109   
110   
111   //! Provide a logical name for a type discriminator for our glName stack
112   enum FeatureType { MussaTrack, MussaSegment };
113
114   //! a useful point class
115   template<class T> struct point {
116     T x;
117     T y;
118
119     point(T x_, T y_):x(x_), y(y_) {}
120   };
121
122   //! a useful rectangle, where 0,0 is in the lower left
123   template<class T> struct rect {
124     T top;
125     T left;
126     T bottom;
127     T right;
128
129     rect() {}
130     rect(T t, T l, T b, T r) : top(t), left(l), bottom(b), right(r) {}
131     T width() { return right - left; }
132     T height() { return top - bottom; }
133     void clear() { top=0; left=0; bottom=0; right=0; }
134   };
135
136   struct Segment
137   {
138     point<float> start;
139     point<float> end;
140     bool reversed;
141     std::set<int> path_ids;
142
143     Segment() : start(0.0, 0.0), end(0.0, 0.0) {}
144     Segment(float x1, float y1, float x2, float y2, bool isRC) 
145       : start(x1, y1), end(x2, y2), reversed(isRC) {}
146   };
147
148   //! data structure holding our line segments
149   /*! the vector is of size track_container.size()-1
150    *  it's indexed by the pair x1, x2 (the two x coordinates between
151    *  the two tracks
152    */
153   typedef std::pair<int, int> segment_key;
154   typedef std::map<segment_key, Segment> pair_segment_map;
155   typedef std::vector<pair_segment_map> path_segment_map_vector;
156   path_segment_map_vector path_segments;
157
158 private:
159   //! recalculate the viewable world
160   /*! depending on the size of our canvas, our zoom level and
161    *  how far we've been offset
162    */
163   void update_viewport(float center, double new_zoom);
164
165   //! determine where all the tracks should be placed
166   void update_layout();
167
168   //! convert opengl selections into the list of paths we should highlight
169   void processSelection(GLuint hits, 
170                         GLuint buffer[], 
171                         GLuint bufsize, 
172                         const rect<float>& r);
173
174   //! master scene drawing function
175   /*! draw is broken out for the opengl selection code
176    */
177   void draw() const;
178   //! draw glsequence tracks
179   void draw_tracks() const;
180   //! draw line segments between tracks
181   void draw_segments() const;
182   //! draw selection box
183   void draw_selection() const;
184
185   //! number of pixels to reserve around the edges of our canvas
186   const int border_width;
187   //! the current viewable region (world coord)
188   rect<float> cur_ortho;
189   //! how many pixels our viewport is (screen coord)
190   point<int> viewport_size;
191   //! the center of our current viewport (world coord) (used for scrollbar)
192   float viewport_center;
193   double zoom_level;
194   boost::shared_ptr<AnnotationColors> color_mapper;
195   //! container of all the GlSequences loaded into our scene
196   std::vector<GlSequence> track_container;
197   //! counter for each path added to us via connect
198   int pathid;
199
200 protected:
201   //! where to draw our box (world coordinates)
202   rect<float> selectedRegion;
203   //! true if we have a selection
204   bool selectedMode;
205   //! indicate which paths are selected
206   std::set<int> selected_paths;
207   //! which track is selected (it only makes sense to have one track selected).
208   std::list<TrackRegion> selected_tracks;
209   typedef std::list<TrackRegion>::iterator selected_track_iterator;
210 };
211 #endif