From 5fb1cdfe5bdd48406e58441b354fc87d3d3c582e Mon Sep 17 00:00:00 2001
From: "Tim E. Real" <termtech@rogers.com>
Date: Sat, 26 Jan 2013 01:15:35 +0000
Subject: Feature/fix: Zoom at cursor! Zoom now zooms about cursor.

---
 muse2/ChangeLog                    |  6 ++++
 muse2/muse/arranger/arranger.cpp   | 50 ++++++++++++++++--------------
 muse2/muse/arranger/arranger.h     |  4 +--
 muse2/muse/midiedit/drumedit.cpp   | 35 ++++++++++-----------
 muse2/muse/midiedit/pianoroll.cpp  | 34 ++++++++++----------
 muse2/muse/midieditor.cpp          | 28 ++++++-----------
 muse2/muse/midieditor.h            |  3 +-
 muse2/muse/waveedit/wavecanvas.cpp |  9 ++----
 muse2/muse/waveedit/waveedit.cpp   | 63 ++++++++++++++++----------------------
 muse2/muse/waveedit/waveedit.h     |  3 +-
 muse2/muse/wavetrack.cpp           | 44 --------------------------
 muse2/muse/widgets/canvas.cpp      |  6 +---
 muse2/muse/widgets/canvas.h        |  3 +-
 muse2/muse/widgets/scrollscale.cpp | 29 ++++++++++++++----
 muse2/muse/widgets/scrollscale.h   |  7 ++---
 15 files changed, 135 insertions(+), 189 deletions(-)

(limited to 'muse2')

diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 1e420bee..411536b0 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,9 @@
+25.01.2013:
+         * Feature/fix: Zoom at cursor! Zoom Ctl+PgUp/PgDown (defaults) and Ctl+MouseWheel now zoom about cursor. (Tim)
+           Eliminated redundant call in ScrollScale::setMag(), by blocking signals.
+           Consolidated all HorizontalZoomIn and HorizontalZoomOut functions into a single HorizontalZoom.
+           Added eight more 'quick zoom' levels to class ScrollScale.
+           Modified all HorizontalZoom functions to pass cursor offset, and use it in ScrollScale::setScale().
 19.01.2013:
          - Fixed confused controllers on seek with multiple muted/off midi tracks/parts on same port/channel. (Tim)
            In MidiDevice::handleSeek(): Re-wrote controller value sending section - fixed obeying mute/off section.
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp
index 18886bd1..90a7e8f3 100644
--- a/muse2/muse/arranger/arranger.cpp
+++ b/muse2/muse/arranger/arranger.cpp
@@ -37,6 +37,9 @@
 #include <QVBoxLayout>
 #include <QWheelEvent>
 #include <QPainter>
+#include <QCursor>
+#include <QPoint>
+#include <QRect>
 
 #include "arrangerview.h"
 #include "arranger.h"
@@ -337,7 +340,7 @@ Arranger::Arranger(ArrangerView* parent, const char* name)
       tpolicy.setVerticalStretch(100);
       tracklist->setSizePolicy(tpolicy);
 
-      QWidget* editor = new QWidget(split);
+      editor = new QWidget(split);
       split->setStretchFactor(split->indexOf(editor), 1);
       QSizePolicy epolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
       epolicy.setHorizontalStretch(255);
@@ -474,8 +477,7 @@ Arranger::Arranger(ArrangerView* parent, const char* name)
       connect(list, SIGNAL(keyPressExt(QKeyEvent*)), canvas, SLOT(redirKeypress(QKeyEvent*)));
       connect(canvas, SIGNAL(selectTrackAbove()), list, SLOT(selectTrackAbove()));
       connect(canvas, SIGNAL(selectTrackBelow()), list, SLOT(selectTrackBelow()));
