Merge pull request #24 from cjcliffe/mode-selector
GL mode selector, up/down converter support, OSX fixes
This commit is contained in:
commit
7d25bdac72
|
@ -141,6 +141,8 @@ SET (cubicsdr_sources
|
|||
src/visual/MeterContext.cpp
|
||||
src/visual/TuningCanvas.cpp
|
||||
src/visual/TuningContext.cpp
|
||||
src/visual/ModeSelectorCanvas.cpp
|
||||
src/visual/ModeSelectorContext.cpp
|
||||
src/visual/ScopeCanvas.cpp
|
||||
src/visual/ScopeContext.cpp
|
||||
src/visual/SpectrumCanvas.cpp
|
||||
|
@ -175,6 +177,8 @@ SET (cubicsdr_headers
|
|||
src/visual/MeterContext.h
|
||||
src/visual/TuningCanvas.h
|
||||
src/visual/TuningContext.h
|
||||
src/visual/ModeSelectorCanvas.h
|
||||
src/visual/ModeSelectorContext.h
|
||||
src/visual/ScopeCanvas.h
|
||||
src/visual/ScopeContext.h
|
||||
src/visual/SpectrumCanvas.h
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "wx/numdlg.h"
|
||||
|
||||
#if !wxUSE_GLCANVAS
|
||||
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
||||
#endif
|
||||
|
@ -38,6 +40,16 @@ AppFrame::AppFrame() :
|
|||
wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
|
||||
demodModeSelector = new ModeSelectorCanvas(this, NULL);
|
||||
demodModeSelector->addChoice(DEMOD_TYPE_FM,"FM");
|
||||
demodModeSelector->addChoice(DEMOD_TYPE_AM,"AM");
|
||||
demodModeSelector->addChoice(DEMOD_TYPE_LSB,"LSB");
|
||||
demodModeSelector->addChoice(DEMOD_TYPE_USB,"USB");
|
||||
demodTray->Add(demodModeSelector, 2, wxEXPAND | wxALL, 0);
|
||||
|
||||
// demodTray->AddSpacer(2);
|
||||
|
||||
demodSpectrumCanvas = new SpectrumCanvas(this, NULL);
|
||||
demodSpectrumCanvas->setup(1024);
|
||||
demodSpectrumCanvas->setView(DEFAULT_FREQ, 300000);
|
||||
|
@ -88,20 +100,22 @@ AppFrame::AppFrame() :
|
|||
|
||||
this->SetSizer(vbox);
|
||||
|
||||
waterfallCanvas->SetFocusFromKbd();
|
||||
// waterfallCanvas->SetFocusFromKbd();
|
||||
waterfallCanvas->SetFocus();
|
||||
|
||||
// SetIcon(wxICON(sample));
|
||||
|
||||
// Make a menubar
|
||||
// wxMenu *menu = new wxMenu;
|
||||
// menu->Append(wxID_NEW);
|
||||
// menu->AppendSeparator();
|
||||
// menu->Append(wxID_CLOSE);
|
||||
// wxMenuBar *menuBar = new wxMenuBar;
|
||||
// menuBar->Append(menu, wxT("&File"));
|
||||
|
||||
wxMenuBar *menuBar = new wxMenuBar;
|
||||
wxMenu *menu = new wxMenu;
|
||||
// menu->Append(wxID_NEW);
|
||||
menu->Append(wxID_SET_FREQ_OFFSET, "Set Frequency Offset");
|
||||
menu->AppendSeparator();
|
||||
menu->Append(wxID_CLOSE);
|
||||
|
||||
menuBar->Append(menu, wxT("&File"));
|
||||
|
||||
menu = new wxMenu;
|
||||
|
||||
std::vector<RtAudio::DeviceInfo>::iterator devices_i;
|
||||
std::map<int, RtAudio::DeviceInfo>::iterator mdevices_i;
|
||||
|
@ -130,17 +144,8 @@ AppFrame::AppFrame() :
|
|||
outputDeviceMenuItems[mdevices_i->first] = itm;
|
||||
}
|
||||
|
||||
wxMenuBar *menuBar = new wxMenuBar;
|
||||
menuBar->Append(menu, wxT("Active Demodulator &Output"));
|
||||
|
||||
wxMenu *demodMenu = new wxMenu;
|
||||
demodMenuItems[DEMOD_TYPE_FM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_FM, wxT("FM"), wxT("Description?"));
|
||||
demodMenuItems[DEMOD_TYPE_AM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_AM, wxT("AM"), wxT("Description?"));
|
||||
demodMenuItems[DEMOD_TYPE_LSB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_LSB, wxT("LSB"), wxT("Description?"));
|
||||
demodMenuItems[DEMOD_TYPE_USB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_USB, wxT("USB"), wxT("Description?"));
|
||||
|
||||
menuBar->Append(demodMenu, wxT("Active Demodulator &Type"));
|
||||
|
||||
SetMenuBar(menuBar);
|
||||
|
||||
CreateStatusBar();
|
||||
|
@ -165,22 +170,9 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
|||
activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE);
|
||||
activeDemodulator = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeDemodulator) {
|
||||
if (event.GetId() == wxID_DEMOD_TYPE_FM) {
|
||||
activeDemodulator->setDemodulatorType(DEMOD_TYPE_FM);
|
||||
activeDemodulator = NULL;
|
||||
} else if (event.GetId() == wxID_DEMOD_TYPE_AM) {
|
||||
activeDemodulator->setDemodulatorType(DEMOD_TYPE_AM);
|
||||
activeDemodulator = NULL;
|
||||
} else if (event.GetId() == wxID_DEMOD_TYPE_LSB) {
|
||||
activeDemodulator->setDemodulatorType(DEMOD_TYPE_LSB);
|
||||
activeDemodulator = NULL;
|
||||
} else if (event.GetId() == wxID_DEMOD_TYPE_USB) {
|
||||
activeDemodulator->setDemodulatorType(DEMOD_TYPE_USB);
|
||||
activeDemodulator = NULL;
|
||||
}
|
||||
} else if (event.GetId() == wxID_SET_FREQ_OFFSET) {
|
||||
long ofs = wxGetNumberFromUser ("Shift the displayed frequency by this amount.\ni.e. -125000000 for -125 MHz", "Frequency (Hz)", "Frequency Offset", 0, -2000000000, 2000000000, this);
|
||||
wxGetApp().setOffset(ofs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,13 +205,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||
scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
|
||||
outputDeviceMenuItems[outputDevice]->Check(true);
|
||||
int dType = demod->getDemodulatorType();
|
||||
demodMenuItems[dType]->Check(true);
|
||||
demodModeSelector->setSelection(dType);
|
||||
}
|
||||
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||
if (demod->getParams().frequency != demodWaterfallCanvas->getCenterFrequency()) {
|
||||
demodWaterfallCanvas->setCenterFrequency(demod->getFrequency());
|
||||
demodSpectrumCanvas->setCenterFrequency(demod->getFrequency());
|
||||
}
|
||||
int dSelection = demodModeSelector->getSelection();
|
||||
if (dSelection != -1 && dSelection != demod->getDemodulatorType()) {
|
||||
demod->setDemodulatorType(dSelection);
|
||||
}
|
||||
|
||||
unsigned int demodBw = (unsigned int) ceil((float) demod->getParams().bandwidth * 2.5);
|
||||
if (demodBw > SRATE / 2) {
|
||||
demodBw = SRATE / 2;
|
||||
|
@ -274,6 +271,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||
work_done = true;
|
||||
}
|
||||
|
||||
if (!waterfallCanvas->HasFocus()) {
|
||||
waterfallCanvas->SetFocus();
|
||||
}
|
||||
|
||||
if (!work_done) {
|
||||
event.Skip();
|
||||
}
|
||||
|
|
|
@ -8,14 +8,12 @@
|
|||
#include "WaterfallCanvas.h"
|
||||
#include "MeterCanvas.h"
|
||||
#include "TuningCanvas.h"
|
||||
#include "ModeSelectorCanvas.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#define wxID_RT_AUDIO_DEVICE 1000
|
||||
#define wxID_DEMOD_TYPE_FM 2000
|
||||
#define wxID_DEMOD_TYPE_AM 2001
|
||||
#define wxID_DEMOD_TYPE_LSB 2002
|
||||
#define wxID_DEMOD_TYPE_USB 2003
|
||||
#define wxID_SET_FREQ_OFFSET 2001
|
||||
|
||||
// Define a new frame type
|
||||
class AppFrame: public wxFrame {
|
||||
|
@ -34,6 +32,7 @@ private:
|
|||
ScopeCanvas *scopeCanvas;
|
||||
SpectrumCanvas *spectrumCanvas;
|
||||
WaterfallCanvas *waterfallCanvas;
|
||||
ModeSelectorCanvas *demodModeSelector;
|
||||
SpectrumCanvas *demodSpectrumCanvas;
|
||||
WaterfallCanvas *demodWaterfallCanvas;
|
||||
MeterCanvas *demodSignalMeter;
|
||||
|
@ -47,7 +46,5 @@ private:
|
|||
std::map<int,RtAudio::DeviceInfo> outputDevices;
|
||||
std::map<int,wxMenuItem *> outputDeviceMenuItems;
|
||||
|
||||
std::map<int,wxMenuItem *> demodMenuItems;
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ bool CubicSDR::OnInit() {
|
|||
return false;
|
||||
|
||||
frequency = DEFAULT_FREQ;
|
||||
offset = 0;
|
||||
|
||||
audioVisualQueue = new DemodulatorThreadOutputQueue();
|
||||
audioVisualQueue->set_max_num_items(1);
|
||||
|
@ -110,6 +111,17 @@ void CubicSDR::setFrequency(long long freq) {
|
|||
threadCmdQueueSDR->push(command);
|
||||
}
|
||||
|
||||
long long CubicSDR::getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
void CubicSDR::setOffset(long long ofs) {
|
||||
offset = ofs;
|
||||
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET);
|
||||
command.llong_value = ofs;
|
||||
threadCmdQueueSDR->push(command);
|
||||
}
|
||||
|
||||
long long CubicSDR::getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
void setFrequency(long long freq);
|
||||
long long getFrequency();
|
||||
|
||||
void setOffset(long long ofs);
|
||||
long long getOffset();
|
||||
|
||||
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
||||
DemodulatorThreadInputQueue* getIQVisualQueue();
|
||||
DemodulatorMgr &getDemodMgr();
|
||||
|
@ -45,6 +48,7 @@ private:
|
|||
DemodulatorMgr demodMgr;
|
||||
|
||||
long long frequency;
|
||||
long long offset;
|
||||
|
||||
SDRThread *sdrThread;
|
||||
SDRPostThread *sdrPostThread;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "CubicSDR.h"
|
||||
|
||||
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
||||
commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false) {
|
||||
commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false), offset(0) {
|
||||
dev = NULL;
|
||||
sampleRate = SRATE;
|
||||
}
|
||||
|
@ -137,7 +137,9 @@ void SDRThread::threadMain() {
|
|||
|
||||
if (!cmdQueue->empty()) {
|
||||
bool freq_changed = false;
|
||||
bool offset_changed = false;
|
||||
long long new_freq;
|
||||
long long new_offset;
|
||||
|
||||
while (!cmdQueue->empty()) {
|
||||
SDRThreadCommand command;
|
||||
|
@ -152,14 +154,24 @@ void SDRThread::threadMain() {
|
|||
}
|
||||
std::cout << "Set frequency: " << new_freq << std::endl;
|
||||
break;
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_SET_OFFSET:
|
||||
offset_changed = true;
|
||||
new_offset = command.llong_value;
|
||||
std::cout << "Set offset: " << new_offset << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset_changed && !freq_changed) {
|
||||
new_freq = frequency;
|
||||
freq_changed = true;
|
||||
offset = new_offset;
|
||||
}
|
||||
if (freq_changed) {
|
||||
frequency = new_freq;
|
||||
rtlsdr_set_center_freq(dev, frequency);
|
||||
rtlsdr_set_center_freq(dev, frequency-offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class SDRThreadCommand {
|
||||
public:
|
||||
enum SDRThreadCommandEnum {
|
||||
SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE
|
||||
SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE, SDR_THREAD_CMD_SET_OFFSET
|
||||
};
|
||||
|
||||
SDRThreadCommand() :
|
||||
|
@ -76,6 +76,7 @@ public:
|
|||
void terminate();
|
||||
protected:
|
||||
uint32_t sampleRate;
|
||||
long long offset;
|
||||
std::atomic<SDRThreadCommandQueue*> commandQueue;
|
||||
std::atomic<SDRThreadIQDataQueue*> iqDataOutQueue;
|
||||
|
||||
|
|
|
@ -149,6 +149,14 @@ void MouseTracker::setHorizDragLock(bool dragLock) {
|
|||
horizDragLock = dragLock;
|
||||
}
|
||||
|
||||
bool MouseTracker::getVertDragLock() {
|
||||
return vertDragLock;
|
||||
}
|
||||
|
||||
bool MouseTracker::getHorizDragLock() {
|
||||
return horizDragLock;
|
||||
}
|
||||
|
||||
bool MouseTracker::mouseDown() {
|
||||
return isMouseDown;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
|
||||
void setVertDragLock(bool dragLock);
|
||||
void setHorizDragLock(bool dragLock);
|
||||
bool getVertDragLock();
|
||||
bool getHorizDragLock();
|
||||
bool mouseDown();
|
||||
bool mouseRightDown();
|
||||
bool mouseInView();
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
#include "ModeSelectorCanvas.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 <algorithm>
|
||||
|
||||
wxBEGIN_EVENT_TABLE(ModeSelectorCanvas, wxGLCanvas) EVT_PAINT(ModeSelectorCanvas::OnPaint)
|
||||
EVT_IDLE(ModeSelectorCanvas::OnIdle)
|
||||
EVT_MOTION(ModeSelectorCanvas::OnMouseMoved)
|
||||
EVT_LEFT_DOWN(ModeSelectorCanvas::OnMouseDown)
|
||||
EVT_LEFT_UP(ModeSelectorCanvas::OnMouseReleased)
|
||||
EVT_LEAVE_WINDOW(ModeSelectorCanvas::OnMouseLeftWindow)
|
||||
EVT_ENTER_WINDOW(ModeSelectorCanvas::OnMouseEnterWindow)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
ModeSelectorCanvas::ModeSelectorCanvas(wxWindow *parent, int *attribList) :
|
||||
InteractiveCanvas(parent, attribList), currentSelection(-1), numChoices(0) {
|
||||
|
||||
glContext = new ModeSelectorContext(this, &wxGetApp().GetContext(this));
|
||||
}
|
||||
|
||||
ModeSelectorCanvas::~ModeSelectorCanvas() {
|
||||
|
||||
}
|
||||
|
||||
int ModeSelectorCanvas::getHoveredSelection() {
|
||||
if (!mouseTracker.mouseInView()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
float ypos = 1.0 - (mouseTracker.getMouseY() * 2.0);
|
||||
float yval = (int) (((ypos + 1.0) / 2.0) * (float) numChoices);
|
||||
|
||||
return yval;
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
wxPaintDC dc(this);
|
||||
const wxSize ClientSize = GetClientSize();
|
||||
|
||||
glContext->SetCurrent(*this);
|
||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||
|
||||
glContext->DrawBegin();
|
||||
|
||||
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
|
||||
|
||||
int demodType = 0;
|
||||
if (demod) {
|
||||
demodType = demod->getDemodulatorType();
|
||||
}
|
||||
|
||||
int yval = getHoveredSelection();
|
||||
|
||||
for (int i = 0; i < numChoices; i++) {
|
||||
glContext->DrawSelector(selections[i].label, i, numChoices, i == currentSelection || yval == i, (yval == i)?0.9:0.75, (yval == i)?0.9:0.75, (yval == i)?0.2:0.75, 1.0);
|
||||
}
|
||||
|
||||
glContext->DrawEnd();
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnIdle(wxIdleEvent &event) {
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseMoved(event);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseDown(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseDown(event);
|
||||
mouseTracker.setHorizDragLock(true);
|
||||
mouseTracker.setVertDragLock(true);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseWheelMoved(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseWheelMoved(event);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseReleased(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseReleased(event);
|
||||
mouseTracker.setHorizDragLock(false);
|
||||
mouseTracker.setVertDragLock(false);
|
||||
|
||||
const wxSize ClientSize = GetClientSize();
|
||||
|
||||
if (mouseTracker.getOriginDeltaMouseX() < 2.0 / ClientSize.y) {
|
||||
currentSelection = getHoveredSelection();
|
||||
}
|
||||
|
||||
SetCursor (wxCURSOR_ARROW);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
|
||||
InteractiveCanvas::OnMouseLeftWindow(event);
|
||||
SetCursor (wxCURSOR_CROSS);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::OnMouseEnterWindow(wxMouseEvent& event) {
|
||||
InteractiveCanvas::mouseTracker.OnMouseEnterWindow(event);
|
||||
SetCursor (wxCURSOR_ARROW);
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::setHelpTip(std::string tip) {
|
||||
helpTip = tip;
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::setNumChoices(int numChoices_in) {
|
||||
numChoices = numChoices_in;
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::addChoice(int value, std::string label) {
|
||||
selections.push_back(ModeSelectorMode(value, label));
|
||||
numChoices = selections.size();
|
||||
}
|
||||
|
||||
void ModeSelectorCanvas::setSelection(int value) {
|
||||
for (int i = 0; i < numChoices; i++) {
|
||||
if (selections[i].value == value) {
|
||||
currentSelection = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentSelection = -1;
|
||||
}
|
||||
|
||||
int ModeSelectorCanvas::getSelection() {
|
||||
if (currentSelection == -1) {
|
||||
return -1;
|
||||
}
|
||||
return selections[currentSelection].value;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#include "wx/glcanvas.h"
|
||||
#include "wx/timer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#include "InteractiveCanvas.h"
|
||||
#include "ModeSelectorContext.h"
|
||||
#include "MouseTracker.h"
|
||||
|
||||
#include "fftw3.h"
|
||||
#include "Timer.h"
|
||||
|
||||
class ModeSelectorMode {
|
||||
public:
|
||||
int value;
|
||||
std::string label;
|
||||
|
||||
ModeSelectorMode(int value, std::string label) : value(value), label(label) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class ModeSelectorCanvas: public InteractiveCanvas {
|
||||
public:
|
||||
ModeSelectorCanvas(wxWindow *parent, int *attribList = NULL);
|
||||
~ModeSelectorCanvas();
|
||||
|
||||
int getHoveredSelection();
|
||||
void setHelpTip(std::string tip);
|
||||
|
||||
void addChoice(int value, std::string label);
|
||||
void setSelection(int value);
|
||||
int getSelection();
|
||||
|
||||
private:
|
||||
void setNumChoices(int numChoices_in);
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnIdle(wxIdleEvent &event);
|
||||
|
||||
void OnMouseMoved(wxMouseEvent& event);
|
||||
void OnMouseDown(wxMouseEvent& event);
|
||||
void OnMouseWheelMoved(wxMouseEvent& event);
|
||||
void OnMouseReleased(wxMouseEvent& event);
|
||||
void OnMouseEnterWindow(wxMouseEvent& event);
|
||||
void OnMouseLeftWindow(wxMouseEvent& event);
|
||||
|
||||
ModeSelectorContext *glContext;
|
||||
|
||||
std::string helpTip;
|
||||
int numChoices;
|
||||
int currentSelection;
|
||||
std::vector<ModeSelectorMode> selections;
|
||||
//
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#include "ModeSelectorContext.h"
|
||||
#include "ModeSelectorCanvas.h"
|
||||
|
||||
ModeSelectorContext::ModeSelectorContext(ModeSelectorCanvas *canvas, wxGLContext *sharedContext) :
|
||||
PrimaryGLContext(canvas, sharedContext) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void ModeSelectorContext::DrawBegin() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void ModeSelectorContext::DrawSelector(std::string label, int c, int cMax, bool on, float r, float g, float b, float a) {
|
||||
GLint vp[4];
|
||||
glGetIntegerv( GL_VIEWPORT, vp);
|
||||
|
||||
float viewHeight = (float) vp[3];
|
||||
float viewWidth = (float) vp[2];
|
||||
|
||||
PrimaryGLContext::GLFontSize fontSize = GLFONT_SIZE16;
|
||||
|
||||
int fontHeight = 16;
|
||||
|
||||
if (viewWidth < 30) {
|
||||
fontSize = GLFONT_SIZE12;
|
||||
fontHeight = 12;
|
||||
}
|
||||
|
||||
glColor4f(r, g, b, a);
|
||||
|
||||
float y = 1.0 - ((float) (c+1) / (float) cMax * 2.0);
|
||||
float height = (2.0 / (float) cMax);
|
||||
float padX = (4.0 / viewWidth);
|
||||
float padY = (4.0 / viewHeight);
|
||||
|
||||
glBegin(on?GL_QUADS:GL_LINE_LOOP);
|
||||
glVertex2f(-1.0 + padX, y + padY);
|
||||
glVertex2f(1.0 - padX, y + padY);
|
||||
glVertex2f(1.0 - padX, y + height - padY);
|
||||
glVertex2f(-1.0 + padX, y + height - padY);
|
||||
glEnd();
|
||||
|
||||
if (on) {
|
||||
glColor4f(1.0-r, 1.0-g, 1.0-b, a);
|
||||
}
|
||||
|
||||
getFont(fontSize).drawString(label, 0.0, y + height / 2.0, fontHeight, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
void ModeSelectorContext::DrawEnd() {
|
||||
glFlush();
|
||||
|
||||
CheckGLError();
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "PrimaryGLContext.h"
|
||||
#include "Gradient.h"
|
||||
|
||||
#define NUM_WATERFALL_LINES 512
|
||||
|
||||
class ModeSelectorCanvas;
|
||||
|
||||
class ModeSelectorContext: public PrimaryGLContext {
|
||||
public:
|
||||
ModeSelectorContext(ModeSelectorCanvas *canvas, wxGLContext *sharedContext);
|
||||
|
||||
void DrawBegin();
|
||||
void DrawSelector(std::string label, int c, int cMax, bool on, float r, float g, float b, float a);
|
||||
void DrawEnd();
|
||||
};
|
Loading…
Reference in New Issue