Skip to content

Commit

Permalink
Add new project template wizard sample
Browse files Browse the repository at this point in the history
  • Loading branch information
mrward committed Oct 15, 2022
1 parent c2beb6e commit aadfeb2
Show file tree
Hide file tree
Showing 15 changed files with 364 additions and 0 deletions.
25 changes: 25 additions & 0 deletions NewProjectTemplateWizard/NewProjectTemplateWizardSample.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 25.0.1703.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewProjectTemplateWizardSample", "src\NewProjectTemplateWizardSample.csproj", "{07509FEE-6069-491A-927B-8FEFF45CAC51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{07509FEE-6069-491A-927B-8FEFF45CAC51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07509FEE-6069-491A-927B-8FEFF45CAC51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07509FEE-6069-491A-927B-8FEFF45CAC51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07509FEE-6069-491A-927B-8FEFF45CAC51}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {080D064E-D149-41F1-AA67-D00696F67927}
EndGlobalSection
EndGlobal
10 changes: 10 additions & 0 deletions NewProjectTemplateWizard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# New project template wizard sample extension

This sample shows how to have include a custom project template and show
wizard UI in the New Project dialog when creating a new project from this
template.

A new 'Sample Extension' template will be available in the New Project
dialog in the Extensions - Custom - General section. This template will
have a custom wizard UI displayed in the New Project dialog.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Microsoft",
"classifications": [],
"description": "",
"name": "Sample Extension",
"defaultName": "SampleExtensionProjectTemplate",
"identity": "Microsoft.SampleExtensionProjectTemplate.CSharp",
"groupIdentity": "Microsoft.SampleExtensionProjectTemplate",
"tags": {
"language": "C#",
"type": "project",
"vsmac-category": "extensions/custom/general"
},
"shortName": "SampleExtensionProjectTemplate",
"sourceName": "SampleExtensionProjectTemplate",
"guids": [
"{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}"
],
"sources": [
{
"modifiers": [
{
"exclude": [
".vs/**/*"
]
}
]
}
],
"primaryOutputs": [
{
"path": "SampleExtensionProjectTemplate.csproj"
}
]
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Mono.Addins;

[assembly: Addin(
"SampleExtensionProjectTemplate",
Namespace = "Microsoft.VisualStudioMac.Extensibility.Samples",
Version = "0.1",
Category = "IDE extensions")]

[assembly: AddinName("SampleExtensionProjectTemplate")]
[assembly: AddinDescription("SampleExtensionProjectTemplate")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<ExtensionModel>
<Runtime>
<Import assembly="SampleExtensionProjectTemplate.dll" />
</Runtime>

</ExtensionModel>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudioMac.Sdk" Version="17.0.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>Microsoft.SampleExtensionProjectTemplate.CSharp</id>
<version>1.0.0</version>
<title>Microsoft.SampleExtensionProjectTemplate</title>
<authors>Microsoft</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<description>Microsoft.SampleExtensionProjectTemplate.CSharp</description>
<copyright>Microsoft</copyright>
<packageTypes>
<packageType name="Template" />
</packageTypes>
</metadata>
<files>
<file src=".template.config/template.json" target="content/.template.config/" />
<file src="SampleExtensionProjectTemplate.csproj" target="content" />
<file src="Properties/*.*" target="content/Properties/" />
</files>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 25.0.1703.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleExtensionProjectTemplate", "SampleExtensionProjectTemplate.csproj", "{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF3BF5FF-02F0-4C1C-BCC9-DA35CE88FAD7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD7C63E6-BD80-4811-ADEC-4094D5D18699}
EndGlobalSection
EndGlobal
26 changes: 26 additions & 0 deletions NewProjectTemplateWizard/src/NewProjectTemplateWizardSample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudioMac.Sdk" Version="$(VisualStudioMacSdkNuGetVersion)" />
<PackageReference Include="System.Runtime.InteropServices.NFloat.Internal" Version="6.0.1" />
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.macOS">
<HintPath>$(VSBinDir)\Microsoft.macOS.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>

<ItemGroup>
<AddinFile Include="..\SampleExtensionProjectTemplate\Microsoft.SampleExtensionProjectTemplate.CSharp.1.0.0.nupkg">
<Link>templates\Microsoft.SampleExtensionProjectTemplate.CSharp.1.0.0.nupkg</Link>
</AddinFile>
</ItemGroup>
</Project>
17 changes: 17 additions & 0 deletions NewProjectTemplateWizard/src/Properties/AddinInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Runtime.Versioning;
using Mono.Addins;

[assembly: Addin(
"NewProjectTemplateWizardSample",
Namespace = "Microsoft.VisualStudioMac.Extensibility.Samples",
Version = "0.1",
Category = "IDE extensions")]

[assembly: AddinName("NewProjectTemplateWizardSample")]
[assembly: AddinDescription("Extension that has a new project template wizard")]

// Need to fix CA1416 build warning.
// This call site is reachable on all platforms. 'NSLayoutConstraint.Active' is only supported on: 'ios' 10.0 and later,
// 'maccatalyst' 10.0 and later, 'macOS/OSX' 10.14 and later, 'tvos' 10.0 and later. (CA1416))
// https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416
[assembly: SupportedOSPlatform("macos10.14")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<ExtensionModel>
<Runtime>
<Import assembly="NewProjectTemplateWizardSample.dll" />
</Runtime>

<Extension path="/MonoDevelop/Ide/ProjectTemplateCategories">
<Category id="extensions" _name="Extensions" insertafter="other">
<Category id="custom" _name="Custom">
<Category id="general" _name="General" />
</Category>
</Category>
</Extension>

<Extension path= "/MonoDevelop/Ide/Templates">
<Template
_overrideName="Sample Extension"
id="Microsoft.SampleExtensionProjectTemplate.CSharp"
templateId="Microsoft.SampleExtensionProjectTemplate.CSharp"
groupId="Microsoft.SampleExtensionProjectTemplate"
path="templates/Microsoft.SampleExtensionProjectTemplate.CSharp.1.0.0.nupkg"
wizard="NewProjectTemplateWizardSample.SampleProjectTemplateWizard"
category="extensions/custom/general" />
</Extension>

<Extension path="/MonoDevelop/Ide/ProjectTemplateWizards">
<Class
id="NewProjectTemplateWizardSample.SampleProjectTemplateWizard"
class="NewProjectTemplateWizardSample.SampleProjectTemplateWizard" />
</Extension>
</ExtensionModel>
14 changes: 14 additions & 0 deletions NewProjectTemplateWizard/src/SampleProjectTemplateWizard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using MonoDevelop.Ide.Templates;

namespace NewProjectTemplateWizardSample;

class SampleProjectTemplateWizard : TemplateWizard
{
public override string Id => "NewProjectTemplateWizardSample.SampleProjectTemplateWizard";

public override WizardPage GetPage(int pageNumber)
{
return new SampleProjectTemplateWizardPage(this);
}
}

59 changes: 59 additions & 0 deletions NewProjectTemplateWizard/src/SampleProjectTemplateWizardPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

using MonoDevelop.Components;
using MonoDevelop.Core;
using MonoDevelop.Ide.Projects;
using MonoDevelop.Ide.Templates;

namespace NewProjectTemplateWizardSample;

class SampleProjectTemplateWizardPage : WizardPage
{
SampleProjectTemplateWizard wizard;
SampleProjectTemplateWizardPageView? view;
string? projectName;

public SampleProjectTemplateWizardPage(SampleProjectTemplateWizard wizard)
{
this.wizard = wizard;

UpdateCanMoveNext();
}

public override string Title => GettextCatalog.GetString("Configure your Sample Extension");

public string? ProjectName
{
get
{
return projectName;
}
set
{
projectName = value?.Trim();
wizard.Parameters["ProjectName"] = projectName ?? string.Empty;
UpdateCanMoveNext();
}
}

void UpdateCanMoveNext()
{
CanMoveToNextPage = !string.IsNullOrEmpty(projectName);
}

protected override object CreateNativeWidget<T> ()
{
view ??= new SampleProjectTemplateWizardPageView(this);
return view;
}

protected override void Dispose(bool disposing)
{
if (disposing && view != null)
{
view.Dispose();
view = null;
}
base.Dispose(disposing);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

using AppKit;
using MonoDevelop.Core;
using MonoDevelop.Ide.Templates;

namespace NewProjectTemplateWizardSample;

class SampleProjectTemplateWizardPageView : NSView
{
NSTextField projectNameTextField;

public override bool IsFlipped => true;

public SampleProjectTemplateWizardPageView(SampleProjectTemplateWizardPage wizardPage)
{
WizardPage = wizardPage;

TranslatesAutoresizingMaskIntoConstraints = false;

var mainStackView = new NSStackView();
mainStackView.EdgeInsets = new NSEdgeInsets(40, 40, 20, 40);
mainStackView.Orientation = NSUserInterfaceLayoutOrientation.Vertical;
mainStackView.TranslatesAutoresizingMaskIntoConstraints = false;

AddSubview(mainStackView);

var projectNameStackView = new NSStackView();
projectNameStackView.Spacing = 20;
projectNameStackView.Orientation = NSUserInterfaceLayoutOrientation.Horizontal;
projectNameStackView.TranslatesAutoresizingMaskIntoConstraints = false;

mainStackView.AddArrangedSubview(projectNameStackView);

var projectNameLabel = new NSTextField();
projectNameLabel.StringValue = GettextCatalog.GetString("Project Name:");
projectNameLabel.Editable = false;
projectNameLabel.Bordered = false;
projectNameLabel.DrawsBackground = false;
projectNameLabel.Alignment = NSTextAlignment.Right;
projectNameLabel.TranslatesAutoresizingMaskIntoConstraints = false;
projectNameStackView.AddArrangedSubview(projectNameLabel);

projectNameTextField = new NSTextField();
projectNameTextField.TranslatesAutoresizingMaskIntoConstraints = false;
projectNameStackView.AddArrangedSubview(projectNameTextField);

projectNameTextField.WidthAnchor.ConstraintEqualTo(248f).Active = true;

projectNameTextField.Changed += ProjectNameTextField_Changed;
}

void ProjectNameTextField_Changed(object? sender, EventArgs e)
{
WizardPage.ProjectName = projectNameTextField.StringValue;
}

public SampleProjectTemplateWizardPage WizardPage { get; set; }

public override bool BecomeFirstResponder()
{
return projectNameTextField.BecomeFirstResponder();
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
projectNameTextField.Changed -= ProjectNameTextField_Changed;
}
base.Dispose(disposing);
}
}

0 comments on commit aadfeb2

Please sign in to comment.