diff --git a/CMakeLists.txt b/CMakeLists.txt index a1e3f33..797481c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/cursor.cpp b/cursor.cpp new file mode 100644 index 0000000..95a532f --- /dev/null +++ b/cursor.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016, Mike Walters + * + * 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 . + */ + +#include +#include +#include "cursor.h" + +Cursor::Cursor(QObject * parent) : QObject::QObject(parent) +{ + +} + +bool Cursor::pointOverCursor(QPoint point) +{ + const int margin = 5; + range_t 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(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(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(event); + if (mouseEvent->button() == Qt::LeftButton) { + dragging = false; + return true; + } + } + return false; +} + +int Cursor::pos() +{ + return cursorPosition; +} + +void Cursor::setPos(int newPos) +{ + cursorPosition = newPos; +} diff --git a/cursor.h b/cursor.h new file mode 100644 index 0000000..5864c35 --- /dev/null +++ b/cursor.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016, Mike Walters + * + * 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 . + */ + +#pragma once + +#include +#include +#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; +}; diff --git a/cursors.cpp b/cursors.cpp index d76828c..1a1b84b 100644 --- a/cursors.cpp +++ b/cursors.cpp @@ -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 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(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(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(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 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 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 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 selection) { - cursorPositions[0] = selection.minimum; - cursorPositions[1] = selection.maximum; + minCursor->setPos(selection.minimum); + maxCursor->setPos(selection.maximum); emit cursorsMoved(); } diff --git a/cursors.h b/cursors.h index 2fe87e9..30ba3b9 100644 --- a/cursors.h +++ b/cursors.h @@ -22,6 +22,7 @@ #include #include #include +#include "cursor.h" #include "util.h" class Cursors : public QObject @@ -35,6 +36,9 @@ public: void setSegments(int segments); void setSelection(range_t 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}; - };