changeset 268:70537b0434c4

* Use a command for adding layer measurements
author Chris Cannam
date Tue, 26 Jun 2007 11:08:21 +0000
parents 4ed1446ad604
children 7b58c5e91f20
files layer/Layer.cpp layer/Layer.h view/Pane.cpp view/View.cpp view/View.h
diffstat 5 files changed, 170 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Layer.cpp	Thu Jun 21 16:12:00 2007 +0000
+++ b/layer/Layer.cpp	Tue Jun 26 11:08:21 2007 +0000
@@ -16,6 +16,7 @@
 #include "Layer.h"
 #include "view/View.h"
 #include "data/model/Model.h"
+#include "base/CommandHistory.h"
 
 #include <iostream>
 
@@ -71,24 +72,6 @@
     emit layerNameChanged();
 }
 
-QString
-Layer::toXmlString(QString indent, QString extraAttributes) const
-{
-    QString s;
-    
-    s += indent;
-
-    s += QString("<layer id=\"%2\" type=\"%1\" name=\"%3\" model=\"%4\" %5/>\n")
-	.arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName
-                            (LayerFactory::getInstance()->getLayerType(this))))
-	.arg(getObjectExportId(this))
-	.arg(encodeEntities(objectName()))
-	.arg(getObjectExportId(getModel()))
-	.arg(extraAttributes);
-
-    return s;
-}
-
 PlayParameters *
 Layer::getPlayParameters() 
 {
@@ -137,13 +120,64 @@
     return true;
 }
 
+bool
+Layer::MeasureRect::operator<(const MeasureRect &mr) const
+{
+    if (haveFrames) {
+        if (startFrame == mr.startFrame) {
+            if (endFrame != mr.endFrame) {
+                return endFrame < mr.endFrame;
+            }
+        } else {
+            return startFrame < mr.startFrame;
+        }
+    } else {
+        if (pixrect.x() == mr.pixrect.x()) {
+            if (pixrect.width() != mr.pixrect.width()) {
+                return pixrect.width() < mr.pixrect.width();
+            }
+        } else {
+            return pixrect.x() < mr.pixrect.x();
+        }
+    }
+
+    // the two rects are equal in x and width
+
+    if (pixrect.y() == mr.pixrect.y()) {
+        return pixrect.height() < mr.pixrect.height();
+    } else {
+        return pixrect.y() < mr.pixrect.y();
+    }
+}
+
+QString
+Layer::AddMeasurementRectCommand::getName() const
+{
+    return tr("Make Measurement");
+}
+
+void
+Layer::AddMeasurementRectCommand::execute()
+{
+    m_layer->addMeasureRect(m_rect);
+}
+
+void
+Layer::AddMeasurementRectCommand::unexecute()
+{
+    m_layer->deleteMeasureRect(m_rect);
+}
+
 void
 Layer::measureStart(View *v, QMouseEvent *e)
 {
     m_draggingRect.pixrect = QRect(e->x(), e->y(), 0, 0);
     if (hasTimeXAxis()) {
+        m_draggingRect.haveFrames = true;
         m_draggingRect.startFrame = v->getFrameForX(e->x());
         m_draggingRect.endFrame = m_draggingRect.startFrame;
+    } else {
+        m_draggingRect.haveFrames = false;
     }
     m_haveDraggingRect = true;
 }
@@ -152,10 +186,13 @@
 Layer::measureDrag(View *v, QMouseEvent *e)
 {
     if (!m_haveDraggingRect) return;
+
     m_draggingRect.pixrect = QRect(m_draggingRect.pixrect.x(),
                                    m_draggingRect.pixrect.y(),
                                    e->x() - m_draggingRect.pixrect.x(),
-                                   e->y() - m_draggingRect.pixrect.y());
+                                   e->y() - m_draggingRect.pixrect.y())
+        .normalized();
+
     if (hasTimeXAxis()) {
         m_draggingRect.endFrame = v->getFrameForX(e->x());
     }
@@ -164,10 +201,12 @@
 void
 Layer::measureEnd(View *v, QMouseEvent *e)
 {
-    //!!! command
     if (!m_haveDraggingRect) return;
     measureDrag(v, e);
-    m_measureRectList.push_back(m_draggingRect);
+    
+    CommandHistory::getInstance()->addCommand
+        (new AddMeasurementRectCommand(this, m_draggingRect));
+
     m_haveDraggingRect = false;
 }
 
