mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-05-02 08:38:30 -04:00
Merge pull request #10 from cjcliffe/canvas_interaction
Canvas interaction
This commit is contained in:
commit
d33ef25a79
@ -95,6 +95,7 @@ SET (cubicsdr_sources
|
|||||||
src/audio/AudioThread.cpp
|
src/audio/AudioThread.cpp
|
||||||
src/util/Gradient.cpp
|
src/util/Gradient.cpp
|
||||||
src/util/Timer.cpp
|
src/util/Timer.cpp
|
||||||
|
src/util/MouseTracker.cpp
|
||||||
src/visual/PrimaryGLContext.cpp
|
src/visual/PrimaryGLContext.cpp
|
||||||
src/visual/ScopeCanvas.cpp
|
src/visual/ScopeCanvas.cpp
|
||||||
src/visual/ScopeContext.cpp
|
src/visual/ScopeContext.cpp
|
||||||
@ -115,6 +116,7 @@ SET (cubicsdr_headers
|
|||||||
src/util/Gradient.h
|
src/util/Gradient.h
|
||||||
src/util/Timer.h
|
src/util/Timer.h
|
||||||
src/util/ThreadQueue.h
|
src/util/ThreadQueue.h
|
||||||
|
src/util/MouseTracker.h
|
||||||
src/visual/PrimaryGLContext.h
|
src/visual/PrimaryGLContext.h
|
||||||
src/visual/ScopeCanvas.h
|
src/visual/ScopeCanvas.h
|
||||||
src/visual/ScopeContext.h
|
src/visual/ScopeContext.h
|
||||||
|
@ -36,6 +36,10 @@ public:
|
|||||||
return iqVisualQueue;
|
return iqVisualQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DemodulatorInstance *getDemodTest() {
|
||||||
|
return demodulatorTest;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimaryGLContext *m_glContext;
|
PrimaryGLContext *m_glContext;
|
||||||
|
|
||||||
|
118
src/util/MouseTracker.cpp
Normal file
118
src/util/MouseTracker.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "MouseTracker.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseMoved(wxMouseEvent& event) {
|
||||||
|
if (target == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxSize ClientSize = target->GetClientSize();
|
||||||
|
|
||||||
|
mouseX = (float) event.m_x / (float) ClientSize.x;
|
||||||
|
mouseY = (float) event.m_y / (float) ClientSize.y;
|
||||||
|
|
||||||
|
deltaMouseX = mouseX - lastMouseX;
|
||||||
|
deltaMouseY = mouseY - lastMouseY;
|
||||||
|
|
||||||
|
if (isMouseDown) {
|
||||||
|
lastMouseX = mouseX;
|
||||||
|
|
||||||
|
if (vertDragLock && mouseY != lastMouseY) {
|
||||||
|
target->WarpPointer(event.m_x, lastMouseY * ClientSize.y);
|
||||||
|
} else {
|
||||||
|
lastMouseY = mouseY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastMouseY = mouseY;
|
||||||
|
lastMouseX = mouseX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseDown(wxMouseEvent& event) {
|
||||||
|
if (target == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxSize ClientSize = target->GetClientSize();
|
||||||
|
|
||||||
|
mouseX = lastMouseX = (float) event.m_x / (float) ClientSize.x;
|
||||||
|
mouseY = lastMouseY = (float) event.m_y / (float) ClientSize.y;
|
||||||
|
|
||||||
|
originMouseX = mouseX;
|
||||||
|
originMouseY = mouseY;
|
||||||
|
|
||||||
|
isMouseDown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseWheelMoved(wxMouseEvent& event) {
|
||||||
|
// std::cout << "wheel?" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseReleased(wxMouseEvent& event) {
|
||||||
|
isMouseDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseEnterWindow(wxMouseEvent& event) {
|
||||||
|
isMouseInView = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::OnMouseLeftWindow(wxMouseEvent& event) {
|
||||||
|
isMouseDown = false;
|
||||||
|
isMouseInView = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getOriginMouseX() {
|
||||||
|
return originMouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getOriginMouseY() {
|
||||||
|
return originMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getOriginDeltaMouseX() {
|
||||||
|
return mouseX - originMouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getOriginDeltaMouseY() {
|
||||||
|
return mouseY - originMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getDeltaMouseX() {
|
||||||
|
return deltaMouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getDeltaMouseY() {
|
||||||
|
return deltaMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getLastMouseX() {
|
||||||
|
return lastMouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getLastMouseY() {
|
||||||
|
return lastMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getMouseX() {
|
||||||
|
return mouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseTracker::getMouseY() {
|
||||||
|
return mouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::setVertDragLock(bool dragLock) {
|
||||||
|
vertDragLock = dragLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseTracker::mouseDown() {
|
||||||
|
return isMouseDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MouseTracker::mouseInView() {
|
||||||
|
return isMouseInView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseTracker::setTarget(wxWindow *target_in) {
|
||||||
|
target = target_in;
|
||||||
|
}
|
51
src/util/MouseTracker.h
Normal file
51
src/util/MouseTracker.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wx/window.h"
|
||||||
|
|
||||||
|
class MouseTracker {
|
||||||
|
public:
|
||||||
|
MouseTracker(wxWindow *target) :
|
||||||
|
target(target), mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), isMouseDown(
|
||||||
|
false), vertDragLock(false), isMouseInView(false) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseTracker() :
|
||||||
|
target(NULL), mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), isMouseDown(
|
||||||
|
false), vertDragLock(false), isMouseInView(false) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnMouseMoved(wxMouseEvent& event);
|
||||||
|
void OnMouseDown(wxMouseEvent& event);
|
||||||
|
void OnMouseWheelMoved(wxMouseEvent& event);
|
||||||
|
void OnMouseReleased(wxMouseEvent& event);
|
||||||
|
void OnMouseEnterWindow(wxMouseEvent& event);
|
||||||
|
void OnMouseLeftWindow(wxMouseEvent& event);
|
||||||
|
|
||||||
|
float getOriginMouseX();
|
||||||
|
float getOriginMouseY();
|
||||||
|
float getOriginDeltaMouseX();
|
||||||
|
float getOriginDeltaMouseY();
|
||||||
|
float getDeltaMouseX();
|
||||||
|
float getDeltaMouseY();
|
||||||
|
float getLastMouseX();
|
||||||
|
float getLastMouseY();
|
||||||
|
float getMouseX();
|
||||||
|
float getMouseY();
|
||||||
|
|
||||||
|
void setVertDragLock(bool dragLock);
|
||||||
|
bool mouseDown();
|
||||||
|
bool mouseInView();
|
||||||
|
void setTarget(wxWindow *target_in);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float mouseX, mouseY;
|
||||||
|
float lastMouseX, lastMouseY;
|
||||||
|
float deltaMouseX, deltaMouseY;
|
||||||
|
float originMouseX, originMouseY;
|
||||||
|
|
||||||
|
bool isMouseDown, isMouseInView;
|
||||||
|
bool vertDragLock;
|
||||||
|
wxWindow *target;
|
||||||
|
};
|
@ -57,13 +57,13 @@ void ScopeCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq += 100000;
|
freq += 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_LEFT:
|
case WXK_LEFT:
|
||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq -= 100000;
|
freq -= 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_DOWN:
|
case WXK_DOWN:
|
||||||
break;
|
break;
|
||||||
@ -81,7 +81,7 @@ void ScopeCanvas::OnIdle(wxIdleEvent &event) {
|
|||||||
// timer.update();
|
// timer.update();
|
||||||
// frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
// if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
// frameTimer = 0;
|
// frameTimer = 0;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ private:
|
|||||||
|
|
||||||
ScopeContext *glContext;
|
ScopeContext *glContext;
|
||||||
Timer timer;
|
Timer timer;
|
||||||
float frameTimer;
|
float frameTimer;
|
||||||
// event table
|
// event table
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,7 @@ wxEND_EVENT_TABLE()
|
|||||||
|
|
||||||
SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
|
SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
|
||||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), isMouseDown(false) {
|
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0) {
|
||||||
|
|
||||||
int in_block_size = BUF_SIZE / 2;
|
int in_block_size = BUF_SIZE / 2;
|
||||||
int out_block_size = FFT_SIZE;
|
int out_block_size = FFT_SIZE;
|
||||||
@ -44,6 +44,9 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
|
|||||||
glContext = new SpectrumContext(this, &wxGetApp().GetContext(this));
|
glContext = new SpectrumContext(this, &wxGetApp().GetContext(this));
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
|
mTracker.setTarget(this);
|
||||||
|
mTracker.setVertDragLock(true);
|
||||||
|
|
||||||
SetCursor(wxCURSOR_SIZEWE);
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,13 +75,13 @@ void SpectrumCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq += 100000;
|
freq += 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_LEFT:
|
case WXK_LEFT:
|
||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq -= 100000;
|
freq -= 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_DOWN:
|
case WXK_DOWN:
|
||||||
break;
|
break;
|
||||||
@ -167,62 +170,44 @@ void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
|
|||||||
// timer.update();
|
// timer.update();
|
||||||
// frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
// if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
// frameTimer = 0;
|
// frameTimer = 0;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {
|
void SpectrumCanvas::mouseMoved(wxMouseEvent& event) {
|
||||||
if (isMouseDown) {
|
mTracker.OnMouseMoved(event);
|
||||||
const wxSize ClientSize = GetClientSize();
|
if (mTracker.mouseDown()) {
|
||||||
float mouseX = (float)event.m_x/(float)ClientSize.x;
|
int freqChange = mTracker.getDeltaMouseX() * SRATE;
|
||||||
float mouseY = (float)event.m_y/(float)ClientSize.y;
|
|
||||||
|
|
||||||
|
if (freqChange != 0) {
|
||||||
|
int freq = wxGetApp().getFrequency();
|
||||||
|
freq -= freqChange;
|
||||||
|
wxGetApp().setFrequency(freq);
|
||||||
|
|
||||||
deltaMouseX = mouseX-lastMouseX;
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
|
||||||
deltaMouseY = mouseY-lastMouseY;
|
wxString::Format(wxT("Set center frequency: %s"),
|
||||||
|
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
|
||||||
lastMouseX = mouseX;
|
|
||||||
// lastMouseY = mouseY;
|
|
||||||
|
|
||||||
int freqChange = deltaMouseX*SRATE;
|
|
||||||
|
|
||||||
int freq = wxGetApp().getFrequency();
|
|
||||||
freq -= freqChange;
|
|
||||||
wxGetApp().setFrequency(freq);
|
|
||||||
|
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %s"),wxNumberFormatter::ToString((long)freq,wxNumberFormatter::Style_WithThousandsSep)));
|
|
||||||
|
|
||||||
if (mouseY != lastMouseY) {
|
|
||||||
WarpPointer(event.m_x,lastMouseY*ClientSize.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCanvas::mouseDown(wxMouseEvent& event) {
|
void SpectrumCanvas::mouseDown(wxMouseEvent& event) {
|
||||||
const wxSize ClientSize = GetClientSize();
|
mTracker.OnMouseDown(event);
|
||||||
lastMouseX = (float)event.m_x/(float)ClientSize.x;
|
|
||||||
lastMouseY = (float)event.m_y/(float)ClientSize.y;
|
|
||||||
|
|
||||||
isMouseDown = true;
|
|
||||||
SetCursor(wxCURSOR_CROSS);
|
SetCursor(wxCURSOR_CROSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCanvas::mouseWheelMoved(wxMouseEvent& event) {
|
void SpectrumCanvas::mouseWheelMoved(wxMouseEvent& event) {
|
||||||
std::cout << "wheel?" << std::endl;
|
mTracker.OnMouseWheelMoved(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCanvas::mouseReleased(wxMouseEvent& event) {
|
void SpectrumCanvas::mouseReleased(wxMouseEvent& event) {
|
||||||
isMouseDown = false;
|
mTracker.OnMouseReleased(event);
|
||||||
SetCursor(wxCURSOR_SIZEWE);
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCanvas::mouseLeftWindow(wxMouseEvent& event) {
|
void SpectrumCanvas::mouseLeftWindow(wxMouseEvent& event) {
|
||||||
isMouseDown = false;
|
mTracker.OnMouseLeftWindow(event);
|
||||||
SetCursor(wxCURSOR_SIZEWE);
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "fftw3.h"
|
#include "fftw3.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "MouseTracker.h"
|
||||||
|
|
||||||
class SpectrumCanvas: public wxGLCanvas {
|
class SpectrumCanvas: public wxGLCanvas {
|
||||||
public:
|
public:
|
||||||
@ -48,9 +49,7 @@ private:
|
|||||||
Timer timer;
|
Timer timer;
|
||||||
float frameTimer;
|
float frameTimer;
|
||||||
|
|
||||||
float lastMouseX, lastMouseY;
|
MouseTracker mTracker;
|
||||||
float deltaMouseX, deltaMouseY;
|
|
||||||
bool isMouseDown;
|
|
||||||
// event table
|
// event table
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -15,9 +15,16 @@
|
|||||||
#include "AppFrame.h"
|
#include "AppFrame.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <wx/numformatter.h>
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
|
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
|
||||||
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
|
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
|
||||||
EVT_IDLE(WaterfallCanvas::OnIdle)
|
EVT_IDLE(WaterfallCanvas::OnIdle)
|
||||||
|
EVT_MOTION(WaterfallCanvas::mouseMoved)
|
||||||
|
EVT_LEFT_DOWN(WaterfallCanvas::mouseDown)
|
||||||
|
EVT_LEFT_UP(WaterfallCanvas::mouseReleased)
|
||||||
|
EVT_LEAVE_WINDOW(WaterfallCanvas::mouseLeftWindow)
|
||||||
|
EVT_ENTER_WINDOW(WaterfallCanvas::mouseEnterWindow)
|
||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
||||||
@ -37,6 +44,8 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
|||||||
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
|
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
|
mTracker.setTarget(this);
|
||||||
|
|
||||||
SetCursor(wxCURSOR_CROSS);
|
SetCursor(wxCURSOR_CROSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,8 +60,14 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
glContext->SetCurrent(*this);
|
glContext->SetCurrent(*this);
|
||||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||||
|
|
||||||
|
glContext->BeginDraw();
|
||||||
glContext->Draw(spectrum_points);
|
glContext->Draw(spectrum_points);
|
||||||
|
|
||||||
|
if (mTracker.mouseInView()) {
|
||||||
|
glContext->DrawFreqSelector(mTracker.getMouseX());
|
||||||
|
}
|
||||||
|
glContext->EndDraw();
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,13 +80,13 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq += 100000;
|
freq += 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_LEFT:
|
case WXK_LEFT:
|
||||||
freq = wxGetApp().getFrequency();
|
freq = wxGetApp().getFrequency();
|
||||||
freq -= 100000;
|
freq -= 100000;
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
((wxFrame*)parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"),freq));
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||||
break;
|
break;
|
||||||
case WXK_DOWN:
|
case WXK_DOWN:
|
||||||
break;
|
break;
|
||||||
@ -158,7 +173,64 @@ void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
|
|||||||
// timer.update();
|
// timer.update();
|
||||||
// frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
// if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
// frameTimer = 0;
|
// frameTimer = 0;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseMoved(event);
|
||||||
|
if (mTracker.mouseDown()) {
|
||||||
|
int freqChange = mTracker.getDeltaMouseX() * SRATE;
|
||||||
|
|
||||||
|
if (freqChange != 0) {
|
||||||
|
int freq = wxGetApp().getFrequency();
|
||||||
|
freq -= freqChange;
|
||||||
|
wxGetApp().setFrequency(freq);
|
||||||
|
|
||||||
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
|
||||||
|
wxString::Format(wxT("Set center frequency: %s"),
|
||||||
|
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseDown(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseDown(event);
|
||||||
|
SetCursor(wxCURSOR_CROSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseWheelMoved(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseWheelMoved(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseReleased(event);
|
||||||
|
|
||||||
|
if (mTracker.getOriginDeltaMouseX() == 0 && mTracker.getOriginDeltaMouseX() == 0) {
|
||||||
|
|
||||||
|
float pos = mTracker.getMouseX();
|
||||||
|
|
||||||
|
int freq = wxGetApp().getFrequency();
|
||||||
|
|
||||||
|
freq += (pos - 0.5) * SRATE;
|
||||||
|
|
||||||
|
wxGetApp().setFrequency(freq);
|
||||||
|
|
||||||
|
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
|
||||||
|
wxString::Format(wxT("Set center frequency: %s"),
|
||||||
|
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseLeftWindow(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseLeftWindow(event);
|
||||||
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallCanvas::mouseEnterWindow(wxMouseEvent& event) {
|
||||||
|
mTracker.OnMouseEnterWindow(event);
|
||||||
|
SetCursor(wxCURSOR_SIZEWE);
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "WaterfallContext.h"
|
#include "WaterfallContext.h"
|
||||||
|
#include "MouseTracker.h"
|
||||||
|
|
||||||
#include "fftw3.h"
|
#include "fftw3.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
@ -23,6 +24,13 @@ private:
|
|||||||
|
|
||||||
void OnIdle(wxIdleEvent &event);
|
void OnIdle(wxIdleEvent &event);
|
||||||
|
|
||||||
|
void mouseMoved(wxMouseEvent& event);
|
||||||
|
void mouseDown(wxMouseEvent& event);
|
||||||
|
void mouseWheelMoved(wxMouseEvent& event);
|
||||||
|
void mouseReleased(wxMouseEvent& event);
|
||||||
|
void mouseEnterWindow(wxMouseEvent& event);
|
||||||
|
void mouseLeftWindow(wxMouseEvent& event);
|
||||||
|
|
||||||
wxWindow *parent;
|
wxWindow *parent;
|
||||||
std::vector<float> spectrum_points;
|
std::vector<float> spectrum_points;
|
||||||
|
|
||||||
@ -39,6 +47,8 @@ private:
|
|||||||
WaterfallContext *glContext;
|
WaterfallContext *glContext;
|
||||||
Timer timer;
|
Timer timer;
|
||||||
float frameTimer;
|
float frameTimer;
|
||||||
|
MouseTracker mTracker;
|
||||||
|
|
||||||
// event table
|
// event table
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "WaterfallContext.h"
|
#include "WaterfallContext.h"
|
||||||
#include "WaterfallCanvas.h"
|
#include "WaterfallCanvas.h"
|
||||||
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext) :
|
WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext) :
|
||||||
PrimaryGLContext(canvas, sharedContext) {
|
PrimaryGLContext(canvas, sharedContext) {
|
||||||
@ -36,11 +37,14 @@ WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedC
|
|||||||
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(grad.getBlue())[0]);
|
glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(grad.getBlue())[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallContext::Draw(std::vector<float> &points) {
|
void WaterfallContext::BeginDraw() {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallContext::Draw(std::vector<float> &points) {
|
||||||
|
|
||||||
if (points.size()) {
|
if (points.size()) {
|
||||||
memmove(waterfall_tex + FFT_SIZE, waterfall_tex, (NUM_WATERFALL_LINES - 1) * FFT_SIZE);
|
memmove(waterfall_tex + FFT_SIZE, waterfall_tex, (NUM_WATERFALL_LINES - 1) * FFT_SIZE);
|
||||||
@ -57,15 +61,13 @@ void WaterfallContext::Draw(std::vector<float> &points) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, waterfall);
|
glBindTexture(GL_TEXTURE_2D, waterfall);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FFT_SIZE, NUM_WATERFALL_LINES, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FFT_SIZE, NUM_WATERFALL_LINES, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
// glEnable(GL_COLOR_TABLE);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, waterfall);
|
glBindTexture(GL_TEXTURE_2D, waterfall);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0.0, 1.0);
|
glTexCoord2f(0.0, 1.0);
|
||||||
@ -78,6 +80,37 @@ void WaterfallContext::Draw(std::vector<float> &points) {
|
|||||||
glVertex3f(-1.0, 1.0, 0.0);
|
glVertex3f(-1.0, 1.0, 0.0);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallContext::DrawFreqSelector(float uxPos) {
|
||||||
|
DemodulatorInstance *demod = wxGetApp().getDemodTest();
|
||||||
|
|
||||||
|
if (!demod) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0, 1.0, 0.0);
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0, -1.0, 0.0);
|
||||||
|
|
||||||
|
float ofs = ((float) demod->params.inputResampleRate) / (float) SRATE;
|
||||||
|
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0);
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0 - ofs, -1.0, 0.0);
|
||||||
|
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0 + ofs, 1.0, 0.0);
|
||||||
|
glVertex3f((uxPos - 0.5) * 2.0 + ofs, -1.0, 0.0);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaterfallContext::EndDraw() {
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|
||||||
CheckGLError();
|
CheckGLError();
|
||||||
|
@ -11,7 +11,10 @@ class WaterfallContext: public PrimaryGLContext {
|
|||||||
public:
|
public:
|
||||||
WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext);
|
WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext);
|
||||||
|
|
||||||
|
void BeginDraw();
|
||||||
void Draw(std::vector<float> &points);
|
void Draw(std::vector<float> &points);
|
||||||
|
void DrawFreqSelector(float uxPos);
|
||||||
|
void EndDraw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gradient grad;
|
Gradient grad;
|
||||||
|
Loading…
Reference in New Issue
Block a user