-      connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));
-      connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut()));
+      connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int)));
       connect(lenEntry,           SIGNAL(returnPressed()), SLOT(focusCanvas()));
       connect(lenEntry,           SIGNAL(escapePressed()), SLOT(focusCanvas()));
       connect(globalPitchSpinBox, SIGNAL(returnPressed()), SLOT(focusCanvas()));
@@ -1205,41 +1207,43 @@ void Arranger::keyPressEvent(QKeyEvent* event)
         key+= Qt::CTRL;
 
   if (key == shortcuts[SHRT_ZOOM_IN].key) {
-        horizontalZoomIn();
+        int offset = 0;
+        QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+        QPoint sp = editor->mapFromGlobal(QCursor::pos());
+        if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->height())
+          offset = cp.x();
+        horizontalZoom(true, offset);  
         return;
         }
   else if (key == shortcuts[SHRT_ZOOM_OUT].key) {
-        horizontalZoomOut();
+        int offset = 0;
+        QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+        QPoint sp = editor->mapFromGlobal(QCursor::pos());
+        if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < editor->height())
+          offset = cp.x();
+        horizontalZoom(false, offset);  
         return;
         }
 
   QWidget::keyPressEvent(event);
 }
 
-void Arranger::horizontalZoomIn()
+void Arranger::horizontalZoom(bool zoom_in, int pos_offset)
 {
   int mag = hscroll->mag();
   int zoomlvl = ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
+  if(zoom_in)
+  {
+    if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
         zoomlvl++;
-
-  int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
-}
-
-void Arranger::horizontalZoomOut()
-{
-  int mag = hscroll->mag();
-  int zoomlvl = ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl > 1)
+  }
+  else
+  {
+    if (zoomlvl > 1)
         zoomlvl--;
-
+  }
   int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
+  hscroll->setMag(newmag, pos_offset);
 }
 
 } // namespace MusEGui
diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h
index 80f1b24c..e56a187d 100644
--- a/muse2/muse/arranger/arranger.h
+++ b/muse2/muse/arranger/arranger.h
@@ -116,6 +116,7 @@ class Arranger : public QWidget {
       static QByteArray header_state;
 
       ArrangerView* _parentWin;
+      QWidget* editor;
       int _quant, _raster;
       PartCanvas* canvas;
       ScrollScale* hscroll;
@@ -165,8 +166,7 @@ class Arranger : public QWidget {
       void setTempo100();
       void setTempo200();
       void verticalScrollSetYpos(unsigned);
-      void horizontalZoomIn();
-      void horizontalZoomOut();
+      void horizontalZoom(bool zoom_in, int pos_offset);
       
    signals:
       void editPart(MusECore::Track*);
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index e52bc687..c64641e9 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -39,6 +39,9 @@
 #include <QSettings>
 #include <QComboBox>
 #include <QLabel>
+#include <QCursor>
+#include <QPoint>
+#include <QRect>
 
 #include "drumedit.h"
 #include "mtscale.h"
@@ -504,8 +507,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
       canvas->setCanvasTools(drumeditTools);
       canvas->setFocus();
       connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
-      connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));
-      connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut()));
+      connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int)));
       connect(canvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool)));
       time->setOrigin(offset, 0);
 
@@ -1518,26 +1520,21 @@ void DrumEdit::keyPressEvent(QKeyEvent* event)
             return;
             }
       else if (key == shortcuts[SHRT_ZOOM_IN].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
-                  zoomlvl++;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = split1->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height())
+              offset = cp.x();
+            horizontalZoom(true, offset);
             return;
             }
       else if (key == shortcuts[SHRT_ZOOM_OUT].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl > 1)
-                  zoomlvl--;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = split1->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < split1->height())
+              offset = cp.x();
+            horizontalZoom(false, offset);
             return;
             }
       else if (key == shortcuts[SHRT_SCROLL_LEFT].key) {
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 740a5773..9fc835a1 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -42,6 +42,9 @@
 #include <QMimeData>
 #include <QScrollArea>
 #include <QSettings>
+#include <QCursor>
+#include <QPoint>
+#include <QRect>
 
 #include <stdio.h>
 
@@ -372,8 +375,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
       canvas->setCanvasTools(pianorollTools);
       canvas->setFocus();
       connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
-      connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));
-      connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut()));
+      connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int)));
       time->setOrigin(offset, 0);
 
       gridS1->setRowStretch(2, 100);
