changeset 433:ac349afdb23f

* somewhat clearer layout in region layer
author Chris Cannam
date Thu, 16 Oct 2008 13:38:33 +0000
parents 8b2b497d302c
children 4ceb5264404d
files layer/RegionLayer.cpp layer/RegionLayer.h
diffstat 2 files changed, 82 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/layer/RegionLayer.cpp	Wed Oct 15 12:08:02 2008 +0000
+++ b/layer/RegionLayer.cpp	Thu Oct 16 13:38:33 2008 +0000
@@ -43,7 +43,7 @@
     m_originalPoint(0, 0.0, 0, tr("New Point")),
     m_editingPoint(0, 0.0, 0, tr("New Point")),
     m_editingCommand(0),
-    m_verticalScale(AutoAlignScale),
+    m_verticalScale(EqualSpaced),
     m_colourMap(0),
     m_plotStyle(PlotLines)
 {
@@ -58,6 +58,9 @@
 
     connectSignals(m_model);
 
+    connect(m_model, SIGNAL(modelChanged()), this, SLOT(recalcSpacing()));
+    recalcSpacing();
+
 //    std::cerr << "RegionLayer::setModel(" << model << ")" << std::endl;
 
     emit modelReplaced();
@@ -127,7 +130,7 @@
 	
 	if (min) *min = 0;
 	if (max) *max = 3;
-        if (deflt) *deflt = int(AutoAlignScale);
+        if (deflt) *deflt = int(EqualSpaced);
 	
 	val = int(m_verticalScale);
 
@@ -165,8 +168,9 @@
 	switch (value) {
 	default:
 	case 0: return tr("Auto-Align");
-	case 1: return tr("Linear");
-	case 2: return tr("Log");
+	case 1: return tr("Equal Spaced");
+	case 2: return tr("Linear");
+	case 3: return tr("Log");
 	}
     }
     return SingleColourLayer::getPropertyValueLabel(name, value);
@@ -228,6 +232,27 @@
     return !v->shouldIlluminateLocalFeatures(this, discard);
 }
 
+void
+RegionLayer::recalcSpacing()
+{
+    m_spacingMap.clear();
+    if (!m_model) return;
+
+    std::set<float> values;
+
+    for (RegionModel::PointList::const_iterator i = m_model->getPoints().begin();
+         i != m_model->getPoints().end(); ++i) {
+        values.insert(i->value);
+    }
+
+    int n = 0;
+
+    for (std::set<float>::const_iterator i = values.begin();
+         i != values.end(); ++i) {
+        m_spacingMap[*i] = n++;
+    }
+}
+
 bool
 RegionLayer::getValueExtents(float &min, float &max,
                            bool &logarithmic, QString &unit) const
@@ -245,7 +270,9 @@
 bool
 RegionLayer::getDisplayExtents(float &min, float &max) const
 {
-    if (!m_model || m_verticalScale == AutoAlignScale) return false;
+    if (!m_model ||
+        m_verticalScale == AutoAlignScale ||
+        m_verticalScale == EqualSpaced) return false;
 
     min = m_model->getValueMinimum();
     max = m_model->getValueMaximum();
@@ -476,6 +503,17 @@
 
         }
 
