track labels
authorDiane Trout <diane@caltech.edu>
Thu, 16 Mar 2006 08:14:36 +0000 (08:14 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 16 Mar 2006 08:14:36 +0000 (08:14 +0000)
ticket:3
This adds two side bars to the PathWidget that show the current position
(and the total length of the sequence, and should show the name).

Scrolling the viewport around makes the position number change too.
(Which revealed a bug that glsequence.leftbase would return values larger
than the sequence).

I also fixed the default size hint.

However all is not completely well, I really need to specialize the
right and left sidebars. And there were way too many classes created for
trying to handle all the user interface widgets. And I'm the locations
of the various signals and updating code could certainly be better thought
out.

17 files changed:
alg/glsequence.cpp
alg/mussa.cpp
alg/mussa.hpp
alg/test/module.mk
alg/test/test_glsequence.cpp
mussagl.pro
qui/PathScene.cpp
qui/PathScene.hpp
qui/PathSidebar.cpp [new file with mode: 0644]
qui/PathSidebar.hpp [new file with mode: 0644]
qui/PathWidget.cpp
qui/PathWidget.hpp
qui/PathWindow.cpp
qui/ScrollableScene.cpp [new file with mode: 0644]
qui/ScrollableScene.hpp [new file with mode: 0644]
qui/SequenceDescription.cpp [new file with mode: 0644]
qui/SequenceDescription.hpp [new file with mode: 0644]

index d802d6284f0878d5e63f4ffd83eb86947e82ad74..aaedf183fdf9823d0914297521a0f0838fa7065c 100644 (file)
@@ -86,6 +86,8 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const
   left = ceil(left);
   if (left < seq_x)
     return 0;
+  else if (left > seq.size() )
+    return seq.size();
   else
     return (Sequence::size_type)left;
 }
index fa54eb2f83eed17b58960d4a6cfd3c3f9ccb195e..ea3fb23a57d5b34c9ba06ad79ebef288870448e4 100644 (file)
@@ -107,6 +107,11 @@ Mussa::set_soft_thres(int sft_thres)
   soft_thres = sft_thres;
 }
 
+int Mussa::get_soft_thres() const
+{
+  return soft_thres;
+}
+
 void
 Mussa::set_analysis_mode(enum analysis_modes new_ana_mode)
 {
index ded2a8b77f62d3072a9f963eef8247127642c7e2..8cf8ffa771644be5264b48f8263e2570816f7a75 100644 (file)
@@ -68,7 +68,8 @@ class Mussa
     //! get number of bases that must match for a window to be saved
     int get_threshold() const;
     void set_soft_thres(int sft_thres);
-    
+    int get_soft_thres() const;
     void set_analysis_mode(enum analysis_modes new_ana_mode);
     enum analysis_modes get_analysis_mode() const;
     //! return a string name for an analysis mode
index 81c8cce3239ba1dac33e63a381156978a0b1e56c..63bf40824b8dc6ed9f97ab3c544ef863c01346b7 100644 (file)
@@ -5,7 +5,7 @@ SOURCES.cpp := test_annotation_color.cpp \
                test_flp.cpp \
                test_glsequence.cpp \
                test_gltracks.cpp \
-                                                        test_color.cpp \
+               test_color.cpp \
                test_main.cpp \
                test_mussa.cpp \
                test_nway.cpp \
index 563af535f4901b8f727e54ddcf44d92df110c892..81443a5a1e25c9ff2017d716daf8e736f2e08887 100644 (file)
@@ -106,6 +106,7 @@ BOOST_AUTO_TEST_CASE( glsequence_leftright_base )
 
   BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 );
   BOOST_CHECK_EQUAL( glseq.leftbase(   0.5 ), 1 );
+  BOOST_CHECK_EQUAL( glseq.leftbase( 500.0 ), seq_string.size() );
   BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() );
   BOOST_CHECK_EQUAL( glseq.rightbase( seq_string.size()-0.5),
                      seq_string.size()-1);
index 639ee431e956f33e3dee436c20cc8031ee9d26c7..69b137839d65cdeb8939f44d8096554a11eedbeb 100644 (file)
@@ -15,6 +15,9 @@ HEADERS += mussa_exceptions.hpp \
            qui/PathWidget.hpp \
            qui/PathWindow.hpp \
            qui/PathScene.hpp \
+           qui/PathSidebar.hpp \
+           qui/ScrollableScene.hpp \
+           qui/SequenceDescription.hpp \
            qui/ThresholdWidget.hpp \
            qui/ImageScaler.hpp \
            qui/ImageSaveDialog.hpp \
