diff --git a/src/guitar/tguitarview.cpp b/src/guitar/tguitarview.cpp index 7ceb5dfe52f928c80dda7ef289ee8f081b8fff1d..3c0f79ac455f0bf3d20b89e0810518d9fc018fe8 100644 --- a/src/guitar/tguitarview.cpp +++ b/src/guitar/tguitarview.cpp @@ -19,43 +19,145 @@ #include "tguitarview.h" #include "tfingerboard.h" #include <tmtr.h> +#include <graphics/tdropshadoweffect.h> +#include <tpath.h> #include <QGraphicsProxyWidget> #include <QScrollBar> #include <QDebug> - TguitarView::TguitarView(QGraphicsView* guitar, QGraphicsView* parent) : - QGraphicsView(0, 0) + QGraphicsView(0, 0), + m_parent(parent), + m_couldBeTouch(false), + m_wasTouched(false) { - setAttribute(Qt::WA_AcceptTouchEvents); + m_parent = parent; +// setAttribute(Qt::WA_AcceptTouchEvents); m_guitar = static_cast<TfingerBoard*>(guitar); + setStyleSheet("background-color: transparent;"); setScene(m_guitar->scene()); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setFixedSize(parent->width(), parent->height() / 2); + setFixedSize(m_guitar->averFretWidth() * 2.5, Tmtr::fingerPixels() * 4); qreal factor = (qreal)height() / (qreal)m_guitar->viewport()->height(); scale(factor, factor); m_proxy = parent->scene()->addWidget(this); - m_proxy->setPos(0, parent->height() - height()); m_proxy->setZValue(50); - guitar->installEventFilter(this); + m_proxy->hide(); + m_proxy->setGraphicsEffect(new TdropShadowEffect()); + QPolygonF polygon; + polygon << QPointF(0.0, 0.0) + << QPointF(m_guitar->fbRect().y() / 2, m_guitar->fbRect().y()) + << QPointF(m_guitar->fbRect().y(), 0.0) + << QPointF(0.0, 0.0); + m_mark = m_guitar->scene()->addPolygon(polygon, Qt::NoPen, QBrush(qApp->palette().highlight().color())); + m_mark->hide(); +} + + +TguitarView::~TguitarView() +{ + delete m_mark; +} + + +void TguitarView::displayAt(const QPointF& scenePos) { + m_fret = m_guitar->pointToFinger(QPoint(scenePos.x(), m_guitar->height() / 2)).fret(); + updateContextPosition(); + proxy()->setPos(m_fret ? m_guitar->fretPositionX(m_fret) : m_parent->width() - width(), m_parent->height() - height() - 4); + proxy()->show(); + updateMarkPosition(); } bool TguitarView::mapTouchEvent(QTouchEvent* te) { - if (te->type() == QEvent::TouchUpdate) { - if (QLineF(te->touchPoints().first().pos(), te->touchPoints().first().startPos()).length() > 10) // TODO use screen factor instead 10 - horizontalScrollBar()->setValue (horizontalScrollBar()->value() + (te->touchPoints()[0].lastPos().x() - te->touchPoints()[0].pos().x())); - } else if (te->type() == QEvent::TouchEnd) { - if (QLineF(te->touchPoints().first().pos(), te->touchPoints().first().startPos()).length() < 10) { // TODO use screen factor instead 10 - QPointF mtgv = proxy()->mapFromScene(te->touchPoints().first().pos()); // mapped from global scene to guitar view - m_guitar->fakePress(QPointF((mtgv.x() + horizontalScrollBar()->value()) / transform().m11(), mtgv.y() / transform().m11()).toPoint()); + switch (te->type()) { + case QEvent::TouchBegin: { + if (proxy()->isVisible()) // already displayed - prepare for scrolling + m_couldBeTouch = true; + break; + } + case QEvent::TouchUpdate: { + if (QLineF(te->touchPoints().first().pos(), te->touchPoints().first().startPos()).length() > Tmtr::fingerPixels() / 2) { + horizontalScrollBar()->setValue(horizontalScrollBar()->value() + + (te->touchPoints()[0].pos().x() - te->touchPoints()[0].lastPos().x())); + quint8 currFret = m_guitar->pointToFinger(QPoint(horizontalScrollBar()->value() / transform().m11(), m_guitar->height() / 2)).fret(); + if (currFret != m_fret) { + m_fret = currFret; + updateMarkPosition(); + proxy()->setPos(m_fret ? m_guitar->fretPositionX(m_fret) : m_parent->width() - width(), m_parent->height() - height() - 4); + } + m_couldBeTouch = false; } + break; + } + case QEvent::TouchEnd: { + if (m_couldBeTouch) { + if (m_parent->itemAt(te->touchPoints().first().startPos().toPoint()) == proxy()) { + QPointF mtgv = proxy()->mapFromScene(te->touchPoints().first().pos()); // mapped from global scene to guitar view + m_guitar->fakePress(QPointF((mtgv.x() + horizontalScrollBar()->value()) / transform().m11(), mtgv.y() / transform().m11()).toPoint()); + } + } else if (m_wasTouched) + updateContextPosition(); + m_wasTouched = false; + m_couldBeTouch = false; + break; } + default: + break; + } return true; } +//################################################################################################# +//################### PROTECTED ############################################ +//################################################################################################# + +void TguitarView::updateMarkPosition() { + if (m_fret) { + m_mark->setPos(m_guitar->fretPositionX(m_fret) - 25.0, 0.0); + m_mark->show(); + } else + m_mark->hide(); +} + + +void TguitarView::updateContextPosition() { + if (m_fret) { + if (m_fret == 1) + horizontalScrollBar()->setValue(1); + else + horizontalScrollBar()->setValue(m_guitar->fretPositionX(m_fret - 1) * transform().m11()); + } else { + horizontalScrollBar()->setValue(horizontalScrollBar()->maximum()); + } +} + + +void TguitarView::paintEvent(QPaintEvent* event) { + if (horizontalScrollBar()->value() >= m_guitar->fbRect().x() + m_guitar->fbRect().width()) { + QPainter painter(viewport()); +// if (!gl->GisRightHanded) { +// painter.translate(width(), 0); +// painter.scale(-1, 1); +// } +// if (gl->instrument == e_classicalGuitar || gl->instrument == e_noInstrument) { + QPixmap guitarPixmap = QPixmap(Tpath::img("body")).scaled( + (m_parent->width() / 2) * transform().m11(), height() * 2.445714285714286, Qt::IgnoreAspectRatio); + painter.drawPixmap((m_guitar->posX12fret() + 7) * transform().m11() - horizontalScrollBar()->value(), + height() - guitarPixmap.height(), guitarPixmap); +// } else { +// qreal ratio = (guitar->height() * 3.3) / 535; +// painter.drawPixmap(guitar->fbRect().right() - 235 * ratio, height() - m_bgPixmap.height() , m_bgPixmap); +// if (!gl->GisRightHanded) +// painter.resetTransform(); +// painter.drawPixmap(guitar->pickRect()->x(), guitar->pickRect()->y(), m_rosettePixmap); +// } + } + QGraphicsView::paintEvent(event); +} + diff --git a/src/guitar/tguitarview.h b/src/guitar/tguitarview.h index 455dc3327982446e3175353d2ed12b61900cb445..a6390e4f29cadf0c924d5ed206b41f6bcc22d46c 100644 --- a/src/guitar/tguitarview.h +++ b/src/guitar/tguitarview.h @@ -27,22 +27,49 @@ class TfingerBoard; class QTouchEvent; /** - * Another view of guitar fingerboard + * Another view of guitar fingerboard. + * It displays chunk of fingerboard with just touched fret. + * Automatically determines its scale (depends on real screen size). + * Scale is determined in constructor but first position + * has to be initialized by @p displayAt() with touch coordinates as a parameter. + * It support scrolling when it was touched and finger is moving (even out of view area). + * It is difficult to implement, so parent widget which is @class TmainView has to cooperate. + * First of all - every touch is propagated from parent through @p mapTouchEvent(QTouchEvent), + * but when @class TmainView detects that @class TguitarView was touched it has to call: + * @p TguitarView::setTouched(). + * Also it automatically scrolls its context + * to always displays current fret at the beginning of the view + * and moves view position next to currently displayed fret. */ class TguitarView : public QGraphicsView { public: + /** Creates preview, it is hidden by default and has to be shown through @p displayAt(QPointF) */ TguitarView(QGraphicsView* guitar, QGraphicsView* parent); + virtual ~TguitarView(); QGraphicsProxyWidget* proxy() { return m_proxy; } - bool mapTouchEvent(QTouchEvent* te); + void displayAt(const QPointF& scenePos); /** Shows view at given scene position */ + bool mapTouchEvent(QTouchEvent* te); /** Propagates touch events into view or into guitar */ + void setTouched() { m_wasTouched = true; } + bool wasTouched() { return m_wasTouched; } /** Returns @p TRUE when widget is visible and was touched. */ + +protected: + void updateMarkPosition(); /** Fret mark position depends on current fret */ + void updateContextPosition(); /** Sets value of scroll bar at the beginning position of current fret. */ + void paintEvent(QPaintEvent* event); /** Paint visible piece of guitar body */ private: + QGraphicsView *m_parent; TfingerBoard *m_guitar; QGraphicsProxyWidget *m_proxy; + QGraphicsPolygonItem *m_mark; + quint8 m_fret; + bool m_couldBeTouch; + bool m_wasTouched; };