diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index e7352d4..ff51ba0 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -40,6 +40,10 @@ AppFrame::AppFrame() : 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); @@ -94,20 +98,21 @@ AppFrame::AppFrame() : this->SetSizer(vbox); - waterfallCanvas->SetFocusFromKbd(); +// waterfallCanvas->SetFocusFromKbd(); waterfallCanvas->SetFocus(); // SetIcon(wxICON(sample)); // Make a menubar -// wxMenu *menu = new wxMenu; + wxMenuBar *menuBar = new wxMenuBar; + wxMenu *menu = new wxMenu; // menu->Append(wxID_NEW); // menu->AppendSeparator(); -// menu->Append(wxID_CLOSE); -// wxMenuBar *menuBar = new wxMenuBar; -// menuBar->Append(menu, wxT("&File")); + menu->Append(wxID_CLOSE); - wxMenu *menu = new wxMenu; + menuBar->Append(menu, wxT("&File")); + + menu = new wxMenu; std::vector::iterator devices_i; std::map::iterator mdevices_i; @@ -136,17 +141,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(); @@ -172,22 +168,6 @@ void AppFrame::OnMenu(wxCommandEvent& event) { 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; - } - } } void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) { @@ -219,13 +199,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; @@ -280,6 +265,10 @@ void AppFrame::OnIdle(wxIdleEvent& event) { work_done = true; } + if (!waterfallCanvas->HasFocus()) { + waterfallCanvas->SetFocus(); + } + if (!work_done) { event.Skip(); } diff --git a/src/AppFrame.h b/src/AppFrame.h index f20f67f..78f6a83 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -13,10 +13,6 @@ #include #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 a new frame type class AppFrame: public wxFrame { @@ -49,7 +45,5 @@ private: std::map outputDevices; std::map outputDeviceMenuItems; - std::map demodMenuItems; - wxDECLARE_EVENT_TABLE(); }; diff --git a/src/util/MouseTracker.cpp b/src/util/MouseTracker.cpp index 1447121..e9a7dad 100644 --- a/src/util/MouseTracker.cpp +++ b/src/util/MouseTracker.cpp @@ -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; } diff --git a/src/util/MouseTracker.h b/src/util/MouseTracker.h index f577ded..33640ff 100644 --- a/src/util/MouseTracker.h +++ b/src/util/MouseTracker.h @@ -29,6 +29,8 @@ public: void setVertDragLock(bool dragLock); void setHorizDragLock(bool dragLock); + bool getVertDragLock(); + bool getHorizDragLock(); bool mouseDown(); bool mouseRightDown(); bool mouseInView(); diff --git a/src/visual/ModeSelectorCanvas.cpp b/src/visual/ModeSelectorCanvas.cpp index 47c53ac..3696186 100644 --- a/src/visual/ModeSelectorCanvas.cpp +++ b/src/visual/ModeSelectorCanvas.cpp @@ -25,7 +25,7 @@ EVT_ENTER_WINDOW(ModeSelectorCanvas::OnMouseEnterWindow) wxEND_EVENT_TABLE() ModeSelectorCanvas::ModeSelectorCanvas(wxWindow *parent, int *attribList) : - InteractiveCanvas(parent, attribList) { +InteractiveCanvas(parent, attribList), currentSelection(-1), numChoices(0) { glContext = new ModeSelectorContext(this, &wxGetApp().GetContext(this)); } @@ -34,6 +34,17 @@ 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(); @@ -43,10 +54,18 @@ void ModeSelectorCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glContext->DrawBegin(); - glContext->DrawSelector("FM", 1, 4, true, 0.75, 0.75, 0.75, 1.0); - glContext->DrawSelector("AM", 2, 4, true, 0.75, 0.75, 0.75, 1.0); - glContext->DrawSelector("LSB", 3, 4, true, 0.75, 0.75, 0.75, 1.0); - glContext->DrawSelector("USB", 4, 4, true, 0.75, 0.75, 0.75, 1.0); + 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(); @@ -75,19 +94,54 @@ void ModeSelectorCanvas::OnMouseReleased(wxMouseEvent& event) { InteractiveCanvas::OnMouseReleased(event); mouseTracker.setHorizDragLock(false); mouseTracker.setVertDragLock(false); - SetCursor(wxCURSOR_ARROW); + + 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); + SetCursor (wxCURSOR_CROSS); } void ModeSelectorCanvas::OnMouseEnterWindow(wxMouseEvent& event) { InteractiveCanvas::mouseTracker.OnMouseEnterWindow(event); - SetCursor(wxCURSOR_ARROW); + 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; +} + + diff --git a/src/visual/ModeSelectorCanvas.h b/src/visual/ModeSelectorCanvas.h index 7b3cef0..7dcf12b 100644 --- a/src/visual/ModeSelectorCanvas.h +++ b/src/visual/ModeSelectorCanvas.h @@ -13,14 +13,31 @@ #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); @@ -34,6 +51,9 @@ private: ModeSelectorContext *glContext; std::string helpTip; + int numChoices; + int currentSelection; + std::vector selections; // wxDECLARE_EVENT_TABLE(); }; diff --git a/src/visual/ModeSelectorContext.cpp b/src/visual/ModeSelectorContext.cpp index ef4f2e6..7643f57 100644 --- a/src/visual/ModeSelectorContext.cpp +++ b/src/visual/ModeSelectorContext.cpp @@ -37,23 +37,23 @@ void ModeSelectorContext::DrawSelector(std::string label, int c, int cMax, bool glColor4f(r, g, b, a); - float y = 1.0 - ((float) c / (float) cMax * 2.0); + 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(GL_LINE_LOOP); + + 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); - -// glEnable(GL_BLEND); -// glBlendFunc(GL_ONE, GL_ONE); -// glColor4f(r, g, b, a); - } void ModeSelectorContext::DrawEnd() {