@@ -32,6 +35,9 @@ SOURCES += mussagl.cpp \
            qui/PathWidget.cpp \
            qui/PathWindow.cpp \
            qui/PathScene.cpp \
+           qui/PathSidebar.cpp \
+           qui/ScrollableScene.cpp \
+           qui/SequenceDescription.cpp \
            qui/ThresholdWidget.cpp \
            qui/ImageScaler.cpp \
            qui/ImageSaveDialog.cpp \
@@ -47,13 +53,7 @@ SOURCES += mussagl.cpp \
            alg/nway_other.cpp \
            alg/nway_paths.cpp \
            alg/parse_options.cpp \
-#           alg/nway_refine.cpp \
            alg/sequence.cpp 
-#           test/test_flp.cpp \
-#           test/test_main.cpp \
-#           test/test_mussa.cpp \
-#           test/test_nway.cpp \
-#           test/test_sequence.cpp 
 
 LIBS += -lm 
 QT += opengl
index ccbd7e0f0e758ea6686f908aa9fef01f0324d651..4a488826de29a4a572f7cee2aa13bdcbca89849f 100644 (file)
@@ -26,7 +26,8 @@ PathScene::PathScene(QWidget *parent)
 
 QSize PathScene::sizeHint() const
 {
-  return QSize((int)GlTracks::viewportHeight(), (int)GlTracks::viewportWidth());
+  //return QSize((int)GlTracks::viewportHeight(), (int)GlTracks::viewportWidth());
+  return QSize(600, 400);
 }
 
 void PathScene::setViewportCenter(float x)
@@ -68,6 +69,24 @@ void PathScene::setClipPlane(int )
 */
 }
 
+void PathScene::clear()
+{
+  GlTracks::clear();
+  emit tracksChanged();
+}
+
+void PathScene::push_sequence(const Sequence &s)
+{
+  GlTracks::push_sequence(s);
+  emit tracksChanged();
+}
+
+void PathScene::push_sequence(GlSequence &gs)
+{
+  GlTracks::push_sequence(gs);
+  emit tracksChanged();
+}
+
 ////////////////////
 // Rendering code
 void PathScene::initializeGL()
index 7433907df35a909db215c331ca9cee6a25b907f5..ef4a357edd5433840ead7244e433b060122155ce 100644 (file)
@@ -24,7 +24,11 @@ public:
   PathScene(QWidget *parent=0);
 
   QSize sizeHint() const;
-    
+
+  void clear();
+  void push_sequence(const Sequence &s);
+  void push_sequence(GlSequence &);
+      
 public slots:
   void setClipPlane(int z);
   //! set the center of the current viewport
@@ -33,8 +37,8 @@ public slots:
   void setZoom(int);
 
 signals:
-  //! emitted when our analysis has changed
-  void analysisUpdated();
+  //! emited when someone adds to our list of tracks
+  void tracksChanged();
   void viewportChanged();
 
 private:
diff --git a/qui/PathSidebar.cpp b/qui/PathSidebar.cpp
new file mode 100644 (file)
index 0000000..50bf9cc
--- /dev/null
@@ -0,0 +1,35 @@
+#include "qui/PathSidebar.hpp"
+#include "alg/glsequence.hpp"
+
+using namespace std;
+
+PathSidebar::PathSidebar(QWidget* parent)
+  : QWidget(parent)
+{
+  setLayout(&layout);
+}
+
+void PathSidebar::updateSidebar(PathScene& scene)
+{
+  for (vector<SequenceDescription *>::iterator desc_i = descriptions.begin();
+       desc_i != descriptions.end();
+       ++desc_i)
+  {
+    layout.removeWidget(*desc_i);
+  }
+  descriptions.clear();
+  cout << "sidebar " << scene.tracks().size() << endl;
+  for (vector<GlSequence>::const_iterator track_i = scene.tracks().begin();
+       track_i != scene.tracks().end();
+       ++track_i)
+  {
+    cout << "  " << track_i->sequence().length() << endl;
+    SequenceDescription *desc = new SequenceDescription(this);
+    //disc->setName(track_i->sequence().name());
+    desc->setLength(track_i->sequence().length());
+    //desc->setPosition(track_i->sequence().length());
+    descriptions.push_back(desc);
+    layout.addWidget(desc);
+  }
+  setLayout(&layout);
+}
diff --git a/qui/PathSidebar.hpp b/qui/PathSidebar.hpp
new file mode 100644 (file)
index 0000000..852f1c9
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _PATH_SIDEBAR_H
+#define _PATH_SIDEBAR_H
+
+#include <vector>
+
+#include <QVBoxLayout>
+#include <QWidget>
+#include "qui/PathScene.hpp"
+#include "qui/SequenceDescription.hpp"
+
+//! store a collection of sequence descriptions for the PathWidget
+class PathSidebar : public QWidget
+{
+public:
+  PathSidebar(QWidget *parent = 0);
+
+  void updateSidebar(PathScene& scene);
+  QVBoxLayout layout;
+  std::vector<SequenceDescription *> descriptions;
+};
+#endif
index 88f886fc13949cb37eac64c134d3f9c5b53d7811..1b4cd525a5b34165540a814f292fdde362b576b4 100644 (file)
@@ -1,54 +1,51 @@
 #include <iostream>
 
