we can scroll
authorDiane Trout <diane@caltech.edu>
Thu, 9 Mar 2006 03:46:38 +0000 (03:46 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 9 Mar 2006 03:46:38 +0000 (03:46 +0000)
This adds a scrollbar to allow moving the viewport around, and the
scrollbar does stay in the right place as one changes the zoom level.

However there's a bit of weirdness with it. Currently the minimum zoom
level is "2" as, 1 causes the display to be at half size. (probalby
due to the the curOrtho left and right having the scale added and
subtracted from them, respectively).

I also think the scrollbar's going to be very grumpy for sequences larger
than 100k. as its width isn't scaled, and that's going to make a
very hard to control scrollbar.

mussagl.pro
qui/PathScene.cxx
qui/PathScene.h
qui/PathWidget.cxx [new file with mode: 0644]
qui/PathWidget.h [new file with mode: 0644]
qui/PathWindow.cxx

index eb93b39f2e2da14f39553a64e62d1d970dbfe398..1038135cbca3f99c98f4371c30b0565ba3b47457 100644 (file)
@@ -12,6 +12,7 @@ INCLUDEPATH += . alg qui
 
 # Input
 HEADERS += mussa_exceptions.hh \
+           qui/PathWidget.h \
            qui/PathWindow.h \
            qui/PathScene.h \
            qui/ThresholdWidget.h \
@@ -25,6 +26,7 @@ HEADERS += mussa_exceptions.hh \
            alg/parse_options.h \
            alg/sequence.hh
 SOURCES += mussagl.cxx \
+           qui/PathWidget.cxx \
            qui/PathWindow.cxx \
            qui/PathScene.cxx \
            qui/ThresholdWidget.cxx \
index 224ce5d957ca690a3f01e34d85df975aa4288111..2c6577a4c3f7cae9acc997ad7528aae9fd8d9b87 100644 (file)
@@ -23,9 +23,10 @@ PathScene::PathScene(Mussa* analysis, QWidget *parent) :
   viewport_height(0),
   viewport_width(0),
   clipZ(30.0),
-  zoom(0),
+  zoom(2),
   maxOrtho2d(-50.0, -50, 3000000.0, 300.0),
   curOrtho2d(maxOrtho2d),
+  viewport_center(((curOrtho2d.right()-curOrtho2d.left())/2)+curOrtho2d.left()),
   selectedMode(false),
   rubberBand(0),
   drawingBand(false)
@@ -46,6 +47,31 @@ QSize PathScene::sizeHint() const
   return QSize(400, 400);
 }
 
+float PathScene::left()
+{
+  return maxOrtho2d.left();
+}
+
+float PathScene::right()
+{
+  return maxOrtho2d.right();
+}
+
+float PathScene::viewportLeft()
+{
+  return curOrtho2d.left();
+}
+
+float PathScene::viewportRight()
+{
+  return curOrtho2d.right();
+}
+
+float PathScene::viewportCenter()
+{
+  return viewport_center;
+}
+
 static float max(float a, float b)
 {
   if ( a < b) 
@@ -62,26 +88,36 @@ static float min(float a, float b)
     return b;
 }
 
-void PathScene::setZoom(int newZoom)
+void PathScene::updateViewport(float center, int new_zoom)
 {
-  std::cout << newZoom << " " << zoom << std::endl;
-  if (zoom != newZoom) {
-    // try to figure out where we should be now?
+  float max_width = maxOrtho2d.width();
+  if (new_zoom < 1) new_zoom = 1;
+  float new_max_width = max_width / new_zoom;
+  //curOrtho2d.setLeft(max(center-new_max_width, maxOrtho2d.left()));
+  //curOrtho2d.setRight(min(center+new_max_width, maxOrtho2d.right()));
+  curOrtho2d.setLeft(center-new_max_width);
+  curOrtho2d.setRight(center+new_max_width);
+  emit viewportChanged();
+}
+
+void PathScene::setViewportX(float x)
+{
+  cout << "setViewportX " << x << " " << curOrtho2d.left() << endl;
+  //hopefully this calculates a sufficiently reasonable == for a float
+  if (x != viewport_center )
+  {
+    updateViewport(x, zoom);
+    viewport_center = x;
+    update();
+  }
+}
 
-    float width = maxOrtho2d.width();
-    std::cout << "max width " << width 
-              << " max left " << maxOrtho2d.left()
-              << " max right " << maxOrtho2d.right() << std::endl;
-    float newWidth = width / newZoom;
-    std::cout << "new width" << newWidth<< std::endl;
-    float center = curOrtho2d.width()/2 + curOrtho2d.left();
-    std::cout << "l: " << curOrtho2d.left() << " r: " << curOrtho2d.right() 
-              << " ctr: " << center << std::endl;
-    curOrtho2d.setLeft(max(center-newWidth, maxOrtho2d.left()));
-    curOrtho2d.setRight(min(center+newWidth, maxOrtho2d.right()));
-    std::cout << "nl: " << curOrtho2d.left() << " nr: " << curOrtho2d.right()
-              << std::endl;
-    zoom = newZoom;
+void PathScene::setZoom(int new_zoom)
+{
+  if (zoom != new_zoom) {
+    // try to figure out where we should be now?
+    updateViewport(viewport_center, new_zoom);
+    zoom = new_zoom;
     update();
   }
 }
@@ -237,6 +273,7 @@ void PathScene::updateScene()
   maxOrtho2d.setWidth(max_base_pairs + 100.0);
   maxOrtho2d.setHeight((mussaAnalysis->sequences().size()) * 100 );
   curOrtho2d = maxOrtho2d;
+  viewport_center = (curOrtho2d.right()-curOrtho2d.left())/2+curOrtho2d.left();
 }
 
 void PathScene::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize)
