factor out viewport to display scaling functions
[mussa.git] / alg / glseqbrowser.hpp
index fe5423c7a0ff83707e7c93743a054a3e074d8c0a..f88caf5e7e5bb57e4dea0b1ff56f20d4f8c21408 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef _GLTRACKS_H_
 #define _GLTRACKS_H_
+#include <boost/shared_ptr.hpp>
 
 #include <map>
 #include <set>
@@ -8,6 +9,8 @@
 #include "alg/annotation_colors.hpp"
 #include "alg/sequence.hpp"
 #include "alg/glsequence.hpp"
+#include "alg/sequence_location.hpp"
+#include "alg/track_region.hpp"
 
 //! Manage rendering a collection of glSequences
 class GlSeqBrowser
@@ -24,7 +27,9 @@ public:
   void paintGL() const;
 
   //! select a region (using canvas coordinates)
-  void GlSeqBrowser::selectRegion(int top, int left, int bottom, int right);
+  void selectRegion(int top, int left, int bottom, int right);
+  //! turn off selection
+  void clearSelection();
 
   //! border size
   float border() const;
@@ -33,48 +38,98 @@ public:
   float left() const;
   //! max world right coordinate
   float right() const;
+  // return how wide is a pixel in world coordinates?
+  float get_pixel_width() const;
 
   void setViewportCenter(float x);
+  //! return world coordinate of the left side of the viewport
   float viewportLeft() const;
+  //! return world coordinate of the center of the viewport
   float viewportCenter() const;
+  //! return world coordinate of the right side of the viewport
   float viewportRight() const;
+  //! return height of the viewport in world coordinates
   float viewportHeight() const;
+  //! return width of the viewport in world coordinates
   float viewportWidth() const;
+  
+  //! return viewport height in pixels
+  int viewportPixelHeight() const;
+  //! return viewport width in pixels
+  int viewportPixelWidth() const;
+  
+  //! convert x axis from display to world coordinates
+  float viewportXtoWorldX(int x);
+  //! convert y axis from display to world coordinates
+  float viewportYtoWorldY(int y);
 
   //! zoom out far enough to show the full size of the sequence
-  int zoomOut();
+  double zoomOut();
   //! zoom in to a reasonable sequence view
-  int zoomToSequence();
-  //! set the current zoom level in (base pairs / pix ) * 100
-  /*! a zoomlevel of 1 is .01 base pairs per pixel or a rather exploded
-   *  100 pixels per base pair
-   */
-  void setZoom(int zoom_level);
-  //! returns the current zoom level
-  int zoom() const;
+  double zoomToSequence();
+  //! set the current zoom level in (base pairs / pix )
+  //! its a double as zoom levels of [0.01, 1.0] make nice sequence views
+  void setZoom(double zoom_level);
+  //! returns the current zoom level as basepairs per pixel
+  double zoom() const;
+  //! center the provided path in the current viewport
+  void centerOnPath(const std::vector<int>&);
 
-  void setColorMapper(AnnotationColors& cm);
-  AnnotationColors& colorMapper();
+  void setColorMapper(boost::shared_ptr<AnnotationColors> cm);
+  const AnnotationColorsRef colorMapper();
 
   //! clear our tracks and connections
   void clear();
+  //! clear everything related to a selection
+  void clear_selection();
 
+  //! add a sequence to the back of our track container (makes copy of s)
+  void push_sequence(const Sequence& s);
   //! add a sequence to the back of our track container
-  void push_sequence(const Sequence &s);
+  void push_sequence(boost::shared_ptr<Sequence> s);
   //! add a glsequence to the back of our track container
-  void push_sequence(GlSequence &s);
+  void push_sequence(GlSequence s);
+  //! add a glsequence to the back of our track container
+  void push_sequence(boost::shared_ptr<GlSequence> gs);
   //! return our track container
-  const std::vector<GlSequence>& sequences() const;
+  const std::vector<boost::shared_ptr<GlSequence> >& sequences() const;
 
   //! clear all the line segments between all the sequences
   void clear_links();
   //! define a path
   void link(const std::vector<int>& path, const std::vector<bool>& isRC, int length);
+  //! set selected paths (it'd be nice if this could be a templated function)
+  void setSelectedPaths(std::vector<int> c);
   //! returns the index of pathids based on order added by link
   const std::set<int>& selectedPaths() const;
-  //! center the provided path in the current viewport
-  void centerOnPath(const std::vector<int>&);
 
