cursors: Split out mouse dragging logic into Cursor class

This commit is contained in:
Mike Walters
2016-03-16 03:12:15 +00:00
parent 27381dbb30
commit e618ad02c3
5 changed files with 149 additions and 54 deletions

View File

@@ -27,6 +27,7 @@ endif (NOT CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
list(APPEND inspectrum_sources
cursor.cpp
cursors.cpp
main.cpp
fft.cpp

75
cursor.cpp Normal file
View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2016, Mike Walters <mike@flomp.net>
*
* This file is part of inspectrum.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QDebug>
#include <QMouseEvent>
#include "cursor.h"
Cursor::Cursor(QObject * parent) : QObject::QObject(parent)
{
}
bool Cursor::pointOverCursor(QPoint point)
{
const int margin = 5;
range_t<int> range = {cursorPosition - margin, cursorPosition + margin};
return range.contains(point.x());
}
bool Cursor::eventFilter(QObject *obj, QEvent *event)
{
// Start dragging on left mouse button press, if over a cursor
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
if (pointOverCursor(mouseEvent->pos())) {
dragging = true;
return true;
}
}
// Update current cursor positon if we're dragging
} else if (event->type() == QEvent::MouseMove) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (dragging) {
cursorPosition = mouseEvent->pos().x();
emit posChanged();
}
// Stop dragging on left mouse button release
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
dragging = false;
return true;
}
}
return false;
}
int Cursor::pos()
{
return cursorPosition;
}
void Cursor::setPos(int newPos)
{
cursorPosition = newPos;
}

44
cursor.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2016, Mike Walters <mike@flomp.net>
*
* This file is part of inspectrum.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QObject>
#include <QPoint>
#include "util.h"
class Cursor : public QObject
{
Q_OBJECT
public:
Cursor(QObject * parent);
int pos();
void setPos(int newPos);
bool eventFilter(QObject *obj, QEvent *event);
signals:
void posChanged();
private:
bool pointOverCursor(QPoint point);
bool dragging = false;
int cursorPosition = 0;
};

View File

@@ -23,51 +23,30 @@
Cursors::Cursors(QObject * parent) : QObject::QObject(parent)
{
minCursor = new Cursor(this);
maxCursor = new Cursor(this);
installEventFilter(minCursor);
installEventFilter(maxCursor);
connect(minCursor, &Cursor::posChanged, this, &Cursors::cursorMoved);
connect(maxCursor, &Cursor::posChanged, this, &Cursors::cursorMoved);
}
// Return true if point is over a cursor, put cursor ID in `cursor`
bool Cursors::pointOverCursor(QPoint point, int &cursor)
void Cursors::cursorMoved()
{
int margin = 5;
for (int i = 0; i < 2; i++) {
range_t<int> range = {cursorPositions[i] - margin, cursorPositions[i] + margin};
if (range.contains(point.x())) {
cursor = i;
return true;
}
// Swap cursors if one has been dragged past the other
if (minCursor->pos() > maxCursor->pos()) {
std::swap(minCursor, maxCursor);
}
return false;
emit cursorsMoved();
}
bool Cursors::eventFilter(QObject *obj, QEvent *event)
{
// Start dragging on left mouse button press, if over a cursor
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
if (pointOverCursor(mouseEvent->pos(), selectedCursor)) {
dragging = true;
return true;
}
}
if (minCursor->eventFilter(obj, event))
return true;
if (maxCursor->eventFilter(obj, event))
return true;
// Update current cursor positon if we're dragging
} else if (event->type() == QEvent::MouseMove) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (dragging) {
cursorPositions[selectedCursor] = mouseEvent->pos().x();
emit cursorsMoved();
}
// Stop dragging on left mouse button release
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
dragging = false;
return true;
}
}
return false;
}
@@ -75,7 +54,8 @@ void Cursors::paintFront(QPainter &painter, QRect &rect, range_t<off_t> sampleRa
{
painter.save();
QRect cursorRect(cursorPositions[0], rect.top(), cursorPositions[1] - cursorPositions[0], rect.height());
QRect cursorRect(minCursor->pos(), rect.top(), maxCursor->pos() - minCursor->pos(), rect.height());
// Draw translucent white fill for highlight
painter.fillRect(
cursorRect,
@@ -85,38 +65,31 @@ void Cursors::paintFront(QPainter &painter, QRect &rect, range_t<off_t> sampleRa
// Draw vertical edges for individual segments
painter.setPen(QPen(Qt::gray, 1, Qt::DashLine));
for (int i = 1; i < segmentCount; i++) {
int pos = cursorPositions[0] + (i * cursorRect.width() / segmentCount);
int pos = minCursor->pos() + (i * cursorRect.width() / segmentCount);
painter.drawLine(pos, rect.top(), pos, rect.bottom());
}
// Draw vertical edges
painter.setPen(QPen(Qt::white, 1, Qt::SolidLine));
painter.drawLine(cursorPositions[0], rect.top(), cursorPositions[0], rect.bottom());
painter.drawLine(cursorPositions[1], rect.top(), cursorPositions[1], rect.bottom());
painter.drawLine(minCursor->pos(), rect.top(), minCursor->pos(), rect.bottom());
painter.drawLine(maxCursor->pos(), rect.top(), maxCursor->pos(), rect.bottom());
painter.restore();
}
range_t<int> Cursors::selection()
{
// TODO: ensure correct ordering during dragging, not here
if (cursorPositions[0] < cursorPositions[1]) {
return {cursorPositions[0], cursorPositions[1]};
} else {
return {cursorPositions[1], cursorPositions[0]};
}
return {minCursor->pos(), maxCursor->pos()};
}
void Cursors::setSegments(int segments)
{
segmentCount = std::max(segments, 1);
}
void Cursors::setSelection(range_t<int> selection)
{
cursorPositions[0] = selection.minimum;
cursorPositions[1] = selection.maximum;
minCursor->setPos(selection.minimum);
maxCursor->setPos(selection.maximum);
emit cursorsMoved();
}

View File

@@ -22,6 +22,7 @@
#include <QObject>
#include <QPainter>
#include <QPoint>
#include "cursor.h"
#include "util.h"
class Cursors : public QObject
@@ -35,6 +36,9 @@ public:
void setSegments(int segments);
void setSelection(range_t<int> selection);
public slots:
void cursorMoved();
signals:
void cursorsMoved();
@@ -44,9 +48,7 @@ protected:
private:
bool pointOverCursor(QPoint point, int &cursor);
Cursor *minCursor;
Cursor *maxCursor;
int segmentCount = 1;
bool dragging = false;
int selectedCursor = 0;
int cursorPositions[2] = {0, 50};
};