diff widgets/LevelPanWidget.cpp @ 929:20698aa6a517 tonioni

Introduce level/pan toolbar buttons
author Chris Cannam
date Wed, 25 Mar 2015 10:33:19 +0000
parents 271e729c818b
children 86df7de08e03
line wrap: on
line diff
--- a/widgets/LevelPanWidget.cpp	Tue Mar 24 17:05:42 2015 +0000
+++ b/widgets/LevelPanWidget.cpp	Wed Mar 25 10:33:19 2015 +0000
@@ -42,6 +42,27 @@
 {
 }
 
+QSize
+LevelPanWidget::sizeHint() const
+{
+    static double ratio = 0.0;
+    if (ratio == 0.0) {
+        double baseEm;
+#ifdef Q_OS_MAC
+        baseEm = 17.0;
+#else
+        baseEm = 15.0;
+#endif
+        double em = QFontMetrics(QFont()).height();
+        ratio = em / baseEm;
+    }
+
+    int pixels = 40;
+    int scaled = int(pixels * ratio + 0.5);
+    if (pixels != 0 && scaled == 0) scaled = 1;
+    return QSize(scaled, scaled);
+}
+
 void
 LevelPanWidget::setLevel(float flevel)
 {
@@ -114,7 +135,7 @@
     if (!m_editable) return;
     
     int level, pan;
-    toCell(e->pos(), level, pan);
+    toCell(rect(), e->pos(), level, pan);
     if (level == m_level && pan == m_pan) {
 	return;
     }
@@ -170,24 +191,28 @@
 }
 
 void
-LevelPanWidget::toCell(QPointF loc, int &level, int &pan) const
+LevelPanWidget::toCell(QRectF rect, QPointF loc, int &level, int &pan) const
 {
-    double w = width(), h = height();
+    double w = rect.width(), h = rect.height();
+
     int npan = maxPan * 2 + 1;
     int nlevel = maxLevel + 1;
+
     double wcell = w / npan, hcell = h / nlevel;
+
     level = int((h - loc.y()) / hcell);
     if (level < 0) level = 0;
     if (level > maxLevel) level = maxLevel;
+
     pan = int(loc.x() / wcell) - maxPan;
     if (pan < -maxPan) pan = -maxPan;
     if (pan > maxPan) pan = maxPan;
 }
 
 QSizeF
-LevelPanWidget::cellSize() const
+LevelPanWidget::cellSize(QRectF rect) const
 {
-    double w = width(), h = height();
+    double w = rect.width(), h = rect.height();
     int npan = maxPan * 2 + 1;
     int nlevel = maxLevel + 1;
     double wcell = w / npan, hcell = h / nlevel;
@@ -195,27 +220,27 @@
 }
 
 QPointF
-LevelPanWidget::cellCentre(int level, int pan) const
+LevelPanWidget::cellCentre(QRectF rect, int level, int pan) const
 {
-    QSizeF cs = cellSize();
+    QSizeF cs = cellSize(rect);
     return QPointF(cs.width() * (pan + maxPan) + cs.width() / 2.,
-		   height() - cs.height() * (level + 1) + cs.height() / 2.);
+		   rect.height() - cs.height() * (level + 1) + cs.height() / 2.);
 }
 
 QSizeF
-LevelPanWidget::cellLightSize() const
+LevelPanWidget::cellLightSize(QRectF rect) const
 {
     double extent = 3. / 4.;
-    QSizeF cs = cellSize();
+    QSizeF cs = cellSize(rect);
     double m = std::min(cs.width(), cs.height());
     return QSizeF(m * extent, m * extent);
 }
 
 QRectF
-LevelPanWidget::cellLightRect(int level, int pan) const
+LevelPanWidget::cellLightRect(QRectF rect, int level, int pan) const
 {
-    QSizeF cls = cellLightSize();
-    QPointF cc = cellCentre(level, pan);
+    QSizeF cls = cellLightSize(rect);
+    QPointF cc = cellCentre(rect, level, pan);
     return QRectF(cc.x() - cls.width() / 2., 
 		  cc.y() - cls.height() / 2.,
 		  cls.width(),
@@ -223,32 +248,32 @@
 }
 
 double
-LevelPanWidget::thinLineWidth() const
+LevelPanWidget::thinLineWidth(QRectF rect) const
 {
-    double tw = ceil(width() / (maxPan * 2. * 10.));
-    double th = ceil(height() / (maxLevel * 10.));
+    double tw = ceil(rect.width() / (maxPan * 2. * 10.));
+    double th = ceil(rect.height() / (maxLevel * 10.));
     return std::min(th, tw);
 }
 
 void
-LevelPanWidget::paintEvent(QPaintEvent *)
+LevelPanWidget::renderTo(QPaintDevice *dev, QRectF rect, bool asIfEditable) const
 {
-    QPainter paint(this);
+    QPainter paint(dev);
     ColourMapper mapper(ColourMapper::Sunset, 0, maxLevel);
 
     paint.setRenderHint(QPainter::Antialiasing, true);
 
     QPen pen;
 
-    double thin = thinLineWidth();
+    double thin = thinLineWidth(rect);
     
     pen.setColor(QColor(127, 127, 127, 127));
-    pen.setWidthF(cellLightSize().width() + thin);
+    pen.setWidthF(cellLightSize(rect).width() + thin);
     pen.setCapStyle(Qt::RoundCap);
     paint.setPen(pen);
 
     for (int pan = -maxPan; pan <= maxPan; ++pan) {
-	paint.drawLine(cellCentre(0, pan), cellCentre(maxLevel, pan));
+	paint.drawLine(cellCentre(rect, 0, pan), cellCentre(rect, maxLevel, pan));
     }
 
     if (isEnabled()) {
@@ -256,6 +281,15 @@
     } else {
 	pen.setColor(Qt::darkGray);
     }
+
+    if (!asIfEditable && m_level == 0) {
+        pen.setWidthF(thin * 2);
+        pen.setCapStyle(Qt::RoundCap);
+        paint.setPen(pen);
+        paint.drawLine(rect.topLeft(), rect.bottomRight());
+        paint.drawLine(rect.bottomLeft(), rect.topRight());
+        return;
+    }
     
     pen.setWidthF(thin);
     pen.setCapStyle(Qt::FlatCap);
@@ -265,7 +299,7 @@
 	if (isEnabled()) {
 	    paint.setBrush(mapper.map(level));
 	}
-	QRectF clr = cellLightRect(level, m_pan);
+	QRectF clr = cellLightRect(rect, level, m_pan);
 	if (m_level == 0) {
 	    paint.drawLine(clr.topLeft(), clr.bottomRight());
 	    paint.drawLine(clr.bottomLeft(), clr.topRight());
@@ -275,4 +309,11 @@
     }
 }
 
+void
+LevelPanWidget::paintEvent(QPaintEvent *)
+{
+    renderTo(this, rect(), m_editable);
+}
 
+
+