+  //! set selected tracks (it'd be nice if this could be a templated function)
+  void appendSelectedTrack(GLuint track_index, int left, int right);
+
+  //! return list of selected tracks
+  std::list<TrackRegion> selectedTracks() const;
+
+  //! copy sequence from selected track using formating function
+  template<class Item>
+  size_t copySelectedTracks(std::list<Item>& result, 
+             Item (*format_track)(const Sequence& s, int left, int right));
+  //! copy sequence from selected tracks as FASTA sequences
+  /*! \return number of base pairs copied
+   */
+  size_t copySelectedTracksAsFasta(std::string& copy_buffer);
+  //! copy sequence from selected tracks as a list of sequences
+  /*! \return number of base pairs copied
+   */
+  size_t copySelectedTracksAsSequences(std::list<Sequence>& result);
+  //! copy sequence from selected tracks as plain sequences
+  /*! \return number of base pairs copied
+   */
+  size_t copySelectedTracksAsString(std::string& copy_buffer);
+
+  //! copy tracks as a sequence and its coordinates
+  size_t copySelectedTracksAsSeqLocation(std::list<SequenceLocation>& result);
+  
+  
   //! Provide a logical name for a type discriminator for our glName stack
   enum FeatureType { MussaTrack, MussaSegment };
 
@@ -97,6 +152,7 @@ public:
     rect(T t, T l, T b, T r) : top(t), left(l), bottom(b), right(r) {}
     T width() { return right - left; }
     T height() { return top - bottom; }
+    void clear() { top=0; left=0; bottom=0; right=0; }
   };
 
   struct Segment
@@ -104,11 +160,13 @@ public:
     point<float> start;
     point<float> end;
     bool reversed;
+    int length;
+    // each integer represents an index into our list of paths
     std::set<int> path_ids;
 
-    Segment() : start(0.0, 0.0), end(0.0, 0.0) {}
-    Segment(float x1, float y1, float x2, float y2, bool isRC) 
-      : start(x1, y1), end(x2, y2), reversed(isRC) {}
+    Segment() : start(0.0, 0.0), end(0.0, 0.0), reversed(false), length(0) {}
+    Segment(float x1, float y1, float x2, float y2, bool isRC, int length_
+      : start(x1, y1), end(x2, y2), reversed(isRC), length(length_) {}
   };
 
   //! data structure holding our line segments
@@ -116,22 +174,26 @@ public:
    *  it's indexed by the pair x1, x2 (the two x coordinates between
    *  the two tracks
    */
-  typedef std::pair<int, int> segment_key;
+  typedef std::pair<int, int> segment_key;  
   typedef std::map<segment_key, Segment> pair_segment_map;
   typedef std::vector<pair_segment_map> path_segment_map_vector;
   path_segment_map_vector path_segments;
+
 private:
   //! recalculate the viewable world
   /*! depending on the size of our canvas, our zoom level and
    *  how far we've been offset
    */
-  void update_viewport(float center, int new_zoom);
+  void update_viewport(float center, double new_zoom);
 
   //! determine where all the tracks should be placed
   void update_layout();
 
   //! convert opengl selections into the list of paths we should highlight
-  void processSelection(GLuint hits, GLuint buffer[], GLuint bufsize);
+  void processSelection(GLuint hits, 
+                        GLuint buffer[], 
+                        GLuint bufsize, 
+                        const rect<float>& r);
 
   //! master scene drawing function
   /*! draw is broken out for the opengl selection code
@@ -152,22 +214,33 @@ private:
   point<int> viewport_size;
   //! the center of our current viewport (world coord) (used for scrollbar)
   float viewport_center;
-  int zoom_level;
-  AnnotationColors color_mapper;
-  //! container of all the GlSequences loaded into our scene
-  std::vector<GlSequence> track_container;
+  double zoom_level;
+  AnnotationColorsRef color_mapper;
   //! counter for each path added to us via connect
   int pathid;
 
 protected:
-  //! where to draw our box 
+  //! container of all the GlSequences loaded into our scene
+  std::vector<GlSequenceRef > track_container;
+  //! where to draw our box (world coordinates)
   rect<float> selectedRegion;
   //! true if we have a selection
   bool selectedMode;
   //! indicate which paths are selected
   std::set<int> selected_paths;
   //! which track is selected (it only makes sense to have one track selected).
-  std::set<int> selected_tracks;
-
+  std::list<TrackRegion> selected_tracks;
+  typedef std::list<TrackRegion>::iterator selected_track_iterator;
 };
+
+inline float GlSeqBrowser::viewportXtoWorldX(int x) {
+  GLfloat x_scale = cur_ortho.width()/((float)viewport_size.x);
+  return (cur_ortho.left + (x * x_scale));
+}
+
+inline float GlSeqBrowser::viewportYtoWorldY(int y) {
+  GLfloat y_scale = cur_ortho.height()/((float)viewport_size.y);
+  return cur_ortho.top-(y * y_scale);
+}
+
 #endif