21 #include <QGestureEvent>
22 #include <QApplication>
24 #include "qwt_plot_panner.h"
25 #include "qwt_plot_canvas.h"
26 #include "qwt_plot_magnifier.h"
27 #include "qwt_plot_zoomer.h"
36 mNumberOfKeys(numberOfKeys),
40 setAttribute(Qt::WA_AcceptTouchEvents);
45 setAxisScaleDraw(xBottom, xScaleDraw);
46 QObject::connect(
this, SIGNAL(
keyWidthChanged(
double)), xScaleDraw, SLOT(setKeyWidth(
double)));
49 QwtPlotPanner *panner =
new QwtPlotPanner(canvas());
50 panner->setMouseButton(Qt::LeftButton, Qt::ControlModifier);
54 ( void )
new QwtPlotMagnifier( canvas() );
58 mPlotZoomer->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton);
66 return transform(QwtPlot::xBottom, 3) - transform(QwtPlot::xBottom, 2);
70 bool isLogX =
dynamic_cast<QwtLogScaleEngine*
>(axisScaleEngine(xBottom)) !=
nullptr;
71 bool isLogY =
dynamic_cast<QwtLogScaleEngine*
>(axisScaleEngine(yLeft)) !=
nullptr;
74 QStack< QRectF > zoomStack =
mPlotZoomer->zoomStack();
77 auto invTransform = [
this](
const QPointF &p) {
78 return QPointF(this->invTransform(xBottom, p.x()),
79 this->invTransform(yLeft, p.y()));
82 const QwtInterval xInterval(axisInterval(xBottom));
83 const QwtInterval yInterval(axisInterval(yLeft));
84 QPointF topLeft(xInterval.minValue(), yInterval.maxValue());
85 QPointF botRight(xInterval.maxValue(), yInterval.minValue());
87 const QList<QTouchEvent::TouchPoint> &points(
mTouchPoints);
88 if (points.size() == 1) {
89 const QTouchEvent::TouchPoint &p(points.first());
90 const QPointF pPrev(invTransform(p.lastPos()));
91 const QPointF pCurr(invTransform(p.pos()));
92 const QPointF d = pCurr - pPrev;
93 newRect = QRectF(topLeft, botRight);
94 if (dynamic_cast<QwtLogScaleEngine*>(axisScaleEngine(yLeft))) {
95 newRect.translate(-d.x(), 0);
96 newRect = newRect.normalized();
98 double logFac = pCurr.y() / pPrev.y();
99 newRect.setBottom(newRect.bottom() / logFac);
100 newRect.setTop(newRect.top() / logFac);
103 newRect.translate(-d);
105 }
else if (points.size() == 2) {
106 const QTouchEvent::TouchPoint &p1(points.first());
107 const QTouchEvent::TouchPoint &p2(points.last());
109 const QPointF p1Last = invTransform(p1.lastPos());
110 const QPointF p2Last = invTransform(p2.lastPos());
111 const QPointF p1Curr = invTransform(p1.pos());
112 const QPointF p2Curr = invTransform(p2.pos());
115 auto invLinearTransform = [](qreal x, qreal m, qreal t) {
return (x - t) / m;};
118 auto invLogTransform = [](qreal x, qreal m, qreal t) {
return std::pow(x / t, 1/m);};
120 auto linM = [](qreal p1, qreal c1, qreal p2, qreal c2) {
return (c1 - c2) / (p1 - p2);};
121 auto logM = [](qreal p1, qreal c1, qreal p2, qreal c2) {
return log(c1 / c2) / log(p1 / p2);};
123 auto linT = [](qreal p1, qreal c1, qreal m) {
return c1 - m * p1;};
124 auto logT = [](qreal p1, qreal c1, qreal m) {
return c1 / std::pow(p1, m);};
126 auto computeBounds = [&](
int axis,
bool log, qreal &top, qreal &bot) {
127 auto c = &QPointF::y;
128 if (axis == xBottom) {c = &QPointF::x;}
130 const qreal p1 = (p1Last.*c)();
131 const qreal p2 = (p2Last.*c)();
132 const qreal c1 = (p1Curr.*c)();
133 const qreal c2 = (p2Curr.*c)();
136 const qreal m = logM(p1, c1, p2, c2);
137 const qreal t = logT(p1, c1, m);
138 top = invLogTransform(top, m, t);
139 bot =invLogTransform(bot, m, t);
141 const qreal m = linM(p1, c1, p2, c2);
142 const qreal t = linT(p1, c1, m);
144 top = invLinearTransform(top, m, t);
145 bot = invLinearTransform(bot, m, t);
149 computeBounds(xBottom, isLogX, topLeft.rx(), botRight.rx());
150 computeBounds(yLeft, isLogY, topLeft.ry(), botRight.ry());
152 newRect.setTopLeft(topLeft);
153 newRect.setBottomRight(botRight);
157 if (newRect.isNull() ==
false) {
158 zoomStack << newRect.normalized();
166 if (newRect.isNull() ==
false) {
177 if (dynamic_cast<QTouchEvent*>(e)) {
179 return touchEvent(static_cast<QTouchEvent *>(e));
181 return QwtPlot::event(e);
185 QList<QTouchEvent::TouchPoint> points(e->touchPoints());
186 for (
auto it = points.begin(); it != points.end(); ) {
187 if (it->state() == Qt::TouchPointReleased || it->state() == Qt::TouchPointPressed) {
188 it = points.erase(it);
200 for (
int i = 0; i < points.size(); ++i) {
211 QwtPlot::updateLayout();
216 QwtPlot::showEvent(e);
220 QwtPlot::resizeEvent(e);
225 QwtPlot::paintEvent(e);
230 setAxisAutoScale(QwtPlot::yLeft);
235 const QwtInterval xInterval(axisInterval(xBottom));
236 const QwtInterval yInterval(axisInterval(yLeft));
237 QPointF topLeft(xInterval.minValue(), yInterval.maxValue());
238 QPointF botRight(xInterval.maxValue(), yInterval.minValue());
239 QStack<QRectF> stack;
240 QRectF r(topLeft, botRight);
241 stack << r.normalized();
virtual bool touchEvent(QTouchEvent *e)
QwtPlotZoomer * mPlotZoomer
virtual void resizeEvent(QResizeEvent *e) override
CentralPlotFrame(int numberOfKeys, int keyOffset)
void keyWidthChanged(double width)
void moveCanvas(int dx, int dy)
static const int FLYING_UPDATE_INTERVALL_IN_MS
virtual void paintEvent(QPaintEvent *e) override
virtual void updateLayout() override
virtual void showEvent(QShowEvent *e) override
QwtPlotZoomer * mNonStackInvisibleZoomer
void applyTouchTransform(int final)
virtual bool event(QEvent *) override
double currentTickDistanceInPixel() const
QList< QTouchEvent::TouchPoint > mTouchPoints