+#include <QLabel>
+#include <QScrollBar>
+#include <QSpacerItem>
+#include <QSplitter>
 #include <QVBoxLayout>
 #include <QWidget>
 
 #include "qui/PathScene.hpp"
 #include "qui/PathWidget.hpp"
+#include "qui/ScrollableScene.hpp"
+#include "qui/SequenceDescription.hpp"
+#include "alg/glsequence.hpp"
 
 #include <math.h>
 using namespace std;
 
-// whats the maximum reasonable range for a scrollbar
-const float max_scrollbar_range = 100000;
-
-PathWidget::PathWidget(QWidget *parent) :
-  QWidget(parent),
-  viewportBar(Qt::Horizontal)
+PathWidget::PathWidget(QWidget *parent)
+  : QSplitter(parent),
+    scrollable_scene(parent)
 {
-  QVBoxLayout *layout = new QVBoxLayout;
-
-  layout->addWidget(&scene);
-  layout->addWidget(&viewportBar);
+  setOrientation(Qt::Horizontal);
 
-  connect(&viewportBar, SIGNAL(valueChanged(int)), 
-          this, SLOT(setViewportCenter(int)));
-  connect(&scene, SIGNAL(viewportChanged()), 
-          this, SLOT(updateScrollBar()));
-  setLayout(layout);
+  addWidget(&left_sidebar);
+  addWidget(&scrollable_scene);
+  addWidget(&right_sidebar);
 
-  // sets range & scale
-  updateScrollBar();
+  connect(&scrollable_scene.scene(), SIGNAL(viewportChanged()),
+          this, SLOT(updatePosition()));
 }
 
-void PathWidget::updateScrollBar()
+void PathWidget::updateTracks()
 {
-  float max_right = scene.right();
-  float max_left = scene.left();
-  float max_range = max_right - max_left;
-  float cur_left = scene.viewportLeft();
-  float cur_right = scene.viewportRight();
-  float cur_center = ((cur_right-cur_left)/2)+cur_left;
-  // set range to min
-  thumb = (int)cur_center;
-  viewportBar.setRange((int)max_left, (int)max_right);
-  viewportBar.setValue(thumb);
+  left_sidebar.updateSidebar(scrollable_scene.scene());
+  right_sidebar.updateSidebar(scrollable_scene.scene());
+  updatePosition();
 }
 
