diff --git a/src/visual/MeterCanvas.cpp b/src/visual/MeterCanvas.cpp new file mode 100644 index 0000000..61989b9 --- /dev/null +++ b/src/visual/MeterCanvas.cpp @@ -0,0 +1,131 @@ +#include "MeterCanvas.h" + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if !wxUSE_GLCANVAS +#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" +#endif + +#include "CubicSDR.h" +#include "CubicSDRDefs.h" +#include "AppFrame.h" +#include + +wxBEGIN_EVENT_TABLE(MeterCanvas, wxGLCanvas) EVT_PAINT(MeterCanvas::OnPaint) +EVT_IDLE(MeterCanvas::OnIdle) +EVT_MOTION(MeterCanvas::mouseMoved) +EVT_LEFT_DOWN(MeterCanvas::mouseDown) +EVT_LEFT_UP(MeterCanvas::mouseReleased) +EVT_LEAVE_WINDOW(MeterCanvas::mouseLeftWindow) +EVT_ENTER_WINDOW(MeterCanvas::mouseEnterWindow) +wxEND_EVENT_TABLE() + +MeterCanvas::MeterCanvas(wxWindow *parent, int *attribList) : + wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, + wxFULL_REPAINT_ON_RESIZE), parent(parent), level(0), level_max(1), inputValue(0), userInputValue(0), shiftDown(false), altDown(false), ctrlDown(false) { + + glContext = new MeterContext(this, &wxGetApp().GetContext(this)); + mTracker.setTarget(this); +} + +MeterCanvas::~MeterCanvas() { + +} + +void MeterCanvas::setLevel(float level_in) { + level = level_in; +} +float MeterCanvas::getLevel() { + return level; +} + +void MeterCanvas::setMax(float max_in) { + level_max = max_in; +} + +bool MeterCanvas::setInputValue(float slider_in) { + userInputValue = inputValue = slider_in; +} +bool MeterCanvas::inputChanged() { + return (inputValue != userInputValue); +} +float MeterCanvas::getInputValue() { + inputValue = userInputValue; + return userInputValue; +} + +void MeterCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { + wxPaintDC dc(this); + const wxSize ClientSize = GetClientSize(); + + glContext->SetCurrent(*this); + glViewport(0, 0, ClientSize.x, ClientSize.y); + + glContext->DrawBegin(); + if (mTracker.mouseInView()) { + glContext->Draw(0.4, 0.4, 0.4, 0.5, mTracker.getMouseY()); + } + + glContext->Draw(0.1, 0.75, 0.1, 0.5, level/level_max); + + glContext->Draw(0.75, 0.1, 0.1, 0.5, userInputValue/level_max); + + glContext->DrawEnd(); + + SwapBuffers(); +} + +void MeterCanvas::OnIdle(wxIdleEvent &event) { + Refresh(false); +} + +void MeterCanvas::mouseMoved(wxMouseEvent& event) { + mTracker.OnMouseMoved(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); + + if (mTracker.mouseDown()) { + userInputValue = mTracker.getMouseY()*level_max; + } +} + +void MeterCanvas::mouseDown(wxMouseEvent& event) { + mTracker.OnMouseDown(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); + + userInputValue = mTracker.getMouseY()*level_max; + mTracker.setHorizDragLock(true); +} + +void MeterCanvas::mouseWheelMoved(wxMouseEvent& event) { + mTracker.OnMouseWheelMoved(event); +} + +void MeterCanvas::mouseReleased(wxMouseEvent& event) { + mTracker.OnMouseReleased(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); + + userInputValue = mTracker.getMouseY()*level_max; +} + +void MeterCanvas::mouseLeftWindow(wxMouseEvent& event) { + mTracker.OnMouseLeftWindow(event); + SetCursor(wxCURSOR_CROSS); +} + +void MeterCanvas::mouseEnterWindow(wxMouseEvent& event) { + mTracker.OnMouseEnterWindow(event); + SetCursor(wxCURSOR_CROSS); +} diff --git a/src/visual/MeterCanvas.h b/src/visual/MeterCanvas.h new file mode 100644 index 0000000..67da7e5 --- /dev/null +++ b/src/visual/MeterCanvas.h @@ -0,0 +1,57 @@ +#pragma once + +#include "wx/glcanvas.h" +#include "wx/timer.h" + +#include +#include + +#include "MeterContext.h" +#include "MouseTracker.h" + +#include "fftw3.h" +#include "Timer.h" + +class MeterCanvas: public wxGLCanvas { +public: + std::vector waveform_points; + + MeterCanvas(wxWindow *parent, int *attribList = NULL); + ~MeterCanvas(); + + void setLevel(float level_in); + float getLevel(); + + void setMax(float max_in); + + bool setInputValue(float slider_in); + bool inputChanged(); + float getInputValue(); + +private: + void OnPaint(wxPaintEvent& 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); + + MouseTracker mTracker; + wxWindow *parent; + MeterContext *glContext; + + float level; + float level_max; + + float inputValue; + float userInputValue; + + bool shiftDown; + bool altDown; + bool ctrlDown; +wxDECLARE_EVENT_TABLE(); +}; + diff --git a/src/visual/MeterContext.cpp b/src/visual/MeterContext.cpp new file mode 100644 index 0000000..40fe4fd --- /dev/null +++ b/src/visual/MeterContext.cpp @@ -0,0 +1,40 @@ +#include "MeterContext.h" +#include "MeterCanvas.h" + +MeterContext::MeterContext(MeterCanvas *canvas, wxGLContext *sharedContext) : + PrimaryGLContext(canvas, sharedContext) { + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +} + +void MeterContext::DrawBegin() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_TEXTURE_2D); +} + +void MeterContext::Draw(float r, float g, float b, float a, float level) { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glColor4f(r, g, b, a); + glBegin(GL_QUADS); + glVertex2f(1.0, -1.0 + 2.0 * level); + glVertex2f(-1.0, -1.0 + 2.0 * level); + glVertex2f(-1.0, -1.0); + glVertex2f(1.0, -1.0); + glEnd(); + glDisable(GL_BLEND); +} + +void MeterContext::DrawEnd() { + glFlush(); + + CheckGLError(); +} + diff --git a/src/visual/MeterContext.h b/src/visual/MeterContext.h new file mode 100644 index 0000000..3fac2f2 --- /dev/null +++ b/src/visual/MeterContext.h @@ -0,0 +1,19 @@ +#pragma once + +#include "PrimaryGLContext.h" +#include "Gradient.h" + +#define NUM_WATERFALL_LINES 512 + +class MeterCanvas; + +class MeterContext: public PrimaryGLContext { +public: + MeterContext(MeterCanvas *canvas, wxGLContext *sharedContext); + + void DrawBegin(); + void Draw(float r, float g, float b, float a, float level); + void DrawEnd(); + +private: +};