[studio] Add Back/Forward navigation
All checks were successful
Build / build (push) Successful in 1m18s

This commit is contained in:
2025-05-25 22:36:04 -05:00
parent 78e9f70db6
commit 93c84b7186
8 changed files with 167 additions and 50 deletions

View File

@@ -34,18 +34,6 @@ static bool shutdownHandler(turbine::Context &ctx) {
return sctx->ui.handleShutdown();
}
void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs) noexcept {
ox::String path = std::move(filePath);
if (beginsWith(path, "uuid://")) {
auto [p, err] = keel::uuidUrlToPath(keelCtx(ctx), path);
if (err) {
return;
}
path = p;
}
ctx.ui.navigateTo(std::move(path), std::move(navArgs));
}
namespace ig {
extern bool s_mainWinHasFocus;
}
@@ -147,6 +135,9 @@ StudioUI::StudioUI(turbine::Context &tctx, ox::StringParam projectDataDir) noexc
oxLogError(headerizeConfigFile<StudioConfigV1>(kctx));
turbine::setApplicationData(m_tctx, &m_sctx);
turbine::setShutdownHandler(m_tctx, shutdownHandler);
m_sctx.navCallback = [this](ox::StringParam filePath, ox::StringParam navArgs) {
handleNavigationChange(std::move(filePath), std::move(navArgs));
};
m_projectExplorer.fileChosen.connect(this, &StudioUI::openFile);
m_projectExplorer.addDir.connect(this, &StudioUI::addDir);
m_projectExplorer.addItem.connect(this, &StudioUI::addFile);
@@ -186,7 +177,7 @@ void StudioUI::handleKeyEvent(turbine::Key const key, bool const down) noexcept
}
}
void StudioUI::navigateTo(ox::StringParam path, ox::StringParam navArgs) noexcept {
void StudioUI::handleNavigationChange(ox::StringParam path, ox::StringParam navArgs) noexcept {
m_navAction.emplace(std::move(path), std::move(navArgs));
}
@@ -270,7 +261,7 @@ void StudioUI::drawMenu() noexcept {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Edit")) {
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
auto const undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
if (ImGui::MenuItem(
"Undo", STUDIO_CTRL "+Z", false, undoStack && undoStack->canUndo())) {
oxLogError(undoStack->undo());
@@ -310,6 +301,17 @@ void StudioUI::drawMenu() noexcept {
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Navigate")) {
if (ImGui::MenuItem("Back", STUDIO_CTRL "+{", false, m_sctx.navIdx > 1)) {
navigateBack(m_sctx);
}
if (ImGui::MenuItem(
"Forward", STUDIO_CTRL "+}", false,
m_sctx.navIdx < m_sctx.navStack.size())) {
navigateForward(m_sctx);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help")) {
if (ImGui::MenuItem("About")) {
m_aboutPopup.open();
@@ -353,6 +355,13 @@ void StudioUI::drawTabs() noexcept {
}
if (m_activeEditorOnLastDraw != e.get()) [[unlikely]] {
m_activeEditor->onActivated();
if (!m_sctx.navIdx ||
(m_sctx.navIdx <= m_sctx.navStack.size() &&
m_sctx.navStack[m_sctx.navIdx - 1].filePath != m_activeEditor->itemPath())) {
m_sctx.navStack.resize(m_sctx.navIdx);
++m_sctx.navIdx;
m_sctx.navStack.emplace_back(ox::String{m_activeEditor->itemPath()}, ox::String{""});
}
}
if (m_closeActiveTab) [[unlikely]] {
ImGui::SetTabItemClosed(e->itemDisplayName().c_str());
@@ -395,9 +404,14 @@ void StudioUI::drawTabs() noexcept {
m_closeActiveTab = false;
}
if (m_navAction) {
oxLogError(openFile(m_navAction->path));
m_activeEditor->navigateTo(m_navAction->args);
m_navAction.reset();
if (!openFile(m_navAction->path)) {
m_activeEditor->navigateTo(m_navAction->args);
m_navAction.reset();
} else {
//auto const i = m_sctx.navIdx - 1;
//oxDebugf("deleting {}", m_sctx.navStack[i].filePath);
//std::ignore = m_sctx.navStack.erase(i);
}
}
}
@@ -506,6 +520,22 @@ void StudioUI::handleKeyInput() noexcept {
}
}
}
if constexpr (ox::defines::OS == ox::OS::Darwin) {
if (ImGui::IsKeyPressed(ImGuiKey_LeftBracket)) {
navigateBack(m_sctx);
} else if (ImGui::IsKeyPressed(ImGuiKey_RightBracket)) {
navigateForward(m_sctx);
}
}
}
if constexpr (ox::defines::OS != ox::OS::Darwin) {
if (ImGui::IsKeyDown(ImGuiKey_ModAlt)) {
if (ImGui::IsKeyPressed(ImGuiKey_LeftArrow)) {
navigateBack(m_sctx);
} else if (ImGui::IsKeyPressed(ImGuiKey_RightArrow)) {
navigateForward(m_sctx);
}
}
}
}
@@ -664,7 +694,10 @@ ox::Error StudioUI::openFile(ox::StringViewCR path) noexcept {
ox::Error StudioUI::openFileActiveTab(ox::StringViewCR path, bool const makeActiveTab) noexcept {
if (!m_project) {
return ox::Error(1, "No project open to open a file from");
return ox::Error(1, "no project open to open a file from");
}
if (!m_project->romFs().exists(path)) {
return ox::Error{1, "file does note exist"};
}
if (m_openFiles.contains(path)) {
for (auto &e : m_editors) {

View File

@@ -87,7 +87,7 @@ class StudioUI final: public ox::SignalHandler {
void handleKeyEvent(turbine::Key, bool down) noexcept;
void navigateTo(ox::StringParam path, ox::StringParam navArgs) noexcept;
void handleNavigationChange(ox::StringParam path, ox::StringParam navArgs) noexcept;
[[nodiscard]]
constexpr Project *project() noexcept {