index 4fc639a8fbc4687bb98366289d06519acf02ee1b..4819c6715bbd8eee7bdbc901dfef12a7c591b3ee 100644 (file)
@@ -27,8 +27,17 @@ public:
   Mussa* mussaAnalysis;
   std::vector<GlSequence> tracks;
 
+  float left();
+  float right();
+  float viewportLeft();
+  float viewportRight();
+  float viewportCenter();
+    
 public slots:
   void setClipPlane(int z);
+  //! set the center of the current viewport
+  void setViewportX(float x);
+  //! set our magnification level
   void setZoom(int);
   //! load a mussa parameter file (which specifies an analysis to run)
   void loadMupa( );
@@ -42,6 +51,7 @@ public slots:
 signals:
   //! emitted when our analysis has changed
   void analysisUpdated();
+  void viewportChanged();
 
 protected:
   int viewport_height;
@@ -50,16 +60,20 @@ protected:
   int zoom;
   QRectF maxOrtho2d;
   QRectF curOrtho2d;
-  // true if we have a selection
+  //! where the "center" of the viewport is
+  float viewport_center;
+  //! true if we have a selection
   bool selectedMode;
-  // indicate which paths are selected
+  //! indicate which paths are selected
   std::vector<bool> selectedPaths;
-  // which track is selected (it only makes sense to have one track selected).
+  //! which track is selected (it only makes sense to have one track selected).
   unsigned int selectedTrack;
 
   void initializeGL();
   void resizeGL(int width, int height);
   void paintGL();
+  // recompute our current viewport dimensions, used by setViewportX & setZoom
+  void updateViewport(float left, int new_zoom);
 
   void mussaesque();
   //! draw all of our sequence tracks
diff --git a/qui/PathWidget.cxx b/qui/PathWidget.cxx
new file mode 100644 (file)
index 0000000..7c72971
--- /dev/null
@@ -0,0 +1,54 @@
+#include <iostream>
+
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include "qui/PathScene.h"
+#include "qui/PathWidget.h"
+
+#include <math.h>
+using namespace std;
+
+// whats the maximum reasonable range for a scrollbar
+const float max_scrollbar_range = 100000;
+
+PathWidget::PathWidget(PathScene *scene, QWidget *parent) :
+  QWidget(parent),
+  scene(scene),
+  viewportBar(Qt::Horizontal)
+{
+  QVBoxLayout *layout = new QVBoxLayout;
+
+  layout->addWidget(scene);
+  layout->addWidget(&viewportBar);
+
+  connect(&viewportBar, SIGNAL(valueChanged(int)), this, SLOT(setViewportX(int)));
+  connect(scene, SIGNAL(viewportChanged()), this, SLOT(updateScrollBar()));
+  setLayout(layout);
+
+  // sets range & scale
+  updateScrollBar();
+}
+
+void PathWidget::updateScrollBar()
+{
+  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);
+}
+
+void PathWidget::setViewportX(int x)
+{
+  if (x != thumb) {
+    thumb = x;
+    cout << "pathwidget " << x << " " << thumb << " " << viewportBar.value() << endl;
+    scene->setViewportX(thumb);
+  }
+}
diff --git a/qui/PathWidget.h b/qui/PathWidget.h
new file mode 100644 (file)
index 0000000..32c1396
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _PATH_WIDGET_H_
+#define _PATH_WIDGET_H_
+
+#include <QScrollBar>
+#include <QWidget>
+class PathScene;
+
+class PathWidget : public QWidget
+{
+  Q_OBJECT 
+
+public:
+  PathWidget(PathScene *, QWidget *parent=0);
+
+public slots:
+  //! update the scrollbar with current viewport information
+  void updateScrollBar();
+  //! update scene with the properly scalled scrollbar offset
+  void setViewportX(int x);
+
+private:
+  PathScene *scene;
+  QScrollBar viewportBar;
+  int thumb;
+
+  float range;
+  float scale;
+
+
+};
+
+#endif
index d263b4590e68ba437b93f200b646c21a56ba5e6b..3048dec2d6124d9f671f7c41890f8bc886830afb 100644 (file)
@@ -1,11 +1,11 @@
-#include "qui/PathWindow.h"
-
 #include <QAction>
 #include <QDir>
 #include <QFileDialog>
+#include <QHBoxLayout>
 #include <QIcon>
 #include <QMenuBar>
 #include <QMessageBox>
+#include <QScrollBar>
 #include <QSpinBox>
 #include <QStatusBar>
 #include <QString>
@@ -13,6 +13,8 @@
 #include <QWhatsThis>
 
 #include "qui/PathScene.h"
+#include "qui/PathWidget.h"
+#include "qui/PathWindow.h"
 #include "qui/ThresholdWidget.h"
 #include "qui/ImageSaveDialog.h"
 
@@ -30,14 +32,16 @@ PathWindow::PathWindow(Mussa *analysis, QWidget *) :
   // a segfault when using WhatsThis feature with 
   // opengl widget.
   scene->setWhatsThis(tr("Mussa in OpenGL!"));
-  setCentralWidget(scene);
+  // make a widget so we can have a scroll bar
+  PathWidget *path_widget = new PathWidget(scene, this);
+  setCentralWidget(path_widget);
 
   mussaViewTB = new QToolBar("Path Views");
   mussaViewTB->addAction(toggleMotifsAction);
 
   QSpinBox *zoom = new QSpinBox();
   zoom->setWhatsThis("zoom magnification factor");
-  zoom->setRange(0,1000);
+  zoom->setRange(2,1000);
   mussaViewTB->addWidget(zoom);
   connect(zoom, SIGNAL(valueChanged(int)), scene, SLOT(setZoom(int)));