+    } else if (m_verticalScale == EqualSpaced) {
+
+        if (!m_spacingMap.empty()) {
+            SpacingMap::const_iterator i = m_spacingMap.begin();
+            min = i->second;
+            i = m_spacingMap.end();
+            --i;
+            max = i->second;
+            std::cerr << "RegionLayer[" << this << "]::getScaleExtents: equal spaced; min = " << min << ", max = " << max << ", log = " << log << std::endl;
+        }
+
     } else {
 
         min = m_model->getValueMinimum();
@@ -496,23 +534,34 @@
     float min = 0.0, max = 0.0;
     bool logarithmic = false;
     int h = v->height();
-    int margin = 8;
-    if (h < margin * 8) margin = h / 8;
 
-    getScaleExtents(v, min, max, logarithmic);
+    if (m_verticalScale == EqualSpaced) {
+
+        if (m_spacingMap.empty()) return h/2;
+        
+        SpacingMap::const_iterator i = m_spacingMap.lower_bound(val);
+        //!!! what now, if i->first != v?
+
+        int vh = i->second;
+
+        SpacingMap::const_iterator j = m_spacingMap.end();
+        --j;
+
+        return h - (((h * vh) / (j->second + 1)) + (h / (2 * (j->second + 1))));
+
+    } else {
+
+        getScaleExtents(v, min, max, logarithmic);
 
 //    std::cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl;
 //    std::cerr << "h = " << h << ", margin = " << margin << std::endl;
 
-    if (logarithmic) {
-        val = LogRange::map(val);
-        std::cerr << "logarithmic true, val now = " << val << std::endl;
+        if (logarithmic) {
+            val = LogRange::map(val);
+        }
+
+        return int(h - ((val - min) * h) / (max - min));
     }
-
-    h -= margin * 2;
-    int y = margin + int(h - ((val - min) * h) / (max - min)) - 1;
-//    std::cerr << "y = " << y << std::endl;
-    return y;
 }
 
 QColor
@@ -624,17 +673,15 @@
 	int y = getYForValue(v, p.value);
 	int w = v->getXForFrame(p.frame + p.duration) - x;
 	int h = 9;
-	
-	bool haveNext = false;
-	int nx = v->getXForFrame(v->getModelsEndFrame());
+	int ex = x + w;
 
         RegionModel::PointList::const_iterator j = i;
 	++j;
 
 	if (j != points.end()) {
 	    const RegionModel::Point &q(*j);
-	    nx = v->getXForFrame(q.frame);
-	    haveNext = true;
+	    int nx = v->getXForFrame(q.frame);
+            if (nx < ex) ex = nx;
         }
 
         if (m_plotStyle != PlotSegmentation) {
@@ -662,14 +709,14 @@
 
 	if (m_plotStyle == PlotSegmentation) {
 
-	    if (nx <= x) continue;
+	    if (ex <= x) continue;
 
 	    if (illuminateFrame != p.frame &&
-		(nx < x + 5 || x >= v->width() - 1)) {
+		(ex < x + 5 || x >= v->width() - 1)) {
 		paint.setPen(Qt::NoPen);
 	    }
 
-	    paint.drawRect(x, -1, nx - x, v->height() + 1);
+	    paint.drawRect(x, -1, ex - x, v->height() + 1);
 
 	} else {
 
@@ -687,9 +734,9 @@
         }
 
 	if (p.label != "") {
-            if (!haveNext || nx > x + 6 + paint.fontMetrics().width(p.label)) {
+//            if (ex > x + 6 + paint.fontMetrics().width(p.label)) {
                 paint.drawText(x + 5, textY, p.label);
-            }
+//            }
 	}
     }
 
--- a/layer/RegionLayer.h	Wed Oct 15 12:08:02 2008 +0000
+++ b/layer/RegionLayer.h	Thu Oct 16 13:38:33 2008 +0000
@@ -22,6 +22,8 @@
 #include <QObject>
 #include <QColor>
 
+#include <map>
+
 class View;
 class QPainter;
 
@@ -80,6 +82,7 @@
 
     enum VerticalScale {
         AutoAlignScale,
+        EqualSpaced,
         LinearScale,
         LogScale,
     };
@@ -111,6 +114,9 @@
 
     void setProperties(const QXmlAttributes &attributes);
 
+protected slots:
+    void recalcSpacing();
+
 protected:
     void getScaleExtents(View *, float &min, float &max, bool &log) const;
     int getYForValue(View *v, float value) const;
@@ -130,6 +136,9 @@
     int m_colourMap;
     PlotStyle m_plotStyle;
 
+    typedef std::map<float, int> SpacingMap;
+    SpacingMap m_spacingMap;
+
     void finish(RegionModel::EditCommand *command) {
         Command *c = command->finish();
         if (c) CommandHistory::getInstance()->addCommand(c, false);