lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006 QMUL. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #include "Panner.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include "system/System.h" lbajardsilogic@0: lbajardsilogic@0: Panner::Panner(QWidget *parent) : lbajardsilogic@0: QWidget(parent), lbajardsilogic@0: m_rectX(0), lbajardsilogic@0: m_rectY(0), lbajardsilogic@0: m_rectWidth(1), lbajardsilogic@0: m_rectHeight(1), lbajardsilogic@0: m_defaultCentreX(0), lbajardsilogic@0: m_defaultCentreY(0), lbajardsilogic@0: m_defaultsSet(false), lbajardsilogic@0: m_thumbColour(palette().highlightedText().color()), lbajardsilogic@0: m_backgroundAlpha(255), lbajardsilogic@0: m_thumbAlpha(255), lbajardsilogic@0: m_clicked(false) lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: Panner::~Panner() lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setAlpha(int backgroundAlpha, int thumbAlpha) lbajardsilogic@0: { lbajardsilogic@0: m_backgroundAlpha = backgroundAlpha; lbajardsilogic@0: m_thumbAlpha = thumbAlpha; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::mousePressEvent(QMouseEvent *e) lbajardsilogic@0: { lbajardsilogic@0: if (e->button() == Qt::MidButton || lbajardsilogic@0: ((e->button() == Qt::LeftButton) && lbajardsilogic@0: (e->modifiers() & Qt::ControlModifier))) { lbajardsilogic@0: resetToDefault(); lbajardsilogic@0: } else if (e->button() == Qt::LeftButton) { lbajardsilogic@0: m_clicked = true; lbajardsilogic@0: m_clickPos = e->pos(); lbajardsilogic@0: m_dragStartX = m_rectX; lbajardsilogic@0: m_dragStartY = m_rectY; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::mouseDoubleClickEvent(QMouseEvent *e) lbajardsilogic@0: { lbajardsilogic@0: if (e->button() != Qt::LeftButton) { lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: emit doubleClicked(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::mouseMoveEvent(QMouseEvent *e) lbajardsilogic@0: { lbajardsilogic@0: if (!m_clicked) return; lbajardsilogic@0: lbajardsilogic@0: float dx = float(e->pos().x() - m_clickPos.x()) / float(width()); lbajardsilogic@0: float dy = float(e->pos().y() - m_clickPos.y()) / float(height()); lbajardsilogic@0: lbajardsilogic@0: m_rectX = m_dragStartX + dx; lbajardsilogic@0: m_rectY = m_dragStartY + dy; lbajardsilogic@0: lbajardsilogic@0: normalise(); lbajardsilogic@0: repaint(); lbajardsilogic@0: emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight); lbajardsilogic@0: emit rectCentreMoved(centreX(), centreY()); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::mouseReleaseEvent(QMouseEvent *e) lbajardsilogic@0: { lbajardsilogic@0: if (!m_clicked) return; lbajardsilogic@0: lbajardsilogic@0: mouseMoveEvent(e); lbajardsilogic@0: m_clicked = false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::wheelEvent(QWheelEvent *e) lbajardsilogic@0: { lbajardsilogic@0: if (e->delta() < 0) { lbajardsilogic@0: m_rectY += 0.1; lbajardsilogic@0: } else { lbajardsilogic@0: m_rectY -= 0.1; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::enterEvent(QEvent *) lbajardsilogic@0: { lbajardsilogic@0: emit mouseEntered(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::leaveEvent(QEvent *) lbajardsilogic@0: { lbajardsilogic@0: emit mouseLeft(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::paintEvent(QPaintEvent *) lbajardsilogic@0: { lbajardsilogic@0: QPainter paint(this); lbajardsilogic@0: paint.setRenderHint(QPainter::Antialiasing, false); lbajardsilogic@0: lbajardsilogic@0: QColor bg(palette().background().color()); lbajardsilogic@0: bg.setAlpha(m_backgroundAlpha); lbajardsilogic@0: lbajardsilogic@0: paint.setPen(palette().dark().color()); lbajardsilogic@0: paint.setBrush(bg); lbajardsilogic@0: paint.drawRect(0, 0, width(), height()); lbajardsilogic@0: lbajardsilogic@0: QColor hl(m_thumbColour); lbajardsilogic@0: hl.setAlpha(m_thumbAlpha); lbajardsilogic@0: lbajardsilogic@0: paint.setBrush(hl); lbajardsilogic@0: lbajardsilogic@0: paint.drawRect(lrintf(width() * m_rectX), lbajardsilogic@0: lrintf(height() * m_rectY), lbajardsilogic@0: lrintf(width() * m_rectWidth), lbajardsilogic@0: lrintf(height() * m_rectHeight)); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::normalise() lbajardsilogic@0: { lbajardsilogic@0: if (m_rectWidth > 1.0) m_rectWidth = 1.0; lbajardsilogic@0: if (m_rectHeight > 1.0) m_rectHeight = 1.0; lbajardsilogic@0: if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth; lbajardsilogic@0: if (m_rectX < 0) m_rectX = 0; lbajardsilogic@0: if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight; lbajardsilogic@0: if (m_rectY < 0) m_rectY = 0; lbajardsilogic@0: lbajardsilogic@0: if (!m_defaultsSet) { lbajardsilogic@0: m_defaultCentreX = centreX(); lbajardsilogic@0: m_defaultCentreY = centreY(); lbajardsilogic@0: m_defaultsSet = true; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::emitAndUpdate() lbajardsilogic@0: { lbajardsilogic@0: emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight); lbajardsilogic@0: emit rectCentreMoved(centreX(), centreY()); lbajardsilogic@0: update(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::getRectExtents(float &x0, float &y0, float &width, float &height) lbajardsilogic@0: { lbajardsilogic@0: x0 = m_rectX; lbajardsilogic@0: y0 = m_rectY; lbajardsilogic@0: width = m_rectWidth; lbajardsilogic@0: height = m_rectHeight; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setRectExtents(float x0, float y0, float width, float height) lbajardsilogic@0: { lbajardsilogic@0: // std::cerr << "Panner::setRectExtents(" << x0 << ", " << y0 << ", " lbajardsilogic@0: // << width << ", " << height << ")" << std::endl; lbajardsilogic@0: lbajardsilogic@0: if (m_rectX == x0 && lbajardsilogic@0: m_rectY == y0 && lbajardsilogic@0: m_rectWidth == width && lbajardsilogic@0: m_rectHeight == height) { lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: m_rectX = x0; lbajardsilogic@0: m_rectY = y0; lbajardsilogic@0: m_rectWidth = width; lbajardsilogic@0: m_rectHeight = height; lbajardsilogic@0: lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setRectWidth(float width) lbajardsilogic@0: { lbajardsilogic@0: if (m_rectWidth == width) return; lbajardsilogic@0: m_rectWidth = width; lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setRectHeight(float height) lbajardsilogic@0: { lbajardsilogic@0: if (m_rectHeight == height) return; lbajardsilogic@0: m_rectHeight = height; lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setRectCentreX(float x) lbajardsilogic@0: { lbajardsilogic@0: float x0 = x - m_rectWidth/2; lbajardsilogic@0: if (x0 == m_rectX) return; lbajardsilogic@0: m_rectX = x0; lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setRectCentreY(float y) lbajardsilogic@0: { lbajardsilogic@0: float y0 = y - m_rectHeight/2; lbajardsilogic@0: if (y0 == m_rectY) return; lbajardsilogic@0: m_rectY = y0; lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QSize lbajardsilogic@0: Panner::sizeHint() const lbajardsilogic@0: { lbajardsilogic@0: return QSize(30, 30); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::setDefaultRectCentre(float cx, float cy) lbajardsilogic@0: { lbajardsilogic@0: m_defaultCentreX = cx; lbajardsilogic@0: m_defaultCentreY = cy; lbajardsilogic@0: m_defaultsSet = true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: Panner::resetToDefault() lbajardsilogic@0: { lbajardsilogic@0: float x0 = m_defaultCentreX - m_rectWidth/2; lbajardsilogic@0: float y0 = m_defaultCentreY - m_rectHeight/2; lbajardsilogic@0: if (x0 == m_rectX && y0 == m_rectY) return; lbajardsilogic@0: m_rectX = x0; lbajardsilogic@0: m_rectY = y0; lbajardsilogic@0: normalise(); lbajardsilogic@0: emitAndUpdate(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: