diff --git a/src/widget/wknobcomposed.cpp b/src/widget/wknobcomposed.cpp index 49269173d1ea..173687f940ec 100644 --- a/src/widget/wknobcomposed.cpp +++ b/src/widget/wknobcomposed.cpp @@ -13,6 +13,10 @@ WKnobComposed::WKnobComposed(QWidget* pParent) m_dMaxAngle(50.0), m_dKnobCenterXOffset(0), m_dKnobCenterYOffset(0), + m_dArcRadius(0), + m_dArcThickness(0), + m_dArcBgThickness(0), + m_arcUnipolar(true), m_renderTimer(mixxx::Duration::fromMillis(20), mixxx::Duration::fromSeconds(1)) { connect(&m_renderTimer, SIGNAL(update()), @@ -46,16 +50,26 @@ void WKnobComposed::setup(const QDomNode& node, const SkinContext& context) { context.hasNodeSelectDouble(node, "MaxAngle", &m_dMaxAngle); context.hasNodeSelectDouble(node, "KnobCenterXOffset", &m_dKnobCenterXOffset); context.hasNodeSelectDouble(node, "KnobCenterYOffset", &m_dKnobCenterYOffset); - m_dArcThickness = context.selectDouble(node, "ArcThickness"); - - if (m_dArcThickness > 0.0) { - m_arcColor = WSkinColor::getCorrectColor(context.selectColor(node, "ArcColor")); + context.hasNodeSelectDouble(node, "ArcRadius", &m_dArcRadius); + + if (m_dArcRadius > 0.0) { + context.hasNodeSelectDouble(node, "ArcThickness", &m_dArcThickness); + context.hasNodeSelectDouble(node, "ArcBgThickness", &m_dArcBgThickness); + if (m_dArcThickness > 0.0) { + m_dArcThickness *= scaleFactor; + m_arcColor = WSkinColor::getCorrectColor(context.selectColor(node, "ArcColor")); + } + if (m_dArcBgThickness > 0.0) { + m_dArcBgThickness *= scaleFactor; + m_arcBgColor = WSkinColor::getCorrectColor(context.selectColor(node, "ArcBgColor")); + } m_arcUnipolar = context.selectBool(node, "ArcUnipolar", false); + // ToDo(ronso0) Also allow customizing the pen shape? + // Qt::FlatCap (default) | Qt::RoundCap } m_dKnobCenterXOffset *= scaleFactor; m_dKnobCenterYOffset *= scaleFactor; - m_dArcThickness *= scaleFactor; setFocusPolicy(Qt::NoFocus); } @@ -111,14 +125,14 @@ void WKnobComposed::paintEvent(QPaintEvent* e) { m_pPixmapBack->draw(rect(), &p, m_pPixmapBack->rect()); } - if ((!m_pKnob.isNull() && !m_pKnob->isNull()) || m_dArcThickness > 0.0) { + if ((!m_pKnob.isNull() && !m_pKnob->isNull()) || m_dArcRadius > 0.1) { // We update m_dCurrentAngle since onConnectedControlChanged uses it for // no-op detection. m_dCurrentAngle = m_dMinAngle + (m_dMaxAngle - m_dMinAngle) * getControlParameterDisplay(); } - if (m_dArcThickness > 0.0) { - drawArc(rect(), &p); + if (m_dArcRadius > 0.1) { + drawArc(&p); } QTransform transform; @@ -137,17 +151,34 @@ void WKnobComposed::paintEvent(QPaintEvent* e) { } } -void WKnobComposed::drawArc(const QRectF& targetRect, QPainter* pPainter) { - QMargins margins = QMargins(); - margins += m_dArcThickness / 2.0; - QRectF rect = targetRect.marginsRemoved(margins); - QPen pen = QPen(m_arcColor); - pen.setWidth(m_dArcThickness); - pen.setCapStyle(Qt::FlatCap); - pPainter->setPen(pen); +void WKnobComposed::drawArc(QPainter* pPainter) { + // In order to always draw the arcs undistorted we set up + // a quadratic target rectangle regardless of the widget's + // width-to-height ratio. + qreal centerX = width() / 2.0 + m_dKnobCenterXOffset; + qreal centerY = height() / 2.0 + m_dKnobCenterYOffset; + QPointF topLeft = QPointF((centerX - m_dArcRadius), (centerY - m_dArcRadius)); + QPointF bottomRight = QPointF((centerX + m_dArcRadius), (centerY + m_dArcRadius)); + QRectF rect = QRectF(topLeft, bottomRight); + + if (m_dArcBgThickness > 0.0) { + QPen arcBgPen = QPen(m_arcBgColor); + arcBgPen.setWidth(m_dArcBgThickness); + arcBgPen.setCapStyle(Qt::FlatCap); + pPainter->setPen(arcBgPen); + pPainter->drawArc(rect, (90 - m_dMinAngle) * 16, (m_dMinAngle - m_dMaxAngle) * 16); + } + + QPen arcPen = QPen(m_arcColor); + arcPen.setWidth(m_dArcThickness); + arcPen.setCapStyle(Qt::FlatCap); + + pPainter->setPen(arcPen); if (m_arcUnipolar) { - pPainter->drawArc(rect, 90 * 16 - m_dMinAngle * 16, (m_dCurrentAngle - m_dMinAngle) * -16); + // draw arc from minAngle to current position + pPainter->drawArc(rect, (90 - m_dMinAngle) * 16, (m_dCurrentAngle - m_dMinAngle) * -16); } else { + // draw arc from center to current position pPainter->drawArc(rect, 90 * 16, m_dCurrentAngle * -16); } } diff --git a/src/widget/wknobcomposed.h b/src/widget/wknobcomposed.h index 8a6df47fc3e1..0a1803f9d88e 100644 --- a/src/widget/wknobcomposed.h +++ b/src/widget/wknobcomposed.h @@ -45,9 +45,7 @@ class WKnobComposed : public WWidget { PixmapSource source, Paintable::DrawMode mode, double scaleFactor); - void drawArc( - const QRectF& targetRect, - QPainter* pPainter); + void drawArc(QPainter* pPainter); double m_dCurrentAngle; PaintablePointer m_pKnob; @@ -57,8 +55,11 @@ class WKnobComposed : public WWidget { double m_dMaxAngle; double m_dKnobCenterXOffset; double m_dKnobCenterYOffset; + double m_dArcRadius; double m_dArcThickness; + double m_dArcBgThickness; QColor m_arcColor; + QColor m_arcBgColor; bool m_arcUnipolar; WidgetRenderTimer m_renderTimer;