diff --git a/src/slic3r/GUI/Automation/WxUiBackend.cpp b/src/slic3r/GUI/Automation/WxUiBackend.cpp index a8d4e81b55..0a1c85cbeb 100644 --- a/src/slic3r/GUI/Automation/WxUiBackend.cpp +++ b/src/slic3r/GUI/Automation/WxUiBackend.cpp @@ -325,4 +325,17 @@ int WxUiBackend::open_files(const std::vector& paths) { }); } +int WxUiBackend::select_view(const std::string& view) { + return run_on_gui(m_gui_timeout_ms, [&]() -> int { + MainFrame* mainframe = wxGetApp().mainframe; + if (mainframe == nullptr) + throw AutomationError(kErrNotFound, "no main frame to select a view in"); + const int index = mainframe->select_tab_by_name(view); + if (index < 0) + throw AutomationError(kErrNotFound, + std::string("view not available: ") + view); + return index; + }); +} + }}} // namespace Slic3r::GUI::Automation diff --git a/src/slic3r/GUI/Automation/WxUiBackend.hpp b/src/slic3r/GUI/Automation/WxUiBackend.hpp index 39f90af6eb..391a86ef3f 100644 --- a/src/slic3r/GUI/Automation/WxUiBackend.hpp +++ b/src/slic3r/GUI/Automation/WxUiBackend.hpp @@ -20,6 +20,7 @@ public: bool send_keys(const std::vector& chords) override; PngImage screenshot_window(const UiNode* target) override; int open_files(const std::vector& paths) override; + int select_view(const std::string& view) override; private: int m_gui_timeout_ms; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 2d18542bdd..024a215b28 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -3883,6 +3883,30 @@ void MainFrame::select_tab(wxPanel* panel) select_tab(size_t(page_idx)); } +int MainFrame::select_tab_by_name(const std::string& name) +{ + // Prepare/Preview share m_plater and sit at fixed indices (always before any + // conditionally-present tab), so select them by index. Every other view selects + // by its page window via FindPage, which stays correct even when optional tabs + // (e.g. Multi-device) shift the raw indices. + if (name == "prepare") { select_tab(size_t(tp3DEditor)); return m_tabpanel->GetSelection(); } + if (name == "preview") { select_tab(size_t(tpPreview)); return m_tabpanel->GetSelection(); } + + wxWindow* page = nullptr; + if (name == "home") page = m_webview; + else if (name == "device") page = m_monitor; + else if (name == "multi_device") page = m_multi_machine; + else if (name == "project") page = m_project; + else if (name == "calibration") page = m_calibration; + else return -1; // unknown view name + + if (page == nullptr) return -1; // view not available in this layout + const int idx = m_tabpanel->FindPage(page); + if (idx == wxNOT_FOUND) return -1; + select_tab(size_t(idx)); + return m_tabpanel->GetSelection(); +} + //BBS void MainFrame::jump_to_monitor(std::string dev_id) { diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 20229a611e..fca7efbbe4 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -327,6 +327,13 @@ public: //BBS: GUI refactor void select_tab(wxPanel* panel); void select_tab(size_t tab = size_t(-1)); + // Automation: select a top-level tab by stable name ("home", "prepare", + // "preview", "device", "multi_device", "project", "calibration"). Returns the + // resulting notebook page index, or -1 if that view is unavailable in the + // current layout. Robust to conditionally-present tabs (e.g. Multi-device) that + // shift raw indices: Prepare/Preview select by fixed index (they share m_plater + // at 1/2), every other view selects by its page window via FindPage. + int select_tab_by_name(const std::string& name); void request_select_tab(TabPosition pos); int get_calibration_curr_tab(); void select_view(const std::string& direction);