-void PathWidget::setViewportCenter(int x)
+void PathWidget::updatePosition()
 {
-  if (x != thumb) {
-    thumb = x;
-    scene.setViewportCenter(thumb);
+  const PathScene& scene = scrollable_scene.scene();
+  const vector<GlSequence> &tracks = scene.tracks();
+  vector<SequenceDescription *> left = left_sidebar.descriptions;
+  vector<SequenceDescription *> right = right_sidebar.descriptions;
+  for(size_t i = 0; i != tracks.size() and i != right.size(); ++i)
+  {
+    left[i]->setPosition(tracks[i].leftbase(scene.viewportLeft()));
+    right[i]->setPosition(tracks[i].rightbase(scene.viewportRight()));
   }
 }
index 08c46bb3148b690068da8b6e7765059caf9640bd..7c47f42df7dea310a584215af5ac06292385cbb7 100644 (file)
@@ -1,31 +1,28 @@
 #ifndef _PATH_WIDGET_H_
 #define _PATH_WIDGET_H_
 
-#include <QScrollBar>
-#include <QWidget>
+#include <QSplitter>
 
-#include "qui/PathScene.hpp"
+#include "qui/ScrollableScene.hpp"
+#include "qui/PathSidebar.hpp"
 
-class PathWidget : public QWidget
+class PathWidget : public QSplitter
 {
   Q_OBJECT 
 
 public:
   PathWidget(QWidget *parent=0);
-  PathScene scene;
 
+  PathScene& scene() { return scrollable_scene.scene(); }
+  
 public slots:
-  //! update the scrollbar with current viewport information
-  void updateScrollBar();
-  //! update scene with the properly scalled scrollbar offset
-  void setViewportCenter(int x);
+  //! when a scene changes its tracks lets update some of our meta info
+  void updateTracks();
+  void updatePosition();
 
 private:
-  QScrollBar viewportBar;
-  int thumb;
-
-  float range;
-  float scale;
+  ScrollableScene scrollable_scene;
+  PathSidebar left_sidebar;
+  PathSidebar right_sidebar;
 };
-
 #endif
index 7ffbadc5023dfa5546ec3f69d183b86bcfb80b3b..5a1dc5389234301b1f7559d6bb540b9d34cd0811 100644 (file)
@@ -43,16 +43,16 @@ PathWindow::PathWindow(Mussa *analysis_, QWidget *parent) :
   zoomBox.setRange(2,1000);
   mussaViewTB.addWidget(&zoomBox);
   connect(&zoomBox, SIGNAL(valueChanged(int)), 
-          &path_view.scene, SLOT(setZoom(int)));
+          &path_view.scene(), SLOT(setZoom(int)));
   
   threshold.setRange(19, 30);
   threshold.setThreshold(19);
   //scene->setClipPlane(20);
   // FIXME: for when we get the paths drawn at the appropriate depth
-  //connect(threshold, SIGNAL(thresholdChanged(int)),
-  //        scene, SLOT(setClipPlane(int)));
   //connect(&threshold, SIGNAL(thresholdChanged(int)),
-  //        &scene, SLOT(setSoftThreshold(int)));
+  //        this, SLOT(setClipPlane(int)));
+  connect(&threshold, SIGNAL(thresholdChanged(int)),
+          this, SLOT(setSoftThreshold(int)));
   mussaViewTB.addWidget(&threshold);
 
   addToolBar(&mussaViewTB);
