From 09b2c79ed6320dc6541f1edf435a01b125fe0425 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 26 Aug 2020 19:45:32 -0400 Subject: [PATCH] organized controls; improved connection handling --- gui/stmdsp.cpp | 2 +- gui/wxapp.hpp | 3 ++ gui/wxmain.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++++++++- gui/wxmain.hpp | 128 +++++-------------------------------------- 4 files changed, 159 insertions(+), 117 deletions(-) diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index 73ae880..5fca940 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -16,7 +16,7 @@ namespace stmdsp } device::device(const std::string& file) : - m_serial(file, 230400, serial::Timeout::simpleTimeout(50)) + m_serial(file, 1000000/*230400*/, serial::Timeout::simpleTimeout(50)) { if (m_serial.isOpen()) { m_serial.write("i"); diff --git a/gui/wxapp.hpp b/gui/wxapp.hpp index 6536554..010e3e0 100644 --- a/gui/wxapp.hpp +++ b/gui/wxapp.hpp @@ -4,11 +4,14 @@ #include "wxmain.hpp" #include +#include class MainApp : public wxApp { public: virtual bool OnInit() final { + wxFont::AddPrivateFont("./Hack-Regular.ttf"); + auto mainFrame = new MainFrame; mainFrame->Show(true); SetTopWindow(mainFrame); diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index 847c77a..c2a378a 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -1,13 +1,152 @@ #include "wxmain.hpp" #include +#include + +MainFrame::MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 800)) +{ + + auto window = new wxBoxSizer(wxVERTICAL); + + auto toolbar = new wxBoxSizer(wxHORIZONTAL); + toolbar->Add(new wxButton(this, Id::Single, "Run"), 0, wxALL, 10); + toolbar->Add(new wxButton(this, Id::UploadFilter, "Upload Filter"), 0, wxALL, 10); + toolbar->AddStretchSpacer(2); + toolbar->Add(new wxButton(this, Id::ConnectDevice, "Connect"), 0, wxALL, 10); + window->Add(toolbar, 0, wxALL | wxEXPAND); + + m_text_editor = new wxStyledTextCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(600, 420)); + prepareEditor(); + window->Add(m_text_editor, 1, wxEXPAND | wxALL, 10); + + m_signal_area = new wxControl(this, wxID_ANY, wxDefaultPosition, wxSize(600, 200)); + window->Add(m_signal_area, 1, wxEXPAND | wxALL, 10); + + SetSizerAndFit(window); + + m_render_timer = new wxTimer(this, Id::RenderTimer); + + Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); + Bind(wxEVT_BUTTON, &MainFrame::onUploadPressed, this, Id::UploadFilter); + Bind(wxEVT_BUTTON, &MainFrame::onConnectPressed, this, Id::ConnectDevice); + Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY); + Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer); +} + +void MainFrame::onPaint([[maybe_unused]] wxPaintEvent& pe) +{ + auto *dc = new wxClientDC(this); + auto region = m_signal_area->GetRect(); + dc->SetClippingRegion(region); + + dc->SetBrush(*wxBLACK_BRUSH); + dc->SetPen(*wxBLACK_PEN); + dc->DrawRectangle(region); + + if (m_device_samples.size() > 0) { + dc->SetPen(*wxRED_PEN); + auto points = new wxPoint[m_device_samples.size()]; + const float spacing = static_cast(region.GetWidth()) / m_device_samples.size(); + float x = 0; + for (auto ptr = points; auto sample : m_device_samples) { + *ptr++ = wxPoint { + static_cast(x), + region.GetHeight() - sample * region.GetHeight() / 4096 + }; + x += spacing; + } + dc->DrawLines(m_device_samples.size(), points, region.GetX(), region.GetY()); + delete[] points; + } +} + +void MainFrame::onConnectPressed(wxCommandEvent& ce) +{ + auto button = dynamic_cast(ce.GetEventObject()); + + if (m_device == nullptr) { + stmdsp::scanner scanner; + if (auto devices = scanner.scan(); devices.size() > 0) { + m_device = new stmdsp::device(devices.front()); + if (m_device->connected()) { + button->SetLabel("Disconnect"); + } else { + delete m_device; + m_device = nullptr; + button->SetLabel("Connect"); + } + } + } else { + delete m_device; + m_device = nullptr; + button->SetLabel("Connect"); + } +} + +void MainFrame::doSingle() +{ + m_device_samples_future = std::async(std::launch::async, + [this]() { return m_device->continuous_read(); }); +} + +void MainFrame::onSinglePressed(wxCommandEvent& ce) +{ + auto button = dynamic_cast(ce.GetEventObject()); + + if (!m_render_timer->IsRunning()) { + if (m_device != nullptr && m_device->connected()) { + m_device->continuous_start(); + m_device_samples_future = std::async(std::launch::async, + []() { return decltype(m_device_samples)(); }); + m_render_timer->Start(1000); + button->SetLabel("Stop"); + } + } else { + m_render_timer->Stop(); + m_device->continuous_stop(); + + //m_device_samples.clear(); + //this->RefreshRect(m_signal_area->GetRect()); + + button->SetLabel("Run"); + } +} + +void MainFrame::onUploadPressed([[maybe_unused]] wxCommandEvent& ce) +{ + //wxFileDialog dialog (this, "Select filter to upload", "", "", "*.so", + // wxFD_OPEN | wxFD_FILE_MUST_EXIST); + //if (dialog.ShowModal() != wxID_CANCEL) { + if (auto file = compileEditorCode(); !file.IsEmpty()) { + if (wxFileInputStream file_stream (/*dialog.GetPath()*/file); file_stream.IsOk()) { + auto size = file_stream.GetSize(); + auto buffer = new unsigned char[size]; + if (m_device != nullptr && m_device->connected()) { + file_stream.ReadAll(buffer, size); + m_device->upload_filter(buffer, size); + } + } + } +} + +void MainFrame::onRenderTimer([[maybe_unused]] wxTimerEvent& te) +{ + updateDrawing(); +} + +void MainFrame::updateDrawing() +{ + if (m_device_samples = m_device_samples_future.get(); m_device_samples.size() > 0) + this->RefreshRect(m_signal_area->GetRect()); + + doSingle(); +} void MainFrame::prepareEditor() { m_text_editor->SetLexer(wxSTC_LEX_CPP); m_text_editor->SetMarginWidth(0, 30); m_text_editor->SetMarginType(0, wxSTC_MARGIN_NUMBER); - wxFont::AddPrivateFont("./Hack-Regular.ttf"); m_text_editor->StyleSetFaceName(wxSTC_STYLE_DEFAULT, "Hack"); m_text_editor->StyleClearAll(); m_text_editor->SetTabWidth(4); @@ -34,7 +173,7 @@ void MainFrame::prepareEditor() m_text_editor->SetKeyWords(0, wxT("return for while do break continue if else goto")); m_text_editor->SetKeyWords(1, - wxT("void char short int long float double unsigned signed " + wxT("void char short int long auto float double unsigned signed " "volatile static const constexpr constinit consteval " "virtual final noexcept public private protected")); m_text_editor->SetText("void process_data(adcsample_t *samples, unsigned int size)\n{\n\t\n}\n"); diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index d694734..b0f73a6 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -19,9 +19,8 @@ class MainFrame : public wxFrame { enum Id { - Welcome = 1, - Single, - SelectDevice, + Single = 1, + ConnectDevice, UploadFilter, RenderTimer }; @@ -30,126 +29,27 @@ class MainFrame : public wxFrame wxTimer *m_render_timer = nullptr; wxComboBox *m_device_combo = nullptr; wxStyledTextCtrl *m_text_editor = nullptr; - - const wxRect m_clipping_region = {20, 500, 600, 360}; + wxControl *m_signal_area = nullptr; stmdsp::device *m_device = nullptr; std::future> m_device_samples_future; std::vector m_device_samples; + bool tryDevice(); void prepareEditor(); wxString compileEditorCode(); public: - MainFrame() : wxFrame(nullptr, -1, "Hello world", wxPoint(50, 50), wxSize(640, 880)) - { - new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); - new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); - new wxButton(this, Id::UploadFilter, "Upload Filter", wxPoint(120, 60)); - - m_text_editor = new wxStyledTextCtrl(this, wxID_ANY, wxPoint(20, 100), wxSize(600, 400)); - prepareEditor(); - - m_device_combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30)); - m_device_combo->SetEditable(false); - stmdsp::scanner scanner; - for (auto& dev : scanner.scan()) - m_device_combo->Append(dev); - if (m_device_combo->GetCount() > 0) - m_device_combo->SetSelection(0); - - m_render_timer = new wxTimer(this, Id::RenderTimer); - - Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); - Bind(wxEVT_BUTTON, &MainFrame::onUploadPressed, this, Id::UploadFilter); - Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY); - Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer); - } - - void onPaint([[maybe_unused]] wxPaintEvent& pe) { - auto *dc = new wxClientDC(this); - dc->SetClippingRegion(m_clipping_region); - - dc->SetBrush(*wxBLACK_BRUSH); - dc->SetPen(*wxBLACK_PEN); - dc->DrawRectangle(m_clipping_region); - - if (m_device_samples.size() > 0) { - dc->SetPen(*wxRED_PEN); - auto points = new wxPoint[m_device_samples.size()]; - const float spacing = static_cast(m_clipping_region.GetWidth()) / m_device_samples.size(); - float x = 0; - for (auto ptr = points; auto sample : m_device_samples) { - *ptr++ = wxPoint { - static_cast(x), - m_clipping_region.GetHeight() - sample * m_clipping_region.GetHeight() / 4096 - }; - x += spacing; - } - dc->DrawLines(m_device_samples.size(), points, m_clipping_region.GetX(), m_clipping_region.GetY()); - delete[] points; - } - } - - void doSingle() { - m_device_samples_future = std::async(std::launch::async, - [this]() { return m_device->continuous_read(); }); - } - - void onSinglePressed(wxCommandEvent& ce) { - auto button = dynamic_cast(ce.GetEventObject()); - - if (!m_render_timer->IsRunning()) { - if (m_device == nullptr) - m_device = new stmdsp::device(m_device_combo->GetStringSelection().ToStdString()); - if (m_device->connected()) { - m_device->continuous_start(); - m_device_samples_future = std::async(std::launch::async, - []() { return decltype(m_device_samples)(); }); - m_render_timer->Start(1000); - button->SetLabel("Stop"); - } else { - delete m_device; - m_device = nullptr; - } - } else { - m_render_timer->Stop(); - m_device->continuous_stop(); - button->SetLabel("Single"); - - //delete m_device; - //m_device = nullptr; - } - } - - void onUploadPressed(wxCommandEvent& ce) { - //wxFileDialog dialog (this, "Select filter to upload", "", "", "*.so", - // wxFD_OPEN | wxFD_FILE_MUST_EXIST); - //if (dialog.ShowModal() != wxID_CANCEL) { - if (auto file = compileEditorCode(); !file.IsEmpty()) { - if (wxFileInputStream file_stream (/*dialog.GetPath()*/file); file_stream.IsOk()) { - auto size = file_stream.GetSize(); - auto buffer = new unsigned char[size]; - if (m_device == nullptr) - m_device = new stmdsp::device(m_device_combo->GetStringSelection().ToStdString()); - if (m_device->connected()) { - file_stream.ReadAll(buffer, size); - m_device->upload_filter(buffer, size); - } - } - } - } - - void onRenderTimer([[maybe_unused]] wxTimerEvent& te) { - updateDrawing(); - } - - void updateDrawing() { - if (m_device_samples = m_device_samples_future.get(); m_device_samples.size() > 0) - this->RefreshRect(m_clipping_region); - - doSingle(); - } + MainFrame(); + + void onPaint(wxPaintEvent& pe); + void onSinglePressed(wxCommandEvent& ce); + void onConnectPressed(wxCommandEvent& ce); + void onUploadPressed(wxCommandEvent& ce); + void onRenderTimer(wxTimerEvent& te); + + void doSingle(); + void updateDrawing(); }; #endif // WXMAIN_HPP_