#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 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) wxEND_EVENT_TABLE() GainCanvas::GainCanvas(wxWindow *parent, int *attribList) : InteractiveCanvas(parent, attribList) { 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; barHeight = 0.8; } 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::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::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::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))); gainInfo[panelHit]->current = gainInfo[panelHit]->low+(hitResult.y * (gainInfo[panelHit]->high-gainInfo[panelHit]->low)); gainInfo[panelHit]->changed = true; gainInfo[panelHit]->valuePanel.setText(std::to_string(int(gainInfo[panelHit]->current))); } } 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::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) { (*gi)->highlightPanel.visible = (i==panelHit); i++; } if (mouseTracker.mouseDown()) { SetLevel(); } } void GainCanvas::OnMouseDown(wxMouseEvent& event) { InteractiveCanvas::OnMouseDown(event); SetLevel(); } void GainCanvas::OnMouseWheelMoved(wxMouseEvent& event) { InteractiveCanvas::OnMouseWheelMoved(event); // Refresh(); } void GainCanvas::OnMouseReleased(wxMouseEvent& event) { InteractiveCanvas::OnMouseReleased(event); // Refresh(); } void GainCanvas::OnMouseLeftWindow(wxMouseEvent& event) { InteractiveCanvas::OnMouseLeftWindow(event); SetCursor(wxCURSOR_CROSS); int i = 0; for (std::vector::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); // Refresh(); } void GainCanvas::setHelpTip(std::string tip) { helpTip = tip; } void GainCanvas::updateGainUI() { const wxSize ClientSize = GetClientSize(); SDRDeviceInfo *devInfo = wxGetApp().getDevice(); std::vector &gains = devInfo->getRxChannel()->getGains(); std::vector::iterator gi; numGains = gains.size(); float i = 0; if (!numGains) { return; } spacing = 2.0/numGains; barWidth = (1.0/numGains)*0.7; startPos = spacing/2.0; barHeight = 0.8; 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; gInfo->name = (*gi).getName(); gInfo->low = (*gi).getLow(); gInfo->high = (*gi).getHigh(); gInfo->current = wxGetApp().getGain(gInfo->name); 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); gInfo->levelPanel.setSize(1.0,0.8); 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); gInfo->highlightPanel.setSize(1.0,0.8); gInfo->highlightPanel.setPosition(0.0,-0.2); 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))); gInfo->labelPanel.setText((*gi).getName()); 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))); gInfo->valuePanel.setText(std::to_string(int(gInfo->current))); 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::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); c1 = RGBA4f(0.3,0.3,0.3,1.0); c2 = RGBA4f(0.65,0.65,0.65,1.0);; gInfo->highlightPanel.setFillColor(c1, c2); } Refresh(); }