[studio] Fix Back/Forward navigation actions

This commit is contained in:
2026-05-31 01:01:32 -05:00
parent 8e52dc64d8
commit 1948a1e701
4 changed files with 42 additions and 28 deletions
+3 -6
View File
@@ -155,13 +155,10 @@ static ox::Error run(
if (m->id() == moduleId) { if (m->id() == moduleId) {
for (auto const &c : m->commands()) { for (auto const &c : m->commands()) {
if (c.name == subCmd) { if (c.name == subCmd) {
auto const kctx = keel::init( OX_REQUIRE(kctx, keel::init(
ox::make_unique<ox::PassThroughFS>(projectDir), ox::make_unique<ox::PassThroughFS>(projectDir),
c.name); c.name).reoriginate(2, "failed to load project directory"));
if (kctx.error) { Project project{*kctx, projectDir, projectDataDir};
return ox::Error{2, "failed to load project directory"};
}
Project project{*kctx.value, projectDir, projectDataDir};
return c.func( return c.func(
project, project,
args.size() > numCmdArgs ? args.size() > numCmdArgs ?
+13 -7
View File
@@ -341,12 +341,14 @@ void StudioUI::drawMenu() noexcept {
if (ImGui::BeginMenu("Navigate")) { if (ImGui::BeginMenu("Navigate")) {
constexpr auto backShortcut = ox::defines::OS == ox::OS::Darwin ? "Cmd+[" : "Alt+Left Arrow"; constexpr auto backShortcut = ox::defines::OS == ox::OS::Darwin ? "Cmd+[" : "Alt+Left Arrow";
constexpr auto fwdShortcut = ox::defines::OS == ox::OS::Darwin ? "Cmd+]" : "Alt+Right Arrow"; constexpr auto fwdShortcut = ox::defines::OS == ox::OS::Darwin ? "Cmd+]" : "Alt+Right Arrow";
if (ImGui::MenuItem("Back", backShortcut, false, m_sctx.navIdx > 1)) { if (ImGui::MenuItem(
"Back", backShortcut, false,
m_sctx.navIdx && *m_sctx.navIdx > 1)) {
navigateBack(m_sctx); navigateBack(m_sctx);
} }
if (ImGui::MenuItem( if (ImGui::MenuItem(
"Forward", fwdShortcut, false, "Forward", fwdShortcut, false,
m_sctx.navIdx < m_sctx.navStack.size())) { m_sctx.navIdx && *m_sctx.navIdx < m_sctx.navStack.size())) {
navigateForward(m_sctx); navigateForward(m_sctx);
} }
ImGui::EndMenu(); ImGui::EndMenu();
@@ -395,11 +397,15 @@ void StudioUI::drawTabs() noexcept {
if (m_activeEditorOnLastDraw != e.get()) [[unlikely]] { if (m_activeEditorOnLastDraw != e.get()) [[unlikely]] {
m_activeEditor->onActivated(); m_activeEditor->onActivated();
if (!m_sctx.navIdx || if (!m_sctx.navIdx ||
(m_sctx.navIdx <= m_sctx.navStack.size() && *m_sctx.navIdx == m_sctx.navStack.size() ||
m_sctx.navStack[m_sctx.navIdx - 1].filePath != m_activeEditor->itemPath())) { (*m_sctx.navIdx < m_sctx.navStack.size() &&
m_sctx.navStack.resize(m_sctx.navIdx); m_sctx.navStack[*m_sctx.navIdx].filePath != m_activeEditor->itemPath())) {
++m_sctx.navIdx; auto &navIdx = m_sctx.navIdx.emplace(m_sctx.navIdx.or_value(0u));
m_sctx.navStack.emplace_back(ox::String{m_activeEditor->itemPath()}, ox::String{""}); m_sctx.navStack.resize(navIdx);
++navIdx;
m_sctx.navStack.emplace_back(
ox::String{m_activeEditor->itemPath()},
ox::String{});
} }
} }
if (m_closeActiveTab) [[unlikely]] { if (m_closeActiveTab) [[unlikely]] {
@@ -28,7 +28,7 @@ struct Context {
ox::String filePath; ox::String filePath;
ox::String navArgs; ox::String navArgs;
}; };
size_t navIdx{}; ox::Optional<size_t> navIdx{};
ox::Vector<NavPath> navStack; ox::Vector<NavPath> navStack;
std::function<void(ox::StringParam filePath, ox::StringParam navArgs)> navCallback; std::function<void(ox::StringParam filePath, ox::StringParam navArgs)> navCallback;
Context(StudioUI &pUi, turbine::Context &pTctx) noexcept: Context(StudioUI &pUi, turbine::Context &pTctx) noexcept:
+24 -13
View File
@@ -20,7 +20,7 @@ void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs)
// !err && np->filePath == path && np->navArgs == navArgs.view()) { // !err && np->filePath == path && np->navArgs == navArgs.view()) {
// return; // return;
//} //}
ctx.navStack.resize(ctx.navIdx + 1); ctx.navStack.resize(ctx.navIdx.or_value(0) + 1);
ctx.navStack.emplace_back(ox::String{path}, ox::String{navArgs.view()}); ctx.navStack.emplace_back(ox::String{path}, ox::String{navArgs.view()});
try { try {
ctx.navCallback(std::move(path), std::move(navArgs)); ctx.navCallback(std::move(path), std::move(navArgs));
@@ -30,31 +30,42 @@ void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs)
} }
} }
static void validateNavStack(Context &ctx, auto &navStack) noexcept {
for (size_t i{}; i < navStack.size(); ++i) {
auto const &n = navStack[i];
if (!ctx.project->exists(n.filePath)) {
std::ignore = navStack.erase(i);
continue;
}
++i;
}
}
void navigateBack(Context &ctx) noexcept { void navigateBack(Context &ctx) noexcept {
if (!ctx.navIdx) { if (!ctx.navIdx) {
return; return;
} }
--ctx.navIdx; validateNavStack(ctx, ctx.navStack);
while (ctx.navIdx < ctx.navStack.size() && ctx.navIdx) { auto &navIdx = *ctx.navIdx;
auto const i = ctx.navIdx - 1; navIdx = ox::min(navIdx, ctx.navStack.size() - 1);
auto const &n = ctx.navStack[i]; if (navIdx) {
if (!ctx.project->exists(n.filePath)) { --navIdx;
std::ignore = ctx.navStack.erase(i); auto const &n = ctx.navStack[navIdx];
--ctx.navIdx;
continue;
}
try { try {
ctx.navCallback(n.filePath, n.navArgs); ctx.navCallback(n.filePath, n.navArgs);
} catch (std::exception const &e) { } catch (std::exception const &e) {
oxAssert(ctx.navCallback != nullptr, "navCallback is null"); oxAssert(ctx.navCallback != nullptr, "navCallback is null");
oxErrf("navigateForward failed: {}", e.what()); oxErrf("navigateForward failed: {}", e.what());
} }
break;
} }
} }
void navigateForward(Context &ctx) noexcept { void navigateForward(Context &ctx) noexcept {
auto const nextIdx = ctx.navIdx + 1; if (!ctx.navIdx) {
ctx.navIdx.emplace(0u);
}
auto &navIdx = *ctx.navIdx;
auto const nextIdx = navIdx + 1;
while (nextIdx < ctx.navStack.size()) { while (nextIdx < ctx.navStack.size()) {
auto const &n = ctx.navStack[nextIdx]; auto const &n = ctx.navStack[nextIdx];
try { try {
@@ -67,7 +78,7 @@ void navigateForward(Context &ctx) noexcept {
std::ignore = ctx.navStack.erase(nextIdx); std::ignore = ctx.navStack.erase(nextIdx);
continue; continue;
} }
++ctx.navIdx; ++navIdx;
break; break;
} }
} }