2015-10-27 01:56:49 -04:00
|
|
|
#include "GainCanvas.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(GainCanvas, wxGLCanvas) EVT_PAINT(GainCanvas::OnPaint)
|
|
|
|
EVT_IDLE(GainCanvas::OnIdle)
|
|
|
|
EVT_MOTION(GainCanvas::OnMouseMoved)
|
|
|
|
EVT_LEFT_DOWN(GainCanvas::OnMouseDown)
|
|
|
|
EVT_LEFT_UP(GainCanvas::OnMouseReleased)
|
|
|
|
EVT_LEAVE_WINDOW(GainCanvas::OnMouseLeftWindow)
|
|
|
|
EVT_ENTER_WINDOW(GainCanvas::OnMouseEnterWindow)
|
2016-05-30 19:14:14 -04:00
|
|
|
EVT_MOUSEWHEEL(GainCanvas::OnMouseWheelMoved)
|
2015-10-27 01:56:49 -04:00
|
|
|
wxEND_EVENT_TABLE()
|
|
|
|
|
2016-04-07 20:00:59 -04:00
|
|
|
GainCanvas::GainCanvas(wxWindow *parent, int *dispAttrs) :
|
2016-03-22 20:49:15 -04:00
|
|
|
InteractiveCanvas(parent, dispAttrs) {
|
2015-10-27 01:56:49 -04:00
|
|
|
|
|
|
|
glContext = new PrimaryGLContext(this, &wxGetApp().GetContext(this));
|
|
|
|
bgPanel.setCoordinateSystem(GLPanel::GLPANEL_Y_UP);
|
|
|
|
bgPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_X);
|
|
|
|
|
|
|
|
numGains = 1;
|
|
|
|
spacing = 2.0/numGains;
|
|
|
|
barWidth = (1.0/numGains)*0.8;
|
|
|
|
startPos = spacing/2.0;
|
2016-06-01 19:42:34 -04:00
|
|
|
barHeight = 0.8f;
|
2016-05-11 22:37:25 -04:00
|
|
|
refreshCounter = 0;
|
2015-10-27 01:56:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
GainCanvas::~GainCanvas() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|
|
|
wxPaintDC dc(this);
|
|
|
|
const wxSize ClientSize = GetClientSize();
|
|
|
|
|
|
|
|
glContext->SetCurrent(*this);
|
|
|
|
initGLExtensions();
|
|
|
|
|
|
|
|
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
|
|
|
|
|
|
|
float i = 0;
|
|
|
|
for (std::vector<GainInfo *>::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
GainInfo *gInfo = (*gi);
|
|
|
|
float midPos = -1.0+startPos+spacing*i;
|
|
|
|
|
|
|
|
gInfo->labelPanel.setSize(spacing/2.0,(15.0/float(ClientSize.y)));
|
|
|
|
gInfo->labelPanel.setPosition(midPos, -barHeight-(20.0/float(ClientSize.y)));
|
|
|
|
|
|
|
|
gInfo->valuePanel.setSize(spacing/2.0,(15.0/float(ClientSize.y)));
|
|
|
|
gInfo->valuePanel.setPosition(midPos, barHeight+(20.0/float(ClientSize.y)));
|
|
|
|
|
|
|
|
i+=1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bgPanel.draw();
|
|
|
|
|
|
|
|
SwapBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnIdle(wxIdleEvent &event) {
|
|
|
|
if (mouseTracker.mouseInView()) {
|
|
|
|
Refresh();
|
|
|
|
} else {
|
|
|
|
event.Skip();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (std::vector<GainInfo *>::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
GainInfo *gInfo = (*gi);
|
|
|
|
if (gInfo->changed) {
|
|
|
|
wxGetApp().setGain(gInfo->name, gInfo->current);
|
|
|
|
gInfo->changed = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int GainCanvas::GetPanelHit(CubicVR::vec2 &result) {
|
|
|
|
std::vector<GainInfo *>::iterator gi;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
for (gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
GainInfo *gInfo = (*gi);
|
|
|
|
|
|
|
|
CubicVR::vec2 hitResult;
|
|
|
|
if (gInfo->panel.hitTest(CubicVR::vec2((mouseTracker.getMouseX()-0.5)*2.0, (mouseTracker.getMouseY()-0.5)*2.0), hitResult)) {
|
|
|
|
// std::cout << "Hit #" << i << " result: " << hitResult << std::endl;
|
|
|
|
result = (hitResult + CubicVR::vec2(1.0,1.0)) * 0.5;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GainCanvas::SetLevel() {
|
|
|
|
CubicVR::vec2 hitResult;
|
|
|
|
int panelHit = GetPanelHit(hitResult);
|
|
|
|
|
|
|
|
if (panelHit >= 0) {
|
|
|
|
gainInfo[panelHit]->levelPanel.setSize(1.0, hitResult.y);
|
|
|
|
gainInfo[panelHit]->levelPanel.setPosition(0.0, (-1.0+(hitResult.y)));
|
2016-01-17 10:40:01 -05:00
|
|
|
gainInfo[panelHit]->current = round(gainInfo[panelHit]->low+(hitResult.y * (gainInfo[panelHit]->high-gainInfo[panelHit]->low)));
|
2015-10-27 01:56:49 -04:00
|
|
|
gainInfo[panelHit]->changed = true;
|
2016-06-22 15:21:32 -04:00
|
|
|
gainInfo[panelHit]->valuePanel.setText(std::to_string(int(gainInfo[panelHit]->current)),GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, true);
|
2015-10-27 01:56:49 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseMoved(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::OnMouseMoved(event);
|
|
|
|
|
|
|
|
CubicVR::vec2 hitResult;
|
|
|
|
int panelHit = GetPanelHit(hitResult);
|
|
|
|
|
|
|
|
if (panelHit >= 0) {
|
|
|
|
gainInfo[panelHit]->highlightPanel.setSize(1.0, hitResult.y);
|
|
|
|
gainInfo[panelHit]->highlightPanel.setPosition(0.0, (-1.0+(hitResult.y)));
|
|
|
|
}
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
for (std::vector<GainInfo *>::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
(*gi)->highlightPanel.visible = (i==panelHit);
|
2016-02-07 22:19:05 -05:00
|
|
|
if (i==panelHit) {
|
|
|
|
wxGetApp().setActiveGainEntry((*gi)->name);
|
|
|
|
}
|
2015-10-27 01:56:49 -04:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouseTracker.mouseDown()) {
|
|
|
|
SetLevel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseDown(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::OnMouseDown(event);
|
|
|
|
SetLevel();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseWheelMoved(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::OnMouseWheelMoved(event);
|
2016-05-30 19:14:14 -04:00
|
|
|
|
|
|
|
CubicVR::vec2 hitResult;
|
|
|
|
int panelHit = GetPanelHit(hitResult);
|
|
|
|
|
|
|
|
if (panelHit >= 0) {
|
|
|
|
float movement = 3.0 * (float)event.GetWheelRotation();
|
|
|
|
|
|
|
|
GainInfo *gInfo;
|
|
|
|
|
|
|
|
gInfo = gainInfo[panelHit];
|
|
|
|
|
|
|
|
gInfo->current = gInfo->current + ((movement / 100.0) * ((gInfo->high - gInfo->low) / 100.0));
|
2016-06-01 14:00:21 -04:00
|
|
|
|
|
|
|
//BEGIN Clamp to prevent the meter to escape
|
|
|
|
if (gInfo->current > gInfo->high) {
|
|
|
|
gInfo->current = gInfo->high;
|
|
|
|
}
|
|
|
|
if (gInfo->current < gInfo->low) {
|
|
|
|
gInfo->current = gInfo->low;
|
|
|
|
}
|
|
|
|
|
2016-05-30 19:14:14 -04:00
|
|
|
gInfo->changed = true;
|
|
|
|
|
|
|
|
float levelVal = float(gInfo->current-gInfo->low)/float(gInfo->high-gInfo->low);
|
|
|
|
gInfo->levelPanel.setSize(1.0, levelVal);
|
|
|
|
gInfo->levelPanel.setPosition(0.0, levelVal-1.0);
|
|
|
|
|
2016-06-22 15:21:32 -04:00
|
|
|
gInfo->valuePanel.setText(std::to_string(int(gInfo->current)),GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, true);
|
2016-05-30 19:14:14 -04:00
|
|
|
}
|
|
|
|
|
2015-10-27 01:56:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseReleased(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::OnMouseReleased(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::OnMouseLeftWindow(event);
|
|
|
|
SetCursor(wxCURSOR_CROSS);
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
for (std::vector<GainInfo *>::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
(*gi)->highlightPanel.visible = false;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::OnMouseEnterWindow(wxMouseEvent& event) {
|
|
|
|
InteractiveCanvas::mouseTracker.OnMouseEnterWindow(event);
|
|
|
|
SetCursor(wxCURSOR_CROSS);
|
2016-05-31 17:42:44 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (wxGetApp().getAppFrame()->canFocus()) {
|
|
|
|
this->SetFocus();
|
|
|
|
}
|
|
|
|
#endif
|
2015-10-27 01:56:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void GainCanvas::setHelpTip(std::string tip) {
|
|
|
|
helpTip = tip;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::updateGainUI() {
|
|
|
|
const wxSize ClientSize = GetClientSize();
|
|
|
|
|
|
|
|
SDRDeviceInfo *devInfo = wxGetApp().getDevice();
|
2016-05-11 22:37:25 -04:00
|
|
|
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devInfo->getDeviceId());
|
2015-10-27 01:56:49 -04:00
|
|
|
|
2016-05-11 22:37:25 -04:00
|
|
|
gains = devInfo->getGains(SOAPY_SDR_RX, 0);
|
2016-01-31 15:11:54 -05:00
|
|
|
SDRRangeMap::iterator gi;
|
2015-10-27 01:56:49 -04:00
|
|
|
|
|
|
|
numGains = gains.size();
|
|
|
|
float i = 0;
|
|
|
|
|
|
|
|
if (!numGains) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
spacing = 2.0/numGains;
|
|
|
|
barWidth = (1.0/numGains)*0.7;
|
|
|
|
startPos = spacing/2.0;
|
2016-06-01 19:42:34 -04:00
|
|
|
barHeight = 0.8f;
|
2015-10-27 01:56:49 -04:00
|
|
|
|
|
|
|
RGBA4f c1, c2;
|
|
|
|
|
|
|
|
while (gainInfo.size()) {
|
|
|
|
GainInfo *giDel;
|
|
|
|
giDel = gainInfo.back();
|
|
|
|
gainInfo.pop_back();
|
|
|
|
|
|
|
|
giDel->panel.removeChild(&giDel->levelPanel);
|
|
|
|
bgPanel.removeChild(&(giDel->labelPanel));
|
|
|
|
bgPanel.removeChild(&(giDel->valuePanel));
|
|
|
|
bgPanel.removeChild(&(giDel->panel));
|
|
|
|
delete giDel;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (gi = gains.begin(); gi != gains.end(); gi++) {
|
|
|
|
GainInfo *gInfo = new GainInfo;
|
|
|
|
float midPos = -1.0+startPos+spacing*i;
|
|
|
|
|
2016-01-31 15:11:54 -05:00
|
|
|
gInfo->name = gi->first;
|
|
|
|
gInfo->low = gi->second.minimum();
|
|
|
|
gInfo->high = gi->second.maximum();
|
2016-05-11 22:37:25 -04:00
|
|
|
gInfo->current = devConfig->getGain(gInfo->name,wxGetApp().getGain(gInfo->name));
|
|
|
|
gInfo->changed = false;
|
2015-10-27 01:56:49 -04:00
|
|
|
|
|
|
|
gInfo->panel.setBorderPx(1);
|
|
|
|
gInfo->panel.setFill(GLPanel::GLPANEL_FILL_GRAD_BAR_X);
|
|
|
|
gInfo->panel.setPosition(midPos, 0);
|
|
|
|
gInfo->panel.setSize(barWidth, barHeight);
|
|
|
|
gInfo->panel.setBlend(GL_ONE, GL_ONE);
|
|
|
|
|
|
|
|
gInfo->levelPanel.setBorderPx(0);
|
|
|
|
gInfo->levelPanel.setMarginPx(1);
|
2016-06-01 19:42:34 -04:00
|
|
|
gInfo->levelPanel.setSize(1.0,0.8f);
|
2015-10-27 01:56:49 -04:00
|
|
|
float levelVal = float(gInfo->current-gInfo->low)/float(gInfo->high-gInfo->low);
|
|
|
|
gInfo->levelPanel.setSize(1.0, levelVal);
|
|
|
|
gInfo->levelPanel.setPosition(0.0, (-1.0+(levelVal)));
|
|
|
|
gInfo->levelPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_BAR_X);
|
|
|
|
gInfo->levelPanel.setBlend(GL_ONE, GL_ONE);
|
|
|
|
|
|
|
|
gInfo->panel.addChild(&gInfo->levelPanel);
|
|
|
|
|
|
|
|
gInfo->highlightPanel.setBorderPx(0);
|
|
|
|
gInfo->highlightPanel.setMarginPx(1);
|
2016-06-01 19:42:34 -04:00
|
|
|
gInfo->highlightPanel.setSize(1.0,0.8f);
|
|
|
|
gInfo->highlightPanel.setPosition(0.0,-0.2f);
|
2015-10-27 01:56:49 -04:00
|
|
|
gInfo->highlightPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_BAR_X);
|
|
|
|
gInfo->highlightPanel.setBlend(GL_ONE, GL_ONE);
|
|
|
|
gInfo->highlightPanel.visible = false;
|
|
|
|
|
|
|
|
gInfo->panel.addChild(&gInfo->highlightPanel);
|
|
|
|
|
|
|
|
gInfo->labelPanel.setSize(spacing/2.0,(15.0/float(ClientSize.y)));
|
|
|
|
gInfo->labelPanel.setPosition(midPos, -barHeight-(20.0/float(ClientSize.y)));
|
2016-06-22 15:21:32 -04:00
|
|
|
|
|
|
|
gInfo->labelPanel.setText(gi->first,GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, true);
|
2015-10-27 01:56:49 -04:00
|
|
|
gInfo->labelPanel.setFill(GLPanel::GLPANEL_FILL_NONE);
|
|
|
|
|
|
|
|
bgPanel.addChild(&(gInfo->labelPanel));
|
|
|
|
|
|
|
|
gInfo->valuePanel.setSize(spacing/2.0,(15.0/float(ClientSize.y)));
|
|
|
|
gInfo->valuePanel.setPosition(midPos, barHeight+(20.0/float(ClientSize.y)));
|
2016-06-22 15:21:32 -04:00
|
|
|
|
|
|
|
gInfo->valuePanel.setText(std::to_string(int(gInfo->current)), GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, true);
|
2015-10-27 01:56:49 -04:00
|
|
|
gInfo->valuePanel.setFill(GLPanel::GLPANEL_FILL_NONE);
|
|
|
|
|
|
|
|
bgPanel.addChild(&(gInfo->valuePanel));
|
|
|
|
|
|
|
|
bgPanel.addChild(&(gInfo->panel));
|
|
|
|
gainInfo.push_back(gInfo);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
setThemeColors();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GainCanvas::setThemeColors() {
|
|
|
|
std::vector<GainInfo *>::iterator gi;
|
|
|
|
|
|
|
|
RGBA4f c1, c2;
|
|
|
|
|
|
|
|
c1 = ThemeMgr::mgr.currentTheme->generalBackground;
|
|
|
|
c2 = ThemeMgr::mgr.currentTheme->generalBackground * 0.5;
|
|
|
|
|
|
|
|
bgPanel.setFillColor(c1, c2);
|
|
|
|
|
|
|
|
for (gi = gainInfo.begin(); gi != gainInfo.end(); gi++) {
|
|
|
|
GainInfo *gInfo = (*gi);
|
|
|
|
|
|
|
|
c1 = ThemeMgr::mgr.currentTheme->generalBackground;
|
|
|
|
c2 = ThemeMgr::mgr.currentTheme->generalBackground * 0.5;
|
|
|
|
c1.a = 1.0;
|
|
|
|
c2.a = 1.0;
|
|
|
|
gInfo->panel.setFillColor(c1, c2);
|
|
|
|
|
|
|
|
c1 = ThemeMgr::mgr.currentTheme->meterLevel * 0.5;
|
|
|
|
c2 = ThemeMgr::mgr.currentTheme->meterLevel;
|
|
|
|
c1.a = 1.0;
|
|
|
|
c2.a = 1.0;
|
|
|
|
gInfo->levelPanel.setFillColor(c1, c2);
|
|
|
|
|
2016-06-01 19:42:34 -04:00
|
|
|
c1 = RGBA4f(0.3f,0.3f,0.3f,1.0f);
|
|
|
|
c2 = RGBA4f(0.65f,0.65f,0.65f,1.0f);;
|
2015-10-27 01:56:49 -04:00
|
|
|
gInfo->highlightPanel.setFillColor(c1, c2);
|
|
|
|
}
|
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|