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 "core/app/connect.hpp"
|
||||
#include "core/app/edit.hpp"
|
||||
#include "core/app/export.hpp"
|
||||
#include "core/app/load.hpp"
|
||||
@@ -34,6 +35,7 @@ enum {
|
||||
ID_EXPORT,
|
||||
ID_SET_CONNECTOR_TYPE,
|
||||
ID_ATTACH_BSDL,
|
||||
ID_CONNECT,
|
||||
ID_VERIFY,
|
||||
ID_QUIT,
|
||||
ID_ABOUT,
|
||||
@@ -59,6 +61,8 @@ EssimFrame::EssimFrame(WxFrontend &fe)
|
||||
auto *edit = new wxMenu;
|
||||
edit->Append(ID_SET_CONNECTOR_TYPE, "Set &connector type…\tCtrl-T");
|
||||
edit->Append(ID_ATTACH_BSDL, "Attach &BSDL…\tCtrl-B");
|
||||
edit->AppendSeparator();
|
||||
edit->Append(ID_CONNECT, "C&onnect parts…\tCtrl-O");
|
||||
|
||||
auto *sysm = new wxMenu;
|
||||
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::OnSetConnectorType, this, ID_SET_CONNECTOR_TYPE);
|
||||
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::OnQuit, this, ID_QUIT);
|
||||
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();
|
||||
if (!sys || sys->modules()->size() == 0) {
|
||||
wxMessageBox("No modules loaded.", "Select part",
|
||||
wxMessageBox("No modules loaded.", caption,
|
||||
wxOK | wxICON_INFORMATION, this);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -269,12 +274,12 @@ Part *EssimFrame::PickPart() {
|
||||
std::sort(mods.begin(), mods.end());
|
||||
wxArrayString mchoices;
|
||||
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;
|
||||
Module *m = sys->modules()->get(mods[mi]);
|
||||
|
||||
if (m->size() == 0) {
|
||||
wxMessageBox("That module has no parts.", "Select part",
|
||||
wxMessageBox("That module has no parts.", caption,
|
||||
wxOK | wxICON_INFORMATION, this);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -283,7 +288,7 @@ Part *EssimFrame::PickPart() {
|
||||
std::sort(parts.begin(), parts.end());
|
||||
wxArrayString pchoices;
|
||||
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;
|
||||
return m->get(parts[pi]);
|
||||
}
|
||||
@@ -336,6 +341,43 @@ void EssimFrame::OnAttachBsdl(wxCommandEvent &) {
|
||||
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 &) {
|
||||
app::VerifyReport r = app::verify(fe_.system());
|
||||
|
||||
|
||||
@@ -24,13 +24,15 @@ private:
|
||||
void OnExport(wxCommandEvent &);
|
||||
void OnSetConnectorType(wxCommandEvent &);
|
||||
void OnAttachBsdl(wxCommandEvent &);
|
||||
void OnConnect(wxCommandEvent &);
|
||||
void OnVerify(wxCommandEvent &);
|
||||
void OnQuit(wxCommandEvent &);
|
||||
void OnAbout(wxCommandEvent &);
|
||||
|
||||
// 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.
|
||||
class Part *PickPart();
|
||||
// `caption` titles the dialogs (e.g. to distinguish two picks). Returns
|
||||
// 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 Log(const wxString &line); ///< append a line to the log pane
|
||||
|
||||
Reference in New Issue
Block a user