Files
OpenNest/OpenNest/Help/HelpTopics.cs
T
ajandClaude Opus 5.5 be4886f876 fix(ui): remove the F1 hotkey for help
F1 opening help kept taking over from placing a part. Help stays on
the Help menu and F1 belongs to the Clone tool alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 18:25:56 -05:00

82 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Windows.Forms;
namespace OpenNest.Help
{
/// <summary>
/// Opens the bundled help (built from the ajisaacs/opennest-help repository) at a topic.
/// Topic IDs are a stable contract: the help's <c>topics.json</c> maps each ID to a page,
/// so pages can move without app changes. Never rename an ID the app uses.
/// </summary>
public static class HelpTopics
{
public const string Home = "home";
public const string FirstNest = "first-nest";
public const string ImportDrawings = "import-drawings";
public const string AutoNest = "auto-nest";
public const string Post = "post";
public const string SupportGrid = "support-grid";
public const string SheetCutOff = "sheet-cutoff";
public const string TrimExtendCutOff = "trim-extend-cutoff";
/// <summary>Overrides the help folder, e.g. a local opennest-help <c>site/</c> build.</summary>
public const string DirectoryVariable = "OPENNEST_HELP_DIR";
public static string Directory
{
get
{
var overridden = Environment.GetEnvironmentVariable(DirectoryVariable);
return string.IsNullOrWhiteSpace(overridden)
? Path.Combine(Application.StartupPath, "Help")
: overridden;
}
}
public static bool IsInstalled => File.Exists(Path.Combine(Directory, "index.html"));
public static void Show(IWin32Window owner, string topic)
{
if (!IsInstalled)
{
MessageBox.Show(owner,
$"Help is not installed. Expected it in:\n{Directory}",
"OpenNest Help", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
HelpForm.ShowPage(ResolvePage(Directory, topic));
}
/// <summary>Maps a topic ID to a site-relative page, falling back to the home page.</summary>
public static string ResolvePage(string helpDirectory, string topic)
{
var topics = LoadTopics(helpDirectory);
if (topics.TryGetValue(topic, out var page))
return page;
return topics.TryGetValue(Home, out var home) ? home : "index.html";
}
private static Dictionary<string, string> LoadTopics(string helpDirectory)
{
var path = Path.Combine(helpDirectory, "topics.json");
try
{
using var document = JsonDocument.Parse(File.ReadAllText(path));
var topics = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var property in document.RootElement.GetProperty("topics").EnumerateObject())
topics[property.Name] = property.Value.GetString();
return topics;
}
catch (Exception ex) when (ex is IOException or JsonException or KeyNotFoundException
or InvalidOperationException or UnauthorizedAccessException)
{
return new Dictionary<string, string>();
}
}
}
}