@@ -1198,25 +1200,21 @@ void PianoRoll::keyPressEvent(QKeyEvent* event)
             return;
             }
       else if (key == shortcuts[SHRT_ZOOM_IN].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
-                  zoomlvl++;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = splitter->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height())
+              offset = cp.x(); 
+            horizontalZoom(true, offset);
             return;
             }
       else if (key == shortcuts[SHRT_ZOOM_OUT].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl > 1)
-                  zoomlvl--;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = splitter->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < splitter->height())
+              offset = cp.x();
+            horizontalZoom(false, offset);
             return;
             }
       else if (key == shortcuts[SHRT_GOTO_CPOS].key) {
diff --git a/muse2/muse/midieditor.cpp b/muse2/muse/midieditor.cpp
index c00a7049..50cc6003 100644
--- a/muse2/muse/midieditor.cpp
+++ b/muse2/muse/midieditor.cpp
@@ -245,30 +245,22 @@ void MidiEditor::setCurCanvasPart(MusECore::Part* part)
     canvas->setCurrentPart(part); 
 }
 
-void MidiEditor::horizontalZoomIn()
+void MidiEditor::horizontalZoom(bool zoom_in, int pos_offset)
 {
   int mag = hscroll->mag();
   int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
+  if(zoom_in)
+  {
+    if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
         zoomlvl++;
-
-  int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
-}
-
-void MidiEditor::horizontalZoomOut()
-{
-  int mag = hscroll->mag();
-  int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl > 1)
+  }
+  else
+  {
+    if (zoomlvl > 1)
         zoomlvl--;
-
+  }
   int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
+  hscroll->setMag(newmag, pos_offset);
 }
 
 void MidiEditor::addNewParts(const std::map< MusECore::Part*, std::set<MusECore::Part*> >& param)
diff --git a/muse2/muse/midieditor.h b/muse2/muse/midieditor.h
index 541e4e0c..0131fafb 100644
--- a/muse2/muse/midieditor.h
+++ b/muse2/muse/midieditor.h
@@ -81,8 +81,7 @@ class MidiEditor : public TopWin  {
    public slots:
       void songChanged(MusECore::SongChangedFlags_t type);
       void setCurDrumInstrument(int instr);
-      void horizontalZoomIn();
-      void horizontalZoomOut();
+      void horizontalZoom(bool zoom_in, int pos_offset);
 
       virtual void updateHScrollRange() { };
    signals:
diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp
index 1fa070ec..b9a006eb 100644
--- a/muse2/muse/waveedit/wavecanvas.cpp
+++ b/muse2/muse/waveedit/wavecanvas.cpp
@@ -845,7 +845,7 @@ void WaveCanvas::wheelEvent(QWheelEvent* ev)
   bool shift      = keyState & Qt::ShiftModifier;
   bool ctrl       = keyState & Qt::ControlModifier;
 
-  if (shift) { // scroll vertically
+  if (shift) { // scroll horizontally
       int delta       = -ev->delta() / WHEEL_DELTA;
       int xpixelscale = 5*MusECore::fast_log10(rmapxDev(1));
 
@@ -866,13 +866,8 @@ void WaveCanvas::wheelEvent(QWheelEvent* ev)
       //setYPos(newYpos);
       emit horizontalScroll((unsigned)newXpos);
 
-
   } else if (ctrl) {  // zoom horizontally
-    if (ev->delta()>0)
-      emit horizontalZoomIn();
-    else
-      emit horizontalZoomOut();
-
+      emit horizontalZoom(ev->delta()>0, ev->x());
   } else { // scroll horizontally
       emit mouseWheelMoved(ev->delta() / 10);
   }
diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp
index ca98e380..17f3de00 100644
--- a/muse2/muse/waveedit/waveedit.cpp
+++ b/muse2/muse/waveedit/waveedit.cpp
@@ -38,6 +38,9 @@
 #include <QResizeEvent>
 #include <QKeyEvent>
 #include <QSettings>
+#include <QCursor>
+#include <QPoint>
+#include <QRect>
 
 #include "app.h"
 #include "xml.h"
@@ -295,8 +298,7 @@ WaveEdit::WaveEdit(MusECore::PartList* pl)
       ymag->setFixedWidth(16);
       connect(canvas, SIGNAL(mouseWheelMoved(int)), this, SLOT(moveVerticalSlider(int)));
       connect(ymag, SIGNAL(valueChanged(int)), canvas, SLOT(setYScale(int)));
-      connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));
-      connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut()));
+      connect(canvas, SIGNAL(horizontalZoom(bool,int)), SLOT(horizontalZoom(bool,int)));
 
       time->setOrigin(0, 0);
 
