wx: add Connect parts to the Edit menu
Third editing op in the wx GUI. No core change — app::connect_parts was already extracted and unit-tested; this is pure wiring. Edit ▸ Connect parts… picks two parts (PickPart twice, now caption-parameterised to label "first/second part"), derives their parent modules from Part::prnt, calls app::connect_parts and renders the same outcomes the TUI does: refused / identity NC fill / connected (N wires) / failed. wx builds clean, window opens with no asserts; tui + tests unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "frontends/wx/wx_frontend.hpp"
|
#include "frontends/wx/wx_frontend.hpp"
|
||||||
|
|
||||||
|
#include "core/app/connect.hpp"
|
||||||
#include "core/app/edit.hpp"
|
#include "core/app/edit.hpp"
|
||||||
#include "core/app/export.hpp"
|
#include "core/app/export.hpp"
|
||||||
#include "core/app/load.hpp"
|
#include "core/app/load.hpp"
|
||||||
@@ -34,6 +35,7 @@ enum {
|
|||||||
ID_EXPORT,
|
ID_EXPORT,
|
||||||
ID_SET_CONNECTOR_TYPE,
|
ID_SET_CONNECTOR_TYPE,
|
||||||
ID_ATTACH_BSDL,
|
ID_ATTACH_BSDL,
|
||||||
|
ID_CONNECT,
|
||||||
ID_VERIFY,
|
ID_VERIFY,
|
||||||
ID_QUIT,
|
ID_QUIT,
|
||||||
ID_ABOUT,
|
ID_ABOUT,
|
||||||
@@ -59,6 +61,8 @@ EssimFrame::EssimFrame(WxFrontend &fe)
|
|||||||
auto *edit = new wxMenu;
|
auto *edit = new wxMenu;
|
||||||
edit->Append(ID_SET_CONNECTOR_TYPE, "Set &connector type…\tCtrl-T");
|
edit->Append(ID_SET_CONNECTOR_TYPE, "Set &connector type…\tCtrl-T");
|
||||||
edit->Append(ID_ATTACH_BSDL, "Attach &BSDL…\tCtrl-B");
|
edit->Append(ID_ATTACH_BSDL, "Attach &BSDL…\tCtrl-B");
|
||||||
|
edit->AppendSeparator();
|
||||||
|
edit->Append(ID_CONNECT, "C&onnect parts…\tCtrl-O");
|
||||||
|
|
||||||
auto *sysm = new wxMenu;
|
auto *sysm = new wxMenu;
|
||||||
sysm->Append(ID_VERIFY, "&Verify\tCtrl-K");
|
sysm->Append(ID_VERIFY, "&Verify\tCtrl-K");
|
||||||
@@ -103,6 +107,7 @@ EssimFrame::EssimFrame(WxFrontend &fe)
|
|||||||
Bind(wxEVT_MENU, &EssimFrame::OnExport, this, ID_EXPORT);
|
Bind(wxEVT_MENU, &EssimFrame::OnExport, this, ID_EXPORT);
|
||||||
Bind(wxEVT_MENU, &EssimFrame::OnSetConnectorType, this, ID_SET_CONNECTOR_TYPE);
|
Bind(wxEVT_MENU, &EssimFrame::OnSetConnectorType, this, ID_SET_CONNECTOR_TYPE);
|
||||||
Bind(wxEVT_MENU, &EssimFrame::OnAttachBsdl, this, ID_ATTACH_BSDL);
|
Bind(wxEVT_MENU, &EssimFrame::OnAttachBsdl, this, ID_ATTACH_BSDL);
|
||||||
|
Bind(wxEVT_MENU, &EssimFrame::OnConnect, this, ID_CONNECT);
|
||||||
Bind(wxEVT_MENU, &EssimFrame::OnVerify, this, ID_VERIFY);
|
Bind(wxEVT_MENU, &EssimFrame::OnVerify, this, ID_VERIFY);
|
||||||
Bind(wxEVT_MENU, &EssimFrame::OnQuit, this, ID_QUIT);
|
Bind(wxEVT_MENU, &EssimFrame::OnQuit, this, ID_QUIT);
|
||||||
Bind(wxEVT_MENU, &EssimFrame::OnAbout, this, ID_ABOUT);
|
Bind(wxEVT_MENU, &EssimFrame::OnAbout, this, ID_ABOUT);
|
||||||
@@ -256,10 +261,10 @@ void EssimFrame::OnExport(wxCommandEvent &) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Part *EssimFrame::PickPart() {
|
Part *EssimFrame::PickPart(const wxString &caption) {
|
||||||
System *sys = fe_.system();
|
System *sys = fe_.system();
|
||||||
if (!sys || sys->modules()->size() == 0) {
|
if (!sys || sys->modules()->size() == 0) {
|
||||||
wxMessageBox("No modules loaded.", "Select part",
|
wxMessageBox("No modules loaded.", caption,
|
||||||
wxOK | wxICON_INFORMATION, this);
|
wxOK | wxICON_INFORMATION, this);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -269,12 +274,12 @@ Part *EssimFrame::PickPart() {
|
|||||||
std::sort(mods.begin(), mods.end());
|
std::sort(mods.begin(), mods.end());
|
||||||
wxArrayString mchoices;
|
wxArrayString mchoices;
|
||||||
for (const auto &m : mods) mchoices.Add(wx(m));
|
for (const auto &m : mods) mchoices.Add(wx(m));
|
||||||
int mi = wxGetSingleChoiceIndex("Module:", "Select part", mchoices, this);
|
int mi = wxGetSingleChoiceIndex("Module:", caption, mchoices, this);
|
||||||
if (mi < 0) return nullptr;
|
if (mi < 0) return nullptr;
|
||||||
Module *m = sys->modules()->get(mods[mi]);
|
Module *m = sys->modules()->get(mods[mi]);
|
||||||
|
|
||||||
if (m->size() == 0) {
|
if (m->size() == 0) {
|
||||||
wxMessageBox("That module has no parts.", "Select part",
|
wxMessageBox("That module has no parts.", caption,
|
||||||
wxOK | wxICON_INFORMATION, this);
|
wxOK | wxICON_INFORMATION, this);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -283,7 +288,7 @@ Part *EssimFrame::PickPart() {
|
|||||||
std::sort(parts.begin(), parts.end());
|
std::sort(parts.begin(), parts.end());
|
||||||
wxArrayString pchoices;
|
wxArrayString pchoices;
|
||||||
for (const auto &p : parts) pchoices.Add(wx(p));
|
for (const auto &p : parts) pchoices.Add(wx(p));
|
||||||
int pi = wxGetSingleChoiceIndex("Part:", "Select part", pchoices, this);
|
int pi = wxGetSingleChoiceIndex("Part:", caption, pchoices, this);
|
||||||
if (pi < 0) return nullptr;
|
if (pi < 0) return nullptr;
|
||||||
return m->get(parts[pi]);
|
return m->get(parts[pi]);
|
||||||
}
|
}
|
||||||
@@ -336,6 +341,43 @@ void EssimFrame::OnAttachBsdl(wxCommandEvent &) {
|
|||||||
RebuildModelView();
|
RebuildModelView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EssimFrame::OnConnect(wxCommandEvent &) {
|
||||||
|
Part *p1 = PickPart("Connect — first part");
|
||||||
|
if (!p1) return;
|
||||||
|
Part *p2 = PickPart("Connect — second part");
|
||||||
|
if (!p2) return;
|
||||||
|
if (p1 == p2) {
|
||||||
|
wxMessageBox("Pick two different parts.", "Connect",
|
||||||
|
wxOK | wxICON_INFORMATION, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m1/m2 are the parts' parent modules — connect_parts needs them for the
|
||||||
|
// Connection name and ownership.
|
||||||
|
app::ConnectResult r =
|
||||||
|
app::connect_parts(fe_.system(), p1->prnt, p1, p2->prnt, p2);
|
||||||
|
|
||||||
|
if (r.refused) {
|
||||||
|
Log("connect refused: " + wx(r.error));
|
||||||
|
wxMessageBox(wx(r.error), "Connect refused", wxOK | wxICON_ERROR, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!r.identity_info.empty()) {
|
||||||
|
Log("connect: " + wx(r.identity_info));
|
||||||
|
if (r.nc_added > 0)
|
||||||
|
Log(wxString::Format("connect: added %d NC pin(s) so both sides match",
|
||||||
|
r.nc_added));
|
||||||
|
}
|
||||||
|
if (r.ok) {
|
||||||
|
Log(wxString::Format("connected: %s via %s (%d wires)",
|
||||||
|
wx(r.connection_name), wx(r.transform_name), r.wires));
|
||||||
|
} else {
|
||||||
|
Log("connect failed: " + wx(r.error));
|
||||||
|
wxMessageBox(wx(r.error), "Connect failed", wxOK | wxICON_ERROR, this);
|
||||||
|
}
|
||||||
|
RebuildModelView();
|
||||||
|
}
|
||||||
|
|
||||||
void EssimFrame::OnVerify(wxCommandEvent &) {
|
void EssimFrame::OnVerify(wxCommandEvent &) {
|
||||||
app::VerifyReport r = app::verify(fe_.system());
|
app::VerifyReport r = app::verify(fe_.system());
|
||||||
|
|
||||||
|
|||||||
@@ -24,13 +24,15 @@ private:
|
|||||||
void OnExport(wxCommandEvent &);
|
void OnExport(wxCommandEvent &);
|
||||||
void OnSetConnectorType(wxCommandEvent &);
|
void OnSetConnectorType(wxCommandEvent &);
|
||||||
void OnAttachBsdl(wxCommandEvent &);
|
void OnAttachBsdl(wxCommandEvent &);
|
||||||
|
void OnConnect(wxCommandEvent &);
|
||||||
void OnVerify(wxCommandEvent &);
|
void OnVerify(wxCommandEvent &);
|
||||||
void OnQuit(wxCommandEvent &);
|
void OnQuit(wxCommandEvent &);
|
||||||
void OnAbout(wxCommandEvent &);
|
void OnAbout(wxCommandEvent &);
|
||||||
|
|
||||||
// Prompt the user to pick a module then a part from the current System.
|
// Prompt the user to pick a module then a part from the current System.
|
||||||
// Returns nullptr if there is nothing to pick or the user cancels.
|
// `caption` titles the dialogs (e.g. to distinguish two picks). Returns
|
||||||
class Part *PickPart();
|
// nullptr if there is nothing to pick or the user cancels.
|
||||||
|
class Part *PickPart(const wxString &caption = "Select part");
|
||||||
|
|
||||||
void RebuildModelView(); ///< refresh tree + overview from the System
|
void RebuildModelView(); ///< refresh tree + overview from the System
|
||||||
void Log(const wxString &line); ///< append a line to the log pane
|
void Log(const wxString &line); ///< append a line to the log pane
|
||||||
|
|||||||
Reference in New Issue
Block a user