@@ -175,22 +214,53 @@
 Layer::paintMeasurementRects(View *v, QPainter &paint) const
 {
     if (m_haveDraggingRect) {
-        v->drawMeasurementRect(paint, this, m_draggingRect.pixrect);
+        paintMeasurementRect(v, paint, m_draggingRect);
     }
 
-    bool timex = hasTimeXAxis();
-
-    for (MeasureRectList::const_iterator i = m_measureRectList.begin(); 
-         i != m_measureRectList.end(); ++i) {
-    
-        if (timex) {
-            int x0 = v->getXForFrame(i->startFrame);
-            int x1 = v->getXForFrame(i->endFrame);
-            QRect pr = QRect(x0, i->pixrect.y(), x1 - x0, i->pixrect.height());
-            i->pixrect = pr;
-        }
-
-        v->drawMeasurementRect(paint, this, i->pixrect);
+    for (MeasureRectSet::const_iterator i = m_measureRects.begin(); 
+         i != m_measureRects.end(); ++i) {
+        paintMeasurementRect(v, paint, *i);
     }
 }
 
+void
+Layer::paintMeasurementRect(View *v, QPainter &paint, MeasureRect &r)
+{
+    if (r.haveFrames) {
+        
+        int x0 = -1;
+        int x1 = v->width() + 1;
+        
+        if (r.startFrame >= v->getStartFrame()) {
+            x0 = v->getXForFrame(r.startFrame);
+        }
+        if (r.endFrame <= v->getEndFrame()) {
+            x1 = v->getXForFrame(r.endFrame);
+        }
+        
+        QRect pr = QRect(x0, r.pixrect.y(),
+                         x1 - x0, r.pixrect.height());
+        
+        r.pixrect = pr;
+    }
+    
+    v->drawMeasurementRect(paint, this, r.pixrect);
+}
+
+QString
+Layer::toXmlString(QString indent, QString extraAttributes) const
+{
+    QString s;
+    
+    s += indent;
+
+    s += QString("<layer id=\"%2\" type=\"%1\" name=\"%3\" model=\"%4\" %5/>\n")
+	.arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName
+                            (LayerFactory::getInstance()->getLayerType(this))))
+	.arg(getObjectExportId(this))
+	.arg(encodeEntities(objectName()))
+	.arg(getObjectExportId(getModel()))
+	.arg(extraAttributes);
+
+    return s;
+}
--- a/layer/Layer.h	Thu Jun 21 16:12:00 2007 +0000
+++ b/layer/Layer.h	Tue Jun 26 11:08:21 2007 +0000
@@ -27,6 +27,7 @@
 #include <QMutex>
 
 #include <map>
+#include <set>
 
 class ZoomConstraint;
 class Model;
@@ -396,22 +397,54 @@
 
     void layerParametersChanged();
     void layerParameterRangesChanged();
+    void layerMeasurementRectsChanged();
     void layerNameChanged();
 
     void verticalZoomChanged();
 
 protected:
     struct MeasureRect {
+
         mutable QRect pixrect;
-        long startFrame; // only valid for a layer that hasTimeXAxis
+        bool haveFrames;
+        long startFrame; // only valid if haveFrames
         long endFrame;   // ditto
+
+        bool operator<(const MeasureRect &mr) const;
     };
 
-    typedef std::vector<MeasureRect> MeasureRectList; // should be x-ordered
-    MeasureRectList m_measureRectList;
+    class AddMeasurementRectCommand : public Command
+    {
+    public:
+        AddMeasurementRectCommand(Layer *layer, MeasureRect rect) :
+            m_layer(layer), m_rect(rect) { }
+
+        virtual QString getName() const;
+        virtual void execute();
+        virtual void unexecute();
+
+    private:
+        Layer *m_layer;
+        MeasureRect m_rect;
+    };
+
+    void addMeasureRect(const MeasureRect &r) {
+        m_measureRects.insert(r);
+        emit layerMeasurementRectsChanged();
+    }
+
+    void deleteMeasureRect(const MeasureRect &r) {
+        m_measureRects.erase(r); 
+        emit layerMeasurementRectsChanged();
+    }
+
+    typedef std::set<MeasureRect> MeasureRectSet;
+    MeasureRectSet m_measureRects;
     MeasureRect m_draggingRect;
     bool m_haveDraggingRect;
 
+    void paintMeasurementRect(View *v, QPainter &paint, MeasureRect &r);
+
 private:
     mutable QMutex m_dormancyMutex;
     mutable std::map<const void *, bool> m_dormancy;
--- a/view/Pane.cpp	Thu Jun 21 16:12:00 2007 +0000
+++ b/view/Pane.cpp	Tue Jun 26 11:08:21 2007 +0000
@@ -396,11 +396,11 @@
         }
     }
 