@@ -696,25 +698,21 @@ void WaveEdit::keyPressEvent(QKeyEvent* event)
             
       // TODO: New WaveCanvas: Convert some of these to use frames.
       else if (key == shortcuts[SHRT_ZOOM_IN].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
-                  zoomlvl++;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = mainw->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->height())
+              offset = cp.x();
+            horizontalZoom(true, offset);
             return;
             }
       else if (key == shortcuts[SHRT_ZOOM_OUT].key) {
-            int mag = hscroll->mag();
-            int zoomlvl = MusEGui::ScrollScale::getQuickZoomLevel(mag);
-            if (zoomlvl > 1)
-                  zoomlvl--;
-
-            int newmag = MusEGui::ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-            hscroll->setMag(newmag);
-            //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag);
+            int offset = 0;
+            QPoint cp = canvas->mapFromGlobal(QCursor::pos());
+            QPoint sp = mainw->mapFromGlobal(QCursor::pos());
+            if(cp.x() >= 0 && cp.x() < canvas->width() && sp.y() >= 0 && sp.y() < mainw->height())
+              offset = cp.x();
+            horizontalZoom(false, offset);
             return;
             }
       else if (key == shortcuts[SHRT_GOTO_CPOS].key) {
@@ -785,31 +783,22 @@ void WaveEdit::moveVerticalSlider(int val)
       ymag->setValue(ymag->value() + val);
       }
 
-
-void WaveEdit::horizontalZoomIn()
+void WaveEdit::horizontalZoom(bool zoom_in, int pos_offset)
 {
   int mag = hscroll->mag();
   int zoomlvl = ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
+  if(zoom_in)
+  {
+    if (zoomlvl < MusEGui::ScrollScale::zoomLevels-1)
         zoomlvl++;
-
-  int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
-}
-
-void WaveEdit::horizontalZoomOut()
-{
-  int mag = hscroll->mag();
-  int zoomlvl = ScrollScale::getQuickZoomLevel(mag);
-  if (zoomlvl > 1)
+  }
+  else
+  {
+    if (zoomlvl > 1)
         zoomlvl--;
-
+  }
   int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl);
-
-  hscroll->setMag(newmag);
-
+  hscroll->setMag(newmag, pos_offset);
 }
 
 //---------------------------------------------------------
diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h
index f0bcf199..756b4085 100644
--- a/muse2/muse/waveedit/waveedit.h
+++ b/muse2/muse/waveedit/waveedit.h
@@ -101,8 +101,7 @@ class WaveEdit : public MidiEditor {
    public slots:
       void configChanged();
       virtual void updateHScrollRange();
-      void horizontalZoomIn();
-      void horizontalZoomOut();
+      void horizontalZoom(bool zoom_in, int pos_offset);
       void focusCanvas();
 
    signals:
diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp
index 6f38a6d4..c9997eae 100644
--- a/muse2/muse/wavetrack.cpp
+++ b/muse2/muse/wavetrack.cpp
@@ -301,50 +301,6 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float*
       if (!MusEGlobal::audio->isPlaying())
             return false;
       
-      // DELETETHIS 43
-      // Removed by T356. Multiple out route cacheing now handled by AudioTrack::copyData and ::addData.   // REMOVE Tim.
-      /*
-      if (outRoutes()->size() > 1) {
-            if (bufferPos != framePos) {
-                  // Added by Tim. p3.3.16
-                  printf("WaveTrack::getData bufferPos:%d != framePos\n", bufferPos);
-                  
-                  bufferPos = framePos;
-                  if (MusEGlobal::audio->freewheel()) {
-                        // when freewheeling, read data direct from file:
-                        fetchData(bufferPos, nframe, outBuffers);
-                        }
-                  else {
-                        unsigned pos;
-                        if (_prefetchFifo.get(channels, nframe, outBuffers, &pos)) {
-                              printf("WaveTrack::getData(%s) fifo underrun\n",
-                                 name().toLatin1().constData());
-                              return false;
-                              }
-                        if (pos != framePos) {
-                              printf("fifo get error expected %d, got %d\n",
-                                 framePos, pos);
-                              if (MusEGlobal::debugMsg)
-                                    printf("fifo get error expected %d, got %d\n",
-                                       framePos, pos);
-                              while (pos < framePos) {
-                                    if (_prefetchFifo.get(channels, nframe, bp, &pos)) {
-                                          printf("WaveTrack::getData(%s) fifo underrun\n",
-                                             name().toLatin1().constData());
-                                          return false;
-                                          }
-                                    }
-                              }
-                        }
-                  }
-            for (int i = 0; i < channels; ++i)
-                  //memcpy(bp[i], outBuffers[i], nframe * sizeof(float));
-                  AL::dsp->cpy(bp[i], outBuffers[i], nframe);
-            }
-      else {
-      */
-      
-            
             if (MusEGlobal::audio->freewheel()) {
                   
                   // when freewheeling, read data direct from file:
diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp
index f9280ab5..2091631a 100644
--- a/muse2/muse/widgets/canvas.cpp
+++ b/muse2/muse/widgets/canvas.cpp
@@ -508,11 +508,7 @@ void Canvas::wheelEvent(QWheelEvent* ev)
         emit horizontalScroll((unsigned)newXpos);
 
     } else if (ctrl) {  // zoom horizontally
-      if (ev->delta()>0)
-        emit horizontalZoomIn();
-      else
-        emit horizontalZoomOut();
-
+      emit horizontalZoom(ev->delta()>0, ev->x());
     } else { // scroll vertically
         int delta       = ev->delta() / WHEEL_DELTA;
         int ypixelscale = rmapyDev(1);
diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h
index 74de63c5..e85d3db3 100644
--- a/muse2/muse/widgets/canvas.h
+++ b/muse2/muse/widgets/canvas.h
@@ -186,8 +186,7 @@ class Canvas : public View {
       void verticalScroll(unsigned);
       void horizontalScroll(unsigned);
       void horizontalScrollNoLimit(unsigned);
-      void horizontalZoomIn();
-      void horizontalZoomOut();
+      void horizontalZoom(bool zoom_in, int pos_offset);
       void curPartHasChanged(MusECore::Part*);
       
    public:
diff --git a/muse2/muse/widgets/scrollscale.cpp b/muse2/muse/widgets/scrollscale.cpp
index eb03b2a4..d1f54ce0 100644
--- a/muse2/muse/widgets/scrollscale.cpp
+++ b/muse2/muse/widgets/scrollscale.cpp
@@ -42,9 +42,10 @@ namespace MusEGui {
 //    "val" - slider value in range 0-convertQuickZoomLevelToMag(zoomLevels-1)
 //---------------------------------------------------------
 
-void ScrollScale::setScale ( int val )
+void ScrollScale::setScale ( int val, int pos_offset )
 {
 	int off = offset();
+	int old_scale_val = scaleVal;
 	if ( invers )
         val = convertQuickZoomLevelToMag(zoomLevels-1) - val;
 	double min, max;
@@ -107,6 +108,21 @@ void ScrollScale::setScale ( int val )
     pos = off * scaleVal;
     pmax = maxVal * scaleVal - i;
   }
+
+  // Zoom at cursor support...
+  if(pos_offset != 0)
+  {
+    double oscale = old_scale_val;
+    double nscale = scaleVal;
+    if(old_scale_val < 1)
+      oscale = 1.0 / -old_scale_val;
+    if(scaleVal < 1)
+      nscale = 1.0 / -scaleVal;
+    double scale_fact = nscale / oscale;
+    int pos_diff = (int)((double)pos_offset * scale_fact - (double)pos_offset + 0.5);  // 0.5 for round-off
+    pos += pos_diff;
+  }
+  
   if(pos > pmax)
     pos = pmax;
   setPos(pos);
@@ -116,10 +132,12 @@ void ScrollScale::setScale ( int val )
 //   setMag
 //---------------------------------------------------------
 
-void ScrollScale::setMag ( int cs )
+void ScrollScale::setMag ( int cs, int pos_offset )
 {
+	scale->blockSignals(true);
 	scale->setValue ( cs );
-	setScale ( cs );
+	scale->blockSignals(false);
+	setScale ( cs, pos_offset );
 }
 
 //---------------------------------------------------------
@@ -290,7 +308,6 @@ ScrollScale::ScrollScale ( int s1, int s2, int cs, int max_, Qt::Orientation o,
 	box->addWidget ( scale, 5 );
 	setLayout(box);
 	connect ( scale, SIGNAL ( valueChanged ( int ) ), SLOT ( setScale ( int ) ) );
-	///connect ( scale, SIGNAL ( valueChanged ( int ) ), SIGNAL ( lscaleChanged ( int ) ) );  // ??
 	connect ( scroll, SIGNAL ( valueChanged ( int ) ), SIGNAL ( scrollChanged ( int ) ) );
 }
 
@@ -524,8 +541,8 @@ int ScrollScale::convertQuickZoomLevelToMag(int zoomlevel)
       int vals[] = {
             0,   1,   15,  30,  46,  62,  80,  99,  119, 140,
             163, 187, 214, 242, 274, 308, 346, 388, 436, 491,
-            555, 631, 726, 849, 1024, 1200, 1400, 1500, 1800,
-            2100, 2500 };
+            555, 631, 726, 849, 1024, 1200, 1300, 1400, 1500, 1600, 1700, 1800,    
+            1900, 2100, 2200, 2300, 2400, 2500 };  
 
       return vals[zoomlevel];
 }
diff --git a/muse2/muse/widgets/scrollscale.h b/muse2/muse/widgets/scrollscale.h
index a6f18886..38629229 100644
--- a/muse2/muse/widgets/scrollscale.h
+++ b/muse2/muse/widgets/scrollscale.h
@@ -65,13 +65,12 @@ class ScrollScale : public QWidget {
    public slots:
       void setPos(unsigned);
       void setPosNoLimit(unsigned); 
-      void setMag(int);
+      void setMag(int val, int pos_offset = 0);
       void setOffset(int val);
-      void setScale(int);
+      void setScale(int val, int pos_offset = 0);
 
    signals:
       void scaleChanged(int);
-      void lscaleChanged(int);
       void scrollChanged(int);
       void newPage(int);
 
@@ -97,7 +96,7 @@ class ScrollScale : public QWidget {
       int pos2offset(int pos);
       static int getQuickZoomLevel(int mag);
       static int convertQuickZoomLevelToMag(int zoomlvl);
-      const static int zoomLevels = 31;
+      const static int zoomLevels = 38;
       };
 
 } // namespace MusEGui
-- 
cgit v1.2.3