diff --git a/.github/workflows/build-component.yml b/.github/workflows/build-component.yml index d347d1ef..c1e7e871 100644 --- a/.github/workflows/build-component.yml +++ b/.github/workflows/build-component.yml @@ -67,6 +67,7 @@ jobs: cp ./PYTHON_PACKAGE_LICENSES ./Release/PYTHON_PACKAGE_LICENSES.txt cp ./Tunny/bin/Debug/net48 ./Release/Tunny -recurse cp ./TT-DesignExplorer/server/bin/Debug/net48/TT-DesignExplorer.zip ./Release/Tunny/Lib/TT-DesignExplorer.zip + cp ./Examples ./Release/Tunny/Examples -recurse - name: Upload release build of plugin as artefact uses: actions/upload-artifact@v4 @@ -74,5 +75,5 @@ jobs: name: Tunny path: | ./Release - retention-days: 7 + retention-days: 1 compression-level: 9 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5bcf6c5e..8d72c8cb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "dotnet.defaultSolution": "Tunny.sln", "cSpell.words": [ + "HITL", "hovertemplate", "showlegend", "yaxis", diff --git a/CHANGELOG.md b/CHANGELOG.md index d9f68baa..d95647af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Please see [here](https://github.com/hrntsm/Tunny/releases) for the data release ### Added -for new features. +- Feature to open tutorial files in the menu. ### Changed diff --git a/Examples/Grasshopper/categorical_optimization.gh b/Examples/Grasshopper/Optimization/categorical_optimization.gh similarity index 100% rename from Examples/Grasshopper/categorical_optimization.gh rename to Examples/Grasshopper/Optimization/categorical_optimization.gh diff --git a/Examples/Grasshopper/optimization_with_constraint.gh b/Examples/Grasshopper/Optimization/optimization_with_constraint.gh similarity index 100% rename from Examples/Grasshopper/optimization_with_constraint.gh rename to Examples/Grasshopper/Optimization/optimization_with_constraint.gh diff --git a/Examples/Grasshopper/optimization_with_initial_values.gh b/Examples/Grasshopper/Optimization/optimization_with_initial_values.gh similarity index 100% rename from Examples/Grasshopper/optimization_with_initial_values.gh rename to Examples/Grasshopper/Optimization/optimization_with_initial_values.gh diff --git a/Examples/Grasshopper/optimization_without_ui.gh b/Examples/Grasshopper/Optimization/optimization_without_ui.gh similarity index 100% rename from Examples/Grasshopper/optimization_without_ui.gh rename to Examples/Grasshopper/Optimization/optimization_without_ui.gh diff --git a/Examples/Grasshopper/result_handling_example.gh b/Examples/Grasshopper/Optimization/result_handling_example.gh similarity index 100% rename from Examples/Grasshopper/result_handling_example.gh rename to Examples/Grasshopper/Optimization/result_handling_example.gh diff --git a/Examples/Grasshopper/save_artifact_to_trial.gh b/Examples/Grasshopper/Optimization/save_artifact_to_trial.gh similarity index 100% rename from Examples/Grasshopper/save_artifact_to_trial.gh rename to Examples/Grasshopper/Optimization/save_artifact_to_trial.gh diff --git a/Tunny.Core/Util/TEnvVariables.cs b/Tunny.Core/Util/TEnvVariables.cs index 9f807594..c112cfbc 100644 --- a/Tunny.Core/Util/TEnvVariables.cs +++ b/Tunny.Core/Util/TEnvVariables.cs @@ -7,13 +7,14 @@ namespace Tunny.Core.Util public static class TEnvVariables { public static Version Version { get; } = Assembly.GetExecutingAssembly().GetName().Version; + public static string DefaultStoragePath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "fish.log"); public static string TunnyEnvPath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".tunny_env"); public static string LogPath { get; } = Path.Combine(TunnyEnvPath, "logs"); public static string DesignExplorerPath { get; } = Path.Combine(TunnyEnvPath, "TT-DesignExplorer"); public static string OptimizeSettingsPath { get; } = Path.Combine(TunnyEnvPath, "settings.json"); - public static string DefaultStoragePath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "fish.log"); public static string PythonPath { get; } = Path.Combine(TunnyEnvPath, "python"); public static string ComponentFolder { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + public static string ExampleDirPath { get; } = Path.Combine(ComponentFolder, "Examples", "Grasshopper"); public static Version OldStorageVersion { get; } = new Version("0.9.1"); public static IntPtr GrasshopperWindowHandle { get; set; } diff --git a/Tunny/UI/LoadingInstruction.cs b/Tunny/UI/LoadingInstruction.cs index 50c1cec5..a6e84586 100644 --- a/Tunny/UI/LoadingInstruction.cs +++ b/Tunny/UI/LoadingInstruction.cs @@ -16,9 +16,12 @@ namespace Tunny.UI { public class LoadingInstruction : GH_AssemblyPriority, IDisposable { + private ToolStripMenuItem _tutorialStripMenuItem; private ToolStripMenuItem _tunnyHelpStripMenuItem; private ToolStripMenuItem _optunaDashboardToolStripMenuItem; private ToolStripMenuItem _pythonInstallStripMenuItem; + private ToolStripMenuItem _ttDesignExplorerToolStripMenuItem; + private ToolStripMenuItem _aboutTunnyStripMenuItem; public override GH_LoadingInstruction PriorityLoad() { @@ -72,20 +75,64 @@ void GH_DocumentEditor_AggregateShortcutMenuItems(object sender, GH_MenuShortcut private void AddTunnyMenuItems(ToolStripItemCollection dropDownItems) { TLog.MethodStart(); - _tunnyHelpStripMenuItem = new ToolStripMenuItem("Help", null, TunnyHelpStripMenuItem_Click, "TunnyHelpStripMenuItem"); - _optunaDashboardToolStripMenuItem = new ToolStripMenuItem("Run optuna-dashboard...", Resource.optuna_dashboard, OptunaDashboardToolStripMenuItem_Click, "OptunaDashboardToolStripMenuItem"); + _tunnyHelpStripMenuItem = new ToolStripMenuItem("Help", null, null, "TunnyHelpStripMenuItem"); + _tutorialStripMenuItem = new ToolStripMenuItem("Tutorial Files", null, null, "TutorialStripMenuItem"); + _optunaDashboardToolStripMenuItem = new ToolStripMenuItem("Run Optuna Dashboard...", Resource.optuna_dashboard, OptunaDashboardToolStripMenuItem_Click, "OptunaDashboardToolStripMenuItem"); _pythonInstallStripMenuItem = new ToolStripMenuItem("Install Python...", null, PythonInstallStripMenuItem_Click, "PythonInstallStripMenuItem"); - var ttDesignExplorerToolStripMenuItem = new ToolStripMenuItem("Run TT DesignExplorer...", Resource.TTDesignExplorer, TTDesignExplorerToolStripMenuItem_Click, "TTDesignExplorerToolStripMenuItem"); - var aboutTunnyStripMenuItem = new ToolStripMenuItem("About...", Resource.TunnyIcon, AboutTunnyStripMenuItem_Click, "AboutTunnyStripMenuItem"); + _ttDesignExplorerToolStripMenuItem = new ToolStripMenuItem("Run TT DesignExplorer...", Resource.TTDesignExplorer, TTDesignExplorerToolStripMenuItem_Click, "TTDesignExplorerToolStripMenuItem"); + _aboutTunnyStripMenuItem = new ToolStripMenuItem("About...", Resource.TunnyIcon, AboutTunnyStripMenuItem_Click, "AboutTunnyStripMenuItem"); + + SetHelpDropDownItems(); + SetTutorialDropDownItems(); dropDownItems.AddRange(new ToolStripItem[] { _tunnyHelpStripMenuItem, + _tutorialStripMenuItem, + new ToolStripSeparator(), _optunaDashboardToolStripMenuItem, - ttDesignExplorerToolStripMenuItem, + _ttDesignExplorerToolStripMenuItem, new ToolStripSeparator(), _pythonInstallStripMenuItem, new ToolStripSeparator(), - aboutTunnyStripMenuItem + _aboutTunnyStripMenuItem + }); + } + + private void SetTutorialDropDownItems() + { + TLog.MethodStart(); + var optExample = new ToolStripMenuItem("Optimization", null, null, "TutorialOptimizationStripMenuItem"); + var hitlExample = new ToolStripMenuItem("Human-in-the-loop", null, null, "TutorialHITLStripMenuItem"); + string[] optFiles = Directory.GetFiles(Path.Combine(TEnvVariables.ExampleDirPath, "Optimization"), "*.gh"); + string[] hitlFiles = Directory.GetFiles(Path.Combine(TEnvVariables.ExampleDirPath, "Human-in-the-loop"), "*.gh"); + + SetMenuItemsFromFilePath(optExample, optFiles); + SetMenuItemsFromFilePath(hitlExample, hitlFiles); + + _tutorialStripMenuItem.DropDownItems.AddRange(new[] { optExample, hitlExample }); + } + + private static void SetMenuItemsFromFilePath(ToolStripMenuItem menuItem, string[] filePaths) + { + TLog.MethodStart(); + for (int i = 0; i < filePaths.Length; i++) + { + string file = filePaths[i]; + string fileName = Path.GetFileNameWithoutExtension(file); + var optItem = new ToolStripMenuItem("0" + i + " " + fileName, null, (sender, e) => + { + Grasshopper.Instances.DocumentServer.AddDocument(file, makeActive: true); + }, fileName); + menuItem.DropDownItems.Add(optItem); + } + } + + private void SetHelpDropDownItems() + { + TLog.MethodStart(); + _tunnyHelpStripMenuItem.DropDownItems.AddRange(new[]{ + new ToolStripMenuItem("Tunny Document", null, TunnyDocumentPageStripMenuItem_Click, "TunnyDocumentStripMenuItem"), + new ToolStripMenuItem("Optuna Sampler Document", null, OptunaSamplerPageStripMenuItem_Click, "OptunaTutorialStripMenuItem") }); } @@ -125,16 +172,26 @@ private void PythonInstallStripMenuItem_Click(object sender, EventArgs e) settings.Serialize(TEnvVariables.OptimizeSettingsPath); } - private void TunnyHelpStripMenuItem_Click(object sender, EventArgs e) + private void TunnyDocumentPageStripMenuItem_Click(object sender, EventArgs e) { TLog.MethodStart(); - TLog.Debug("TunnyHelpStripMenuItem Clicked"); + TLog.Debug("TunnyDocumentPageStripMenuItem Clicked"); var browser = new Process(); browser.StartInfo.FileName = $@"https://tunny-docs.deno.dev/"; browser.StartInfo.UseShellExecute = true; browser.Start(); } + private void OptunaSamplerPageStripMenuItem_Click(object sender, EventArgs e) + { + TLog.MethodStart(); + TLog.Debug("OptunaSamplerPageStripMenuItem Clicked"); + var browser = new Process(); + browser.StartInfo.FileName = $@"https://optuna.readthedocs.io/en/stable/reference/samplers/index.html"; + browser.StartInfo.UseShellExecute = true; + browser.Start(); + } + private void OptunaDashboardToolStripMenuItem_Click(object sender, EventArgs e) { TLog.MethodStart(); @@ -211,8 +268,11 @@ public void Dispose() { TLog.MethodStart(); _tunnyHelpStripMenuItem.Dispose(); + _tutorialStripMenuItem.Dispose(); _optunaDashboardToolStripMenuItem.Dispose(); _pythonInstallStripMenuItem.Dispose(); + _ttDesignExplorerToolStripMenuItem.Dispose(); + _aboutTunnyStripMenuItem.Dispose(); GC.SuppressFinalize(this); } }