Skip to content
Snippets Groups Projects
Commit d0f7ff81 authored by SeeLook's avatar SeeLook
Browse files

Implemented scrolling of the view - position changes with displayed current...

Implemented scrolling of the view - position changes with displayed current fret, added mark for current fret
parent 2a705da1
No related branches found
No related tags found
No related merge requests found
......@@ -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);
}
......
......@@ -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;
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment