mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-25 03:42:05 +00:00
feat(automation): add view.select dispatcher handler + tests
This commit is contained in:
@@ -101,6 +101,13 @@ public:
|
||||
// Throws AutomationError(kErrLoadFailed) when nothing loads. Header stays wx-free:
|
||||
// the concrete LoadStrategy is chosen inside WxUiBackend, not exposed here.
|
||||
virtual int open_files(const std::vector<std::string>& paths) = 0;
|
||||
|
||||
// Select a top-level view/tab by stable name (e.g. "prepare", "preview", "home",
|
||||
// "device", "project", "calibration", "multi_device") on the GUI thread. Returns
|
||||
// the resulting tab index. Throws AutomationError(kErrNotFound) when the named
|
||||
// view is unknown or not available in the current layout. The wx-specific
|
||||
// name->tab mapping lives in WxUiBackend/MainFrame, not here.
|
||||
virtual int select_view(const std::string& view) = 0;
|
||||
};
|
||||
|
||||
}}} // namespace Slic3r::GUI::Automation
|
||||
|
||||
@@ -154,6 +154,21 @@ std::vector<std::string> parse_paths(const nlohmann::json& params) {
|
||||
throw AutomationError(kInvalidParams, "'paths' is empty");
|
||||
return out;
|
||||
}
|
||||
|
||||
// "view" must be a non-empty string naming a top-level tab. The name->tab mapping
|
||||
// itself lives in the wx backend, so this only validates shape; throws kInvalidParams
|
||||
// when view is missing, not a string, or empty.
|
||||
std::string parse_view(const nlohmann::json& params) {
|
||||
if (!params.is_object() || !params.contains("view"))
|
||||
throw AutomationError(kInvalidParams, "view.select requires 'view'");
|
||||
const auto& v = params.at("view");
|
||||
if (!v.is_string())
|
||||
throw AutomationError(kInvalidParams, "'view' must be a string");
|
||||
std::string name = v.get<std::string>();
|
||||
if (name.empty())
|
||||
throw AutomationError(kInvalidParams, "'view' is empty");
|
||||
return name;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
@@ -196,7 +211,7 @@ nlohmann::json JsonRpcDispatcher::m_version(const nlohmann::json&) {
|
||||
{"capabilities", nlohmann::json::array({
|
||||
"tree.dump","tree.find","widget.get","input.click","input.type",
|
||||
"input.key","sync.wait_for","app.state","screenshot.window",
|
||||
"file.open" })} };
|
||||
"file.open","view.select" })} };
|
||||
}
|
||||
|
||||
nlohmann::json JsonRpcDispatcher::dispatch(const nlohmann::json& request) {
|
||||
@@ -222,6 +237,7 @@ nlohmann::json JsonRpcDispatcher::dispatch(const nlohmann::json& request) {
|
||||
if (method == "app.state") return make_result(id, m_app_state(params));
|
||||
if (method == "screenshot.window") return make_result(id, m_screenshot_window(params));
|
||||
if (method == "file.open") return make_result(id, m_file_open(params));
|
||||
if (method == "view.select") return make_result(id, m_view_select(params));
|
||||
return make_error(id, kMethodNotFound, "unknown method: " + method);
|
||||
} catch (const AutomationError& e) {
|
||||
return make_error(id, e.code, e.what());
|
||||
@@ -377,4 +393,10 @@ nlohmann::json JsonRpcDispatcher::m_file_open(const nlohmann::json& params) {
|
||||
return { {"ok", true}, {"loaded", loaded} };
|
||||
}
|
||||
|
||||
nlohmann::json JsonRpcDispatcher::m_view_select(const nlohmann::json& params) {
|
||||
const std::string view = parse_view(params);
|
||||
const int index = m_backend.select_view(view);
|
||||
return { {"ok", true}, {"view", view}, {"index", index} };
|
||||
}
|
||||
|
||||
}}} // namespace
|
||||
|
||||
@@ -49,6 +49,7 @@ private:
|
||||
nlohmann::json m_app_state(const nlohmann::json& params);
|
||||
nlohmann::json m_screenshot_window(const nlohmann::json& params);
|
||||
nlohmann::json m_file_open(const nlohmann::json& params);
|
||||
nlohmann::json m_view_select(const nlohmann::json& params);
|
||||
|
||||
// Resolve a unique, actionable (enabled+visible) node from params["target"].
|
||||
// Throws kErrNotFound (missing/ambiguous) or kErrNotActionable (disabled/hidden).
|
||||
|
||||
Reference in New Issue
Block a user