-    Layer *topLayer = 0;
+    Layer *topLayer = getTopLayer();
+
     const Model *waveformModel = 0; // just for reporting purposes
     for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
         --vi;
-        if (!topLayer) topLayer = *vi;
         if (dynamic_cast<WaveformLayer *>(*vi)) {
             waveformModel = (*vi)->getModel();
             break;
@@ -968,8 +968,7 @@
                                 float &dmin, float &dmax,
                                 QString *unit) 
 {
-    Layer *layer = 0;
-    if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
+    Layer *layer = getTopLayer();
     if (!layer) return false;
     bool vlog;
     QString vunit;
@@ -982,8 +981,7 @@
 bool
 Pane::setTopLayerDisplayExtents(float dmin, float dmax)
 {
-    Layer *layer = 0;
-    if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
+    Layer *layer = getTopLayer();
     if (!layer) return false;
     return layer->setDisplayExtents(dmin, dmax);
 }
@@ -1089,7 +1087,7 @@
 
     } else if (mode == ViewManager::MeasureMode) {
 
-        Layer *layer = getSelectedLayer();
+        Layer *layer = getTopLayer();
         if (layer) layer->measureStart(this, e);
         update();
     }
@@ -1175,7 +1173,7 @@
 
     } else if (mode == ViewManager::MeasureMode) {
 
-        Layer *layer = getSelectedLayer();
+        Layer *layer = getTopLayer();
         if (layer) layer->measureEnd(this, e);
         if (m_measureCursor1) setCursor(*m_measureCursor1);
         update();
@@ -1268,7 +1266,7 @@
 
         if (m_measureCursor2) setCursor(*m_measureCursor2);
 
-        Layer *layer = getSelectedLayer();
+        Layer *layer = getTopLayer();
         if (layer) layer->measureDrag(this, e);
 
         if (hasTopLayerTimeXAxis()) {
--- a/view/View.cpp	Thu Jun 21 16:12:00 2007 +0000
+++ b/view/View.cpp	Tue Jun 26 11:08:21 2007 +0000
@@ -466,6 +466,8 @@
 	    this,    SLOT(layerParametersChanged()));
     connect(layer, SIGNAL(layerParameterRangesChanged()),
 	    this,    SLOT(layerParameterRangesChanged()));
+    connect(layer, SIGNAL(layerMeasurementRectsChanged()),
+	    this,    SLOT(layerMeasurementRectsChanged()));
     connect(layer, SIGNAL(layerNameChanged()),
 	    this,    SLOT(layerNameChanged()));
     connect(layer, SIGNAL(modelChanged()),
@@ -784,6 +786,13 @@
 }
 
 void
+View::layerMeasurementRectsChanged()
+{
+    Layer *layer = dynamic_cast<Layer *>(sender());
+    if (layer) update();
+}
+
+void
 View::layerNameChanged()
 {
     Layer *layer = dynamic_cast<Layer *>(sender());
@@ -1631,6 +1640,9 @@
 void
 View::drawMeasurementRect(QPainter &paint, const Layer *topLayer, QRect r) const
 {
+//    std::cerr << "View::drawMeasurementRect(" << r.x() << "," << r.y() << " "
+//              << r.width() << "x" << r.height() << ")" << std::endl;
+
     if (r.x() + r.width() < 0 || r.x() >= width()) return;
 
     int fontHeight = paint.fontMetrics().height();
--- a/view/View.h	Thu Jun 21 16:12:00 2007 +0000
+++ b/view/View.h	Tue Jun 26 11:08:21 2007 +0000
@@ -153,6 +153,15 @@
     virtual Layer *getLayer(int n) { return m_layers[n]; }
 
     /**
+     * Return the top layer.  This is the same as
+     * getLayer(getLayerCount()-1) if there is at least one layer, and
+     * 0 otherwise.
+     */
+    virtual Layer *getTopLayer() {
+        return m_layers.empty() ? 0 : m_layers[m_layers.size()-1];
+    }
+
+    /**
      * Return the layer last selected by the user.  This is normally
      * the top layer, the same as getLayer(getLayerCount()-1).
      * However, if the user has selected the pane itself more recently
@@ -261,6 +270,7 @@
     virtual void modelReplaced();
     virtual void layerParametersChanged();
     virtual void layerParameterRangesChanged();
+    virtual void layerMeasurementRectsChanged();
     virtual void layerNameChanged();
 
     virtual void globalCentreFrameChanged(unsigned long);