@@ -264,7 +264,7 @@ void PathWindow::loadSavedAnalysis()
 
 void PathWindow::setSoftThreshold(int threshold)
 {
-  if (analysis->get_threshold() != threshold) {
+  if (analysis->get_soft_thres() != threshold) {
     analysis->set_soft_thres(threshold);
     analysis->nway();
     updateLinks();
@@ -293,9 +293,9 @@ void PathWindow::NotImplementedBox()
 void PathWindow::promptSaveOpenGlPixmap()
 {
   QSize size;
-  size = path_view.scene.size();
+  size = path_view.scene().size();
   //Image Save Dialog
-  ImageSaveDialog imageSaveDialog(&path_view.scene, this);
+  ImageSaveDialog imageSaveDialog(&path_view.scene(), this);
   imageSaveDialog.setSize(size.width(), size.height());
   int result = imageSaveDialog.exec();
   cout << "Result: " << result << "\n";
@@ -304,20 +304,21 @@ void PathWindow::promptSaveOpenGlPixmap()
 void PathWindow::updateAnalysis()
 {
   cout << "analysis updated" << endl;
-  path_view.scene.clear();
+  path_view.scene().clear();
   const vector<Sequence>& seqs = analysis->sequences();
   for(vector<Sequence>::const_iterator seq_i = seqs.begin();
       seq_i != seqs.end();
       ++seq_i)
   {
-    path_view.scene.push_sequence(*seq_i);
+    path_view.scene().push_sequence(*seq_i);
   }
   updateLinks();
+  path_view.updateTracks();
 }
 
 void PathWindow::updateLinks()
 {
-  path_view.scene.clear_links();
+  path_view.scene().clear_links();
   bool reversed = false;
   const NwayPaths& nway = analysis->paths();
 
@@ -354,7 +355,8 @@ void PathWindow::updateLinks()
       normalized_path.push_back(x);
       rc_flags.push_back(reversed);
     }
-    path_view.scene.link(normalized_path, rc_flags, path_itor->window_size);
+    path_view.scene().link(normalized_path, rc_flags, path_itor->window_size);
   }
+  path_view.scene().update();
 }
 
diff --git a/qui/ScrollableScene.cpp b/qui/ScrollableScene.cpp
new file mode 100644 (file)
index 0000000..0c3de45
--- /dev/null
@@ -0,0 +1,48 @@
+
+#include <QVBoxLayout>
+
+#include "qui/ScrollableScene.hpp"
+
+ScrollableScene::ScrollableScene(QWidget *parent) :
+  QWidget(parent),
+  viewportBar(Qt::Horizontal)
+{
+  // construct central opengl widget
+  QVBoxLayout *layout = new QVBoxLayout;
+
+  layout->addWidget(&path_scene);
+  layout->addWidget(&viewportBar);
+
+  connect(&viewportBar, SIGNAL(valueChanged(int)), 
+          this, SLOT(setViewportCenter(int)));
+  connect(&path_scene, SIGNAL(viewportChanged()), 
+          this, SLOT(updateScrollBar()));
+
+  setLayout(layout);
+
+  // sets range & scale
+  updateScrollBar();
+}
+
+void ScrollableScene::updateScrollBar()
+{
+  float max_right = path_scene.right();
+  float max_left = path_scene.left();
+  float max_range = max_right - max_left;
+  float cur_left = path_scene.viewportLeft();
+  float cur_right = path_scene.viewportRight();
+  float cur_center = ((cur_right-cur_left)/2)+cur_left;
+  // set range to min
+  thumb = (int)cur_center;
+  viewportBar.setRange((int)max_left, (int)max_right);
+  viewportBar.setValue(thumb);
+}
+
+void ScrollableScene::setViewportCenter(int x)
+{
+  if (x != thumb) {
+    thumb = x;
+    path_scene.setViewportCenter(thumb);
+  }
+}
+
diff --git a/qui/ScrollableScene.hpp b/qui/ScrollableScene.hpp
new file mode 100644 (file)
index 0000000..4b90e53
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _SCROLLABLE_SCENE_H_
+#define _SCROLLABLE_SCENE_H_
+
+#include <QScrollBar>
+#include <QWidget>
+#include "qui/PathScene.hpp"
+
+class ScrollableScene : public QWidget
+{
+  Q_OBJECT 
+
+public:
+  ScrollableScene(QWidget *parent=0);
+  PathScene path_scene;
+
+  PathScene& scene() { return path_scene; }
+public slots:
+  //! update the scrollbar with current viewport information
+  void updateScrollBar();
+  //! update scene with the properly scalled scrollbar offset
+  void setViewportCenter(int x);
+
+private:
+  QScrollBar viewportBar;
+  int thumb;
+
+  float range;
+  float scale;
+};
+
+#endif
diff --git a/qui/SequenceDescription.cpp b/qui/SequenceDescription.cpp
new file mode 100644 (file)
index 0000000..130483b
--- /dev/null
@@ -0,0 +1,45 @@
+#include "qui/SequenceDescription.hpp"
+
+#include <QVBoxLayout>
+
+using namespace std;
+
+SequenceDescription::SequenceDescription(QWidget *parent)
+  : QWidget(parent)
+{
+  createWidget();
+}
+
+SequenceDescription::SequenceDescription(string& name, float length, 
+                                         QWidget *parent)
+  : QWidget(parent)
+{
+  setName(name);
+  setLength(length);
+  createWidget();
+}
+
+void SequenceDescription::createWidget()
+{
+  QLayout *layout = new QVBoxLayout;
+  layout->setSpacing(2);
+  layout->addWidget(&name_label);
+  layout->addWidget(&length_label);
+  layout->addWidget(&position_label);
+  setLayout(layout);
+}
+
+void SequenceDescription::setLength(float length)
+{
+  QString s;
+  if (length > 1000) {
+    length /= 1000;
+    s.setNum(length, 'f', 2);
+    s += "kb";
+  } else {
+    s.setNum(length);
+    s += "b";
+  }
+  length_label.setText(s);
+}
+
diff --git a/qui/SequenceDescription.hpp b/qui/SequenceDescription.hpp
new file mode 100644 (file)
index 0000000..88e01ef
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _SEQUENCE_DESCRIPTION_H
+#define _SEQUENCE_DESCRIPTION_H
+
+#include <string>
+
+#include <QString>
+#include <QLabel>
+#include <QWidget>
+
+class SequenceDescription : public QWidget
+{
+  Q_OBJECT 
+
+public:
+  SequenceDescription(QWidget *parent=0);
+  SequenceDescription(std::string& name, float length, QWidget *parent=0);
+
+  void setName(std::string& name) { name_label.setText(name.c_str()); }
+  void setLength(float length);
+  void setPosition(int pos) { QString s; position_label.setText(s.setNum(pos));}
+
+private:
+  QLabel name_label;
+  QLabel length_label;
+  QLabel position_label;
+
+  void createWidget();
+};
+#endif