Implemented basic plugin architecture
Moving interface to WPF for easier integration
This commit is contained in:
parent
19484d8115
commit
dc0e761244
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.CoreAudio.Actions
|
||||||
|
{
|
||||||
|
public class DeviceVolumeAction : IMassiveKnobAction
|
||||||
|
{
|
||||||
|
public Guid ActionId { get; } = new Guid("aabd329c-8be5-4d1e-90ab-5114143b21dd");
|
||||||
|
public MassiveKnobActionType ActionType { get; } = MassiveKnobActionType.InputAnalog;
|
||||||
|
public string Name { get; } = "Set volume";
|
||||||
|
public string Description { get; } = "Sets the volume for the selected device, regardless of the current default device.";
|
||||||
|
|
||||||
|
|
||||||
|
public IMassiveKnobActionInstance Create(IMassiveKnobActionContext context)
|
||||||
|
{
|
||||||
|
return new Instance(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Instance : IMassiveKnobAnalogAction
|
||||||
|
{
|
||||||
|
private readonly Settings settings;
|
||||||
|
|
||||||
|
|
||||||
|
public Instance(IMassiveKnobContext context)
|
||||||
|
{
|
||||||
|
settings = context.GetSettings<Settings>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UserControl CreateSettingsControl()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ValueTask AnalogChanged(byte value)
|
||||||
|
{
|
||||||
|
// TODO set volume
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Settings
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>MassiveKnob.Plugin.CoreAudio</RootNamespace>
|
||||||
|
<AssemblyName>MassiveKnob.Plugin.CoreAudio</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>$(localappdata)\MassiveKnob\Plugins\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xaml" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Actions\DeviceVolumeAction.cs" />
|
||||||
|
<Compile Include="MassiveKnobCoreAudioPlugin.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Settings\DeviceVolumeActionSettings.xaml.cs">
|
||||||
|
<DependentUpon>DeviceVolumeActionSettings.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MassiveKnob.Plugin\MassiveKnob.Plugin.csproj">
|
||||||
|
<Project>{a1298be4-1d23-416c-8c56-fc9264487a95}</Project>
|
||||||
|
<Name>MassiveKnob.Plugin</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Threading.Tasks.Extensions">
|
||||||
|
<Version>4.5.4</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="Settings\DeviceVolumeActionSettings.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MassiveKnob.Plugin.CoreAudio.Actions;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.CoreAudio
|
||||||
|
{
|
||||||
|
[MassiveKnobPlugin]
|
||||||
|
public class MassiveKnobCoreAudioPlugin : IMassiveKnobActionPlugin
|
||||||
|
{
|
||||||
|
public Guid PluginId { get; } = new Guid("eaa5d3f8-8f9b-4a4b-8e29-827228d23e95");
|
||||||
|
public string Name { get; } = "Windows Core Audio";
|
||||||
|
public string Description { get; } = "Included with Massive Knob by default. Provides volume control per device and default device switching.";
|
||||||
|
public string Author { get; } = "Mark van Renswoude <mark@x2software.net>";
|
||||||
|
public string Url { get; } = "https://www.github.com/MvRens/MassiveKnob/";
|
||||||
|
|
||||||
|
public IEnumerable<IMassiveKnobAction> Actions { get; } = new IMassiveKnobAction[]
|
||||||
|
{
|
||||||
|
new DeviceVolumeAction()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("MassiveKnob.Plugin.CoreAudio")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("MassiveKnob.Plugin.CoreAudio")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("5bd5e2f2-9923-4f74-ac69-acda0b847937")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,12 @@
|
|||||||
|
<UserControl x:Class="MassiveKnob.Plugin.CoreAudio.Settings.DeviceVolumeActionSettings"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:MassiveKnob.Plugin.CoreAudio.Settings"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.CoreAudio.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for DeviceVolumeActionSettings.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeviceVolumeActionSettings : UserControl
|
||||||
|
{
|
||||||
|
public DeviceVolumeActionSettings()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
Windows/MassiveKnob.Plugin.MockDevice/Devices/MockDevice.cs
Normal file
45
Windows/MassiveKnob.Plugin.MockDevice/Devices/MockDevice.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using MassiveKnob.Plugin.MockDevice.Settings;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.MockDevice.Devices
|
||||||
|
{
|
||||||
|
public class MockDevice : IMassiveKnobDevice
|
||||||
|
{
|
||||||
|
public Guid DeviceId { get; } = new Guid("e1a4977a-abf4-4c75-a17d-fd8d3a8451ff");
|
||||||
|
public string Name { get; } = "Mock device";
|
||||||
|
public string Description { get; } = "Emulates the actual device but does not communicate with anything.";
|
||||||
|
|
||||||
|
public IMassiveKnobDeviceInstance Create(IMassiveKnobContext context)
|
||||||
|
{
|
||||||
|
return new Instance(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Instance : IMassiveKnobDeviceInstance
|
||||||
|
{
|
||||||
|
public Instance(IMassiveKnobContext context)
|
||||||
|
{
|
||||||
|
// TODO read settings
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UserControl CreateSettingsControl()
|
||||||
|
{
|
||||||
|
// TODO pass context
|
||||||
|
return new MockDeviceSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class Settings
|
||||||
|
{
|
||||||
|
// TODO interval, etc.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>MassiveKnob.Plugin.MockDevice</RootNamespace>
|
||||||
|
<AssemblyName>MassiveKnob.Plugin.MockDevice</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>$(localappdata)\MassiveKnob\Plugins\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xaml" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Devices\MockDevice.cs" />
|
||||||
|
<Compile Include="MassiveKnobMockDevicePlugin.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Settings\MockDeviceSettings.xaml.cs">
|
||||||
|
<DependentUpon>MockDeviceSettings.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MassiveKnob.Plugin\MassiveKnob.Plugin.csproj">
|
||||||
|
<Project>{A1298BE4-1D23-416C-8C56-FC9264487A95}</Project>
|
||||||
|
<Name>MassiveKnob.Plugin</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="Settings\MockDeviceSettings.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.MockDevice
|
||||||
|
{
|
||||||
|
[MassiveKnobPlugin]
|
||||||
|
public class MassiveKnobMockDevicePlugin : IMassiveKnobDevicePlugin
|
||||||
|
{
|
||||||
|
public Guid PluginId { get; } = new Guid("85f04232-d70f-494c-94a2-41452591ffb3");
|
||||||
|
public string Name { get; } = "Mock Device";
|
||||||
|
public string Description { get; } = "Emulates the actual device but does not communicate with anything.";
|
||||||
|
public string Author { get; } = "Mark van Renswoude <mark@x2software.net>";
|
||||||
|
public string Url { get; } = "https://www.github.com/MvRens/MassiveKnob/";
|
||||||
|
|
||||||
|
public IEnumerable<IMassiveKnobDevice> Devices { get; } = new IMassiveKnobDevice[]
|
||||||
|
{
|
||||||
|
new Devices.MockDevice()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("MassiveKnob.Plugin.MockDevice")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("MassiveKnob.Plugin.MockDevice")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("674de974-b134-4db5-bfaf-7bc3d05e16de")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -0,0 +1,24 @@
|
|||||||
|
<UserControl x:Class="MassiveKnob.Plugin.MockDevice.Settings.MockDeviceSettings"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:MassiveKnob.Plugin.MockDevice.Settings"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="0" Grid.Column="0" Margin="4">Number of knobs</TextBlock>
|
||||||
|
<TextBox Grid.Row="0" Grid.Column="1" Margin="4" Width="150" HorizontalAlignment="Left"></TextBox>
|
||||||
|
|
||||||
|
<CheckBox Grid.Row="1" Grid.Column="1" Margin="4">Randomly change the volume</CheckBox>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin.MockDevice.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MockDeviceSettings.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MockDeviceSettings : UserControl
|
||||||
|
{
|
||||||
|
public MockDeviceSettings()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
Windows/MassiveKnob.Plugin/IMassiveKnobAction.cs
Normal file
59
Windows/MassiveKnob.Plugin/IMassiveKnobAction.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the type of control this action can be assigned to.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum MassiveKnobActionType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Can be assigned to a potentiometer. The action instance must implement IMassiveKnobAnalogAction.
|
||||||
|
/// </summary>
|
||||||
|
InputAnalog = 1 << 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be assigned to a button or switch. The action instance must implement IMassiveKnobDigitalAction.
|
||||||
|
/// </summary>
|
||||||
|
InputDigital = 1 << 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Can be assigned to an output, like an LED or relay.
|
||||||
|
/// </summary>
|
||||||
|
OutputSignal = 1 << 2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides information about an action which can be assigned to a knob or button.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobAction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unique identifier for the action.
|
||||||
|
/// </summary>
|
||||||
|
Guid ActionId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the type of control this action can be assigned to.
|
||||||
|
/// </summary>
|
||||||
|
MassiveKnobActionType ActionType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the action as shown in the action list when assigning to a knob or button.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A short description of the functionality provided by the action.
|
||||||
|
/// </summary>
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an action is bound to a knob or button to create an instance of the action.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">Provides an interface to the Massive Knob settings and device. Can be stored until the action instance is disposed.</param>
|
||||||
|
IMassiveKnobActionInstance Create(IMassiveKnobActionContext context);
|
||||||
|
}
|
||||||
|
}
|
12
Windows/MassiveKnob.Plugin/IMassiveKnobActionContext.cs
Normal file
12
Windows/MassiveKnob.Plugin/IMassiveKnobActionContext.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public interface IMassiveKnobActionContext : IMassiveKnobContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the state of the signal. Only valid for OutputSignal action types, will raise an exception otherwise.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="on">Whether the signal is on or off.</param>
|
||||||
|
void SetSignal(bool on);
|
||||||
|
}
|
||||||
|
}
|
18
Windows/MassiveKnob.Plugin/IMassiveKnobActionInstance.cs
Normal file
18
Windows/MassiveKnob.Plugin/IMassiveKnobActionInstance.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base interface for actions assigned to a knob or button. Implement one of the descendant
|
||||||
|
/// interfaces to provide input or output.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobActionInstance : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an action should display it's settings. Assume the width is variable, height is
|
||||||
|
/// determined by the UserControl. Return null to indicate there are no settings for this action.
|
||||||
|
/// </summary>
|
||||||
|
UserControl CreateSettingsControl();
|
||||||
|
}
|
||||||
|
}
|
15
Windows/MassiveKnob.Plugin/IMassiveKnobActionPlugin.cs
Normal file
15
Windows/MassiveKnob.Plugin/IMassiveKnobActionPlugin.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implemented by plugins supporting actions which can be assigned to knobs or buttons.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobActionPlugin : IMassiveKnobPlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A list of actions supported by the plugin which can be assigned to knobs or buttons.
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<IMassiveKnobAction> Actions { get; }
|
||||||
|
}
|
||||||
|
}
|
16
Windows/MassiveKnob.Plugin/IMassiveKnobAnalogAction.cs
Normal file
16
Windows/MassiveKnob.Plugin/IMassiveKnobAnalogAction.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required to be implemented for Action type InputAnalog. Receives an update when a knob's position changes.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobAnalogAction : IMassiveKnobActionInstance
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a knob's position changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The new value. Range is 0 to 100.</param>
|
||||||
|
ValueTask AnalogChanged(byte value);
|
||||||
|
}
|
||||||
|
}
|
22
Windows/MassiveKnob.Plugin/IMassiveKnobContext.cs
Normal file
22
Windows/MassiveKnob.Plugin/IMassiveKnobContext.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides an interface to the Massive Knob settings and device.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the settings for the current action instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The class type to be deserialized using Newtonsoft.Json.</typeparam>
|
||||||
|
/// <returns>The deserialized class if settings were previously stored, or a new instance of the class otherwise.</returns>
|
||||||
|
T GetSettings<T>() where T : class, new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the settings for the current action instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The class type to be serialized using Newtonsoft.Json.</typeparam>
|
||||||
|
/// <param name="settings">The object to be serialized using Newtonsoft.Json.</param>
|
||||||
|
void SetSettings<T>(T settings) where T : class, new();
|
||||||
|
}
|
||||||
|
}
|
31
Windows/MassiveKnob.Plugin/IMassiveKnobDevice.cs
Normal file
31
Windows/MassiveKnob.Plugin/IMassiveKnobDevice.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains information about the device supported by this plugin.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobDevice
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unique identifier for the device.
|
||||||
|
/// </summary>
|
||||||
|
Guid DeviceId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the action as shown in the action list when assigning to a knob or button.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A short description of the functionality provided by the action.
|
||||||
|
/// </summary>
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the device is selected.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">Provides an interface to the Massive Knob settings and device. Can be stored until the device instance is disposed.</param>
|
||||||
|
IMassiveKnobDeviceInstance Create(IMassiveKnobContext context);
|
||||||
|
}
|
||||||
|
}
|
17
Windows/MassiveKnob.Plugin/IMassiveKnobDeviceInstance.cs
Normal file
17
Windows/MassiveKnob.Plugin/IMassiveKnobDeviceInstance.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a connection to a Massive Knob device.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobDeviceInstance : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a device should display it's settings. Assume the width is variable, height is
|
||||||
|
/// determined by the UserControl. Return null to indicate there are no settings for this device.
|
||||||
|
/// </summary>
|
||||||
|
UserControl CreateSettingsControl();
|
||||||
|
}
|
||||||
|
}
|
9
Windows/MassiveKnob.Plugin/IMassiveKnobDigitalAction.cs
Normal file
9
Windows/MassiveKnob.Plugin/IMassiveKnobDigitalAction.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required to be implemented for Action type InputDigital. Receives an update when a knob's position changes.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobDigitalAction : IMassiveKnobActionInstance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
15
Windows/MassiveKnob.Plugin/IMassiveKnobHardwarePlugin.cs
Normal file
15
Windows/MassiveKnob.Plugin/IMassiveKnobHardwarePlugin.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implemented by plugins which interface with Massive Knob device.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobDevicePlugin : IMassiveKnobPlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A list of devices supported by the plugin.
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<IMassiveKnobDevice> Devices { get; }
|
||||||
|
}
|
||||||
|
}
|
36
Windows/MassiveKnob.Plugin/IMassiveKnobPlugin.cs
Normal file
36
Windows/MassiveKnob.Plugin/IMassiveKnobPlugin.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum required interface to implement for writing a Massive Knob plugin.
|
||||||
|
/// Implement one of the various descendant interfaces to provide more functionality.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMassiveKnobPlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unique identifier for the plugin.
|
||||||
|
/// </summary>
|
||||||
|
Guid PluginId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the plugin as shown in the plugin list.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A short description of the functionality provided by the plugin.
|
||||||
|
/// </summary>
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the author(s) of the plugin.
|
||||||
|
/// </summary>
|
||||||
|
string Author { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// URL to the plugin's website.
|
||||||
|
/// </summary>
|
||||||
|
string Url { get; }
|
||||||
|
}
|
||||||
|
}
|
68
Windows/MassiveKnob.Plugin/MassiveKnob.Plugin.csproj
Normal file
68
Windows/MassiveKnob.Plugin/MassiveKnob.Plugin.csproj
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{A1298BE4-1D23-416C-8C56-FC9264487A95}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>MassiveKnob.Plugin</RootNamespace>
|
||||||
|
<AssemblyName>MassiveKnob.Plugin</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Debug\MassiveKnob.Plugin.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>bin\Release\MassiveKnob.Plugin.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="IMassiveKnobActionContext.cs" />
|
||||||
|
<Compile Include="IMassiveKnobActionInstance.cs" />
|
||||||
|
<Compile Include="IMassiveKnobActionPlugin.cs" />
|
||||||
|
<Compile Include="IMassiveKnobDeviceInstance.cs" />
|
||||||
|
<Compile Include="IMassiveKnobDigitalAction.cs" />
|
||||||
|
<Compile Include="IMassiveKnobAnalogAction.cs" />
|
||||||
|
<Compile Include="IMassiveKnobContext.cs" />
|
||||||
|
<Compile Include="IMassiveKnobDevice.cs" />
|
||||||
|
<Compile Include="IMassiveKnobHardwarePlugin.cs" />
|
||||||
|
<Compile Include="MassiveKnobPluginAttribute.cs" />
|
||||||
|
<Compile Include="IMassiveKnobPlugin.cs" />
|
||||||
|
<Compile Include="IMassiveKnobAction.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ReSharper\JetBrains.Annotations.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Threading.Tasks.Extensions">
|
||||||
|
<Version>4.5.4</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
17
Windows/MassiveKnob.Plugin/MassiveKnobPluginAttribute.cs
Normal file
17
Windows/MassiveKnob.Plugin/MassiveKnobPluginAttribute.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
// ReSharper disable once UnusedMember.Global - public API
|
||||||
|
|
||||||
|
namespace MassiveKnob.Plugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attach this attribute to a class to register it as a Massive Knob plugin.
|
||||||
|
/// The class must implement IMassiveKnobPlugin.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
[MeansImplicitUse]
|
||||||
|
public class MassiveKnobPluginAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
36
Windows/MassiveKnob.Plugin/Properties/AssemblyInfo.cs
Normal file
36
Windows/MassiveKnob.Plugin/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("MassiveKnob.PluginHost")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("MassiveKnob.PluginHost")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("a1298be4-1d23-416c-8c56-fc9264487a95")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
180
Windows/MassiveKnob.Plugin/ReSharper/JetBrains.Annotations.cs
Normal file
180
Windows/MassiveKnob.Plugin/ReSharper/JetBrains.Annotations.cs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Stripped version of the ReSharper Annotations source. Enables hinting without referencing the
|
||||||
|
* ReSharper.Annotations NuGet package.
|
||||||
|
*
|
||||||
|
* If you need more annotations, this code was generated using
|
||||||
|
* ReSharper - Options - Code Annotations - Copy C# implementation to clipboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 JetBrains http://www.jetbrains.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE. */
|
||||||
|
|
||||||
|
using System;
|
||||||
|
// ReSharper disable InheritdocConsiderUsage
|
||||||
|
|
||||||
|
#pragma warning disable 1591
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
// ReSharper disable IntroduceOptionalParameters.Global
|
||||||
|
// ReSharper disable MemberCanBeProtected.Global
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
namespace JetBrains.Annotations
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the value of the marked element could be <c>null</c> sometimes,
|
||||||
|
/// so the check for <c>null</c> is necessary before its usage.
|
||||||
|
/// </summary>
|
||||||
|
/// <example><code>
|
||||||
|
/// [CanBeNull] object Test() => null;
|
||||||
|
///
|
||||||
|
/// void UseTest() {
|
||||||
|
/// var p = Test();
|
||||||
|
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
|
||||||
|
/// }
|
||||||
|
/// </code></example>
|
||||||
|
[AttributeUsage(
|
||||||
|
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
|
||||||
|
AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |
|
||||||
|
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]
|
||||||
|
internal sealed class CanBeNullAttribute : Attribute { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the value of the marked element could never be <c>null</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <example><code>
|
||||||
|
/// [NotNull] object Foo() {
|
||||||
|
/// return null; // Warning: Possible 'null' assignment
|
||||||
|
/// }
|
||||||
|
/// </code></example>
|
||||||
|
[AttributeUsage(
|
||||||
|
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
|
||||||
|
AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |
|
||||||
|
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]
|
||||||
|
internal sealed class NotNullAttribute : Attribute { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),
|
||||||
|
/// so this symbol will not be marked as unused (as well as by other usage inspections).
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
|
internal sealed class UsedImplicitlyAttribute : Attribute
|
||||||
|
{
|
||||||
|
public UsedImplicitlyAttribute()
|
||||||
|
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
|
||||||
|
|
||||||
|
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
|
||||||
|
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
|
||||||
|
|
||||||
|
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
|
||||||
|
: this(ImplicitUseKindFlags.Default, targetFlags) { }
|
||||||
|
|
||||||
|
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||||
|
{
|
||||||
|
UseKindFlags = useKindFlags;
|
||||||
|
TargetFlags = targetFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImplicitUseKindFlags UseKindFlags { get; }
|
||||||
|
|
||||||
|
public ImplicitUseTargetFlags TargetFlags { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes
|
||||||
|
/// as unused (as well as by other usage inspections)
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)]
|
||||||
|
internal sealed class MeansImplicitUseAttribute : Attribute
|
||||||
|
{
|
||||||
|
public MeansImplicitUseAttribute()
|
||||||
|
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
|
||||||
|
|
||||||
|
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
|
||||||
|
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
|
||||||
|
|
||||||
|
public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
|
||||||
|
: this(ImplicitUseKindFlags.Default, targetFlags) { }
|
||||||
|
|
||||||
|
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||||
|
{
|
||||||
|
UseKindFlags = useKindFlags;
|
||||||
|
TargetFlags = targetFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; }
|
||||||
|
|
||||||
|
[UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum ImplicitUseKindFlags
|
||||||
|
{
|
||||||
|
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
|
||||||
|
/// <summary>Only entity marked with attribute considered used.</summary>
|
||||||
|
Access = 1,
|
||||||
|
/// <summary>Indicates implicit assignment to a member.</summary>
|
||||||
|
Assign = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates implicit instantiation of a type with fixed constructor signature.
|
||||||
|
/// That means any unused constructor parameters won't be reported as such.
|
||||||
|
/// </summary>
|
||||||
|
InstantiatedWithFixedConstructorSignature = 4,
|
||||||
|
/// <summary>Indicates implicit instantiation of a type.</summary>
|
||||||
|
InstantiatedNoFixedConstructorSignature = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify what is considered used implicitly when marked
|
||||||
|
/// with <see cref="MeansImplicitUseAttribute"/> or <see cref="UsedImplicitlyAttribute"/>.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
internal enum ImplicitUseTargetFlags
|
||||||
|
{
|
||||||
|
Default = Itself,
|
||||||
|
Itself = 1,
|
||||||
|
/// <summary>Members of entity marked with attribute are considered used.</summary>
|
||||||
|
Members = 2,
|
||||||
|
/// <summary>Entity marked with attribute and all its members considered used.</summary>
|
||||||
|
WithMembers = Itself | Members
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This attribute is intended to mark publicly available API
|
||||||
|
/// which should not be removed and so is treated as used.
|
||||||
|
/// </summary>
|
||||||
|
[MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]
|
||||||
|
internal sealed class PublicAPIAttribute : Attribute
|
||||||
|
{
|
||||||
|
public PublicAPIAttribute() { }
|
||||||
|
|
||||||
|
public PublicAPIAttribute([NotNull] string comment)
|
||||||
|
{
|
||||||
|
Comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CanBeNull] public string Comment { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 16
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 16.0.31005.135
|
VisualStudioVersion = 16.0.31005.135
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassiveKnob", "MassiveKnob.csproj", "{73130EC7-49B3-40AD-8367-1095C0F41905}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassiveKnob", "MassiveKnob\MassiveKnob.csproj", "{73130EC7-49B3-40AD-8367-1095C0F41905}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassiveKnob.Plugin", "MassiveKnob.Plugin\MassiveKnob.Plugin.csproj", "{A1298BE4-1D23-416C-8C56-FC9264487A95}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassiveKnob.Plugin.CoreAudio", "MassiveKnob.Plugin.CoreAudio\MassiveKnob.Plugin.CoreAudio.csproj", "{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassiveKnob.Plugin.MockDevice", "MassiveKnob.Plugin.MockDevice\MassiveKnob.Plugin.MockDevice.csproj", "{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -15,6 +21,18 @@ Global
|
|||||||
{73130EC7-49B3-40AD-8367-1095C0F41905}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{73130EC7-49B3-40AD-8367-1095C0F41905}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{73130EC7-49B3-40AD-8367-1095C0F41905}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{73130EC7-49B3-40AD-8367-1095C0F41905}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{73130EC7-49B3-40AD-8367-1095C0F41905}.Release|Any CPU.Build.0 = Release|Any CPU
|
{73130EC7-49B3-40AD-8367-1095C0F41905}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A1298BE4-1D23-416C-8C56-FC9264487A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A1298BE4-1D23-416C-8C56-FC9264487A95}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A1298BE4-1D23-416C-8C56-FC9264487A95}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A1298BE4-1D23-416C-8C56-FC9264487A95}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5BD5E2F2-9923-4F74-AC69-ACDA0B847937}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{674DE974-B134-4DB5-BFAF-7BC3D05E16DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
26
Windows/MassiveKnob/App.xaml
Normal file
26
Windows/MassiveKnob/App.xaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<Application x:Class="MassiveKnob.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:tb="http://www.hardcodet.net/taskbar"
|
||||||
|
ShutdownMode="OnExplicitShutdown">
|
||||||
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="Style.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<ContextMenu x:Shared="false" x:Key="NotifyIconMenu">
|
||||||
|
<MenuItem Header="_Settings" Click="NotifyIconMenuSettingsClick" Style="{StaticResource DefaultMenuItem}" />
|
||||||
|
<MenuItem Header="_Quit" Click="NotifyIconMenuQuitClick" />
|
||||||
|
</ContextMenu>
|
||||||
|
|
||||||
|
<tb:TaskbarIcon
|
||||||
|
x:Key="NotifyIcon"
|
||||||
|
Visibility="Visible"
|
||||||
|
ToolTipText="Massive Knob"
|
||||||
|
IconSource="/Resources/NotifyIcon.ico"
|
||||||
|
ContextMenu="{StaticResource NotifyIconMenu}"
|
||||||
|
TrayMouseDoubleClick="NotifyIconTrayMouseDoubleClick"/>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
75
Windows/MassiveKnob/App.xaml.cs
Normal file
75
Windows/MassiveKnob/App.xaml.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Windows;
|
||||||
|
using Hardcodet.Wpf.TaskbarNotification;
|
||||||
|
using MassiveKnob.View;
|
||||||
|
using SimpleInjector;
|
||||||
|
|
||||||
|
namespace MassiveKnob
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App
|
||||||
|
{
|
||||||
|
private readonly Container container;
|
||||||
|
private TaskbarIcon notifyIcon;
|
||||||
|
|
||||||
|
private SettingsWindow settingsWindow;
|
||||||
|
|
||||||
|
|
||||||
|
public App(Container container)
|
||||||
|
{
|
||||||
|
this.container = container;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnStartup(e);
|
||||||
|
|
||||||
|
notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
|
||||||
|
Debug.Assert(notifyIcon != null, nameof(notifyIcon) + " != null");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnExit(ExitEventArgs e)
|
||||||
|
{
|
||||||
|
notifyIcon?.Dispose();
|
||||||
|
|
||||||
|
base.OnExit(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void ShowSettings()
|
||||||
|
{
|
||||||
|
if (settingsWindow == null)
|
||||||
|
{
|
||||||
|
settingsWindow = container.GetInstance<SettingsWindow>();
|
||||||
|
settingsWindow.Closed += (sender, args) => { settingsWindow = null; };
|
||||||
|
settingsWindow.Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
settingsWindow.Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void NotifyIconMenuSettingsClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ShowSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void NotifyIconTrayMouseDoubleClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ShowSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void NotifyIconMenuQuitClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
Windows/MassiveKnob/Helpers/ComboBoxTemplateSelector.cs
Normal file
54
Windows/MassiveKnob/Helpers/ComboBoxTemplateSelector.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Markup;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Helpers
|
||||||
|
{
|
||||||
|
// Source: https://stackoverflow.com/questions/4672867/can-i-use-a-different-template-for-the-selected-item-in-a-wpf-combobox-than-for
|
||||||
|
public class ComboBoxTemplateSelector : DataTemplateSelector
|
||||||
|
{
|
||||||
|
public DataTemplate SelectedItemTemplate { get; set; }
|
||||||
|
public DataTemplateSelector SelectedItemTemplateSelector { get; set; }
|
||||||
|
public DataTemplate DropdownItemsTemplate { get; set; }
|
||||||
|
public DataTemplateSelector DropdownItemsTemplateSelector { get; set; }
|
||||||
|
|
||||||
|
public override DataTemplate SelectTemplate(object item, DependencyObject container)
|
||||||
|
{
|
||||||
|
var itemToCheck = container;
|
||||||
|
|
||||||
|
// Search up the visual tree, stopping at either a ComboBox or
|
||||||
|
// a ComboBoxItem (or null). This will determine which template to use
|
||||||
|
while (itemToCheck != null && !(itemToCheck is ComboBoxItem) && !(itemToCheck is ComboBox))
|
||||||
|
itemToCheck = VisualTreeHelper.GetParent(itemToCheck);
|
||||||
|
|
||||||
|
// If you stopped at a ComboBoxItem, you're in the dropdown
|
||||||
|
var inDropDown = (itemToCheck is ComboBoxItem);
|
||||||
|
|
||||||
|
return inDropDown
|
||||||
|
? DropdownItemsTemplate ?? DropdownItemsTemplateSelector?.SelectTemplate(item, container)
|
||||||
|
: SelectedItemTemplate ?? SelectedItemTemplateSelector?.SelectTemplate(item, container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ComboBoxTemplateSelectorExtension : MarkupExtension
|
||||||
|
{
|
||||||
|
public DataTemplate SelectedItemTemplate { get; set; }
|
||||||
|
public DataTemplateSelector SelectedItemTemplateSelector { get; set; }
|
||||||
|
public DataTemplate DropdownItemsTemplate { get; set; }
|
||||||
|
public DataTemplateSelector DropdownItemsTemplateSelector { get; set; }
|
||||||
|
|
||||||
|
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
return new ComboBoxTemplateSelector()
|
||||||
|
{
|
||||||
|
SelectedItemTemplate = SelectedItemTemplate,
|
||||||
|
SelectedItemTemplateSelector = SelectedItemTemplateSelector,
|
||||||
|
DropdownItemsTemplate = DropdownItemsTemplate,
|
||||||
|
DropdownItemsTemplateSelector = DropdownItemsTemplateSelector
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
Windows/MassiveKnob/Helpers/DelegateCommand.cs
Normal file
80
Windows/MassiveKnob/Helpers/DelegateCommand.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Helpers
|
||||||
|
{
|
||||||
|
public class DelegateCommand : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action execute;
|
||||||
|
private readonly Func<bool> canExecute;
|
||||||
|
|
||||||
|
|
||||||
|
public DelegateCommand(Action execute) : this(execute, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DelegateCommand(Action execute, Func<bool> canExecute)
|
||||||
|
{
|
||||||
|
this.execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||||
|
this.canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter)
|
||||||
|
{
|
||||||
|
return canExecute?.Invoke() ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Execute(object parameter)
|
||||||
|
{
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged
|
||||||
|
{
|
||||||
|
add => CommandManager.RequerySuggested += value;
|
||||||
|
remove => CommandManager.RequerySuggested -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class DelegateCommand<T> : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action<T> execute;
|
||||||
|
private readonly Predicate<T> canExecute;
|
||||||
|
|
||||||
|
|
||||||
|
public DelegateCommand(Action<T> execute) : this(execute, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
|
||||||
|
{
|
||||||
|
this.execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||||
|
this.canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter)
|
||||||
|
{
|
||||||
|
return canExecute?.Invoke((T)parameter) ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Execute(object parameter)
|
||||||
|
{
|
||||||
|
execute((T)parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged
|
||||||
|
{
|
||||||
|
add => CommandManager.RequerySuggested += value;
|
||||||
|
remove => CommandManager.RequerySuggested -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
@ -10,6 +10,7 @@
|
|||||||
<AssemblyName>MassiveKnob</AssemblyName>
|
<AssemblyName>MassiveKnob</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -41,8 +42,11 @@
|
|||||||
<StartupObject>MassiveKnob.Program</StartupObject>
|
<StartupObject>MassiveKnob.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
@ -50,22 +54,26 @@
|
|||||||
<Reference Include="System.Deployment" />
|
<Reference Include="System.Deployment" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Forms\SettingsForm.cs">
|
|
||||||
<SubType>Form</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Forms\SettingsForm.Designer.cs">
|
|
||||||
<DependentUpon>SettingsForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Hardware\AbstractMassiveKnobHardware.cs" />
|
<Compile Include="Hardware\AbstractMassiveKnobHardware.cs" />
|
||||||
<Compile Include="Hardware\CoreAudioDeviceManager.cs" />
|
<Compile Include="Hardware\CoreAudioDeviceManager.cs" />
|
||||||
<Compile Include="Hardware\IAudioDeviceManager.cs" />
|
<Compile Include="Hardware\IAudioDeviceManager.cs" />
|
||||||
<Compile Include="Hardware\IMassiveKnobHardware.cs" />
|
<Compile Include="Hardware\IMassiveKnobHardware.cs" />
|
||||||
<Compile Include="Hardware\MockMassiveKnobHardware.cs" />
|
<Compile Include="Hardware\MockMassiveKnobHardware.cs" />
|
||||||
<Compile Include="Hardware\SerialMassiveKnobHardware.cs" />
|
<Compile Include="Hardware\SerialMassiveKnobHardware.cs" />
|
||||||
|
<Compile Include="Helpers\ComboBoxTemplateSelector.cs" />
|
||||||
|
<Compile Include="Helpers\DelegateCommand.cs" />
|
||||||
|
<Compile Include="Model\IMassiveKnobOrchestrator.cs" />
|
||||||
|
<Compile Include="Model\IPluginManager.cs" />
|
||||||
|
<Compile Include="Model\MassiveKnobOrchestrator.cs" />
|
||||||
|
<Compile Include="Model\PluginManager.cs" />
|
||||||
|
<Compile Include="ViewModel\SettingsViewModel.cs" />
|
||||||
|
<Compile Include="View\SettingsWindow.xaml.cs">
|
||||||
|
<DependentUpon>SettingsWindow.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Settings\Settings.cs" />
|
<Compile Include="Settings\Settings.cs" />
|
||||||
@ -75,37 +83,10 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Strings.resx</DependentUpon>
|
<DependentUpon>Strings.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="UserControls\KnobDeviceControl.cs">
|
|
||||||
<SubType>UserControl</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="UserControls\KnobDeviceControl.Designer.cs">
|
|
||||||
<DependentUpon>KnobDeviceControl.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<EmbeddedResource Include="Forms\SettingsForm.resx">
|
|
||||||
<DependentUpon>SettingsForm.cs</DependentUpon>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<EmbeddedResource Include="Strings.resx">
|
<EmbeddedResource Include="Strings.resx">
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<None Include="Properties\Settings.settings">
|
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
|
||||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
|
||||||
</None>
|
|
||||||
<Compile Include="Properties\Settings.Designer.cs">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
@ -123,6 +104,9 @@
|
|||||||
<PackageReference Include="Dapplo.Windows.Messages">
|
<PackageReference Include="Dapplo.Windows.Messages">
|
||||||
<Version>0.11.24</Version>
|
<Version>0.11.24</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Hardcodet.NotifyIcon.Wpf">
|
||||||
|
<Version>1.0.8</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="Newtonsoft.Json">
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
<Version>12.0.3</Version>
|
<Version>12.0.3</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@ -135,6 +119,33 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="MainIcon.ico" />
|
<Content Include="MainIcon.ico" />
|
||||||
|
<Resource Include="Resources\NotifyIcon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="App.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Compile Include="App.xaml.cs">
|
||||||
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="Style.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
<Page Include="View\SettingsWindow.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MassiveKnob.Plugin\MassiveKnob.Plugin.csproj">
|
||||||
|
<Project>{A1298BE4-1D23-416C-8C56-FC9264487A95}</Project>
|
||||||
|
<Name>MassiveKnob.Plugin</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
11
Windows/MassiveKnob/Model/IMassiveKnobOrchestrator.cs
Normal file
11
Windows/MassiveKnob/Model/IMassiveKnobOrchestrator.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using MassiveKnob.Plugin;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Model
|
||||||
|
{
|
||||||
|
public interface IMassiveKnobOrchestrator
|
||||||
|
{
|
||||||
|
IMassiveKnobDeviceInstance ActiveDeviceInstance { get; }
|
||||||
|
|
||||||
|
IMassiveKnobDeviceInstance SetActiveDevice(IMassiveKnobDevice device);
|
||||||
|
}
|
||||||
|
}
|
12
Windows/MassiveKnob/Model/IPluginManager.cs
Normal file
12
Windows/MassiveKnob/Model/IPluginManager.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MassiveKnob.Plugin;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Model
|
||||||
|
{
|
||||||
|
public interface IPluginManager
|
||||||
|
{
|
||||||
|
IEnumerable<IMassiveKnobPlugin> Plugins { get; }
|
||||||
|
|
||||||
|
IEnumerable<IMassiveKnobDevicePlugin> GetDevicePlugins();
|
||||||
|
}
|
||||||
|
}
|
52
Windows/MassiveKnob/Model/MassiveKnobOrchestrator.cs
Normal file
52
Windows/MassiveKnob/Model/MassiveKnobOrchestrator.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using MassiveKnob.Plugin;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Model
|
||||||
|
{
|
||||||
|
public class MassiveKnobOrchestrator : IMassiveKnobOrchestrator
|
||||||
|
{
|
||||||
|
private readonly Settings.Settings settings;
|
||||||
|
|
||||||
|
|
||||||
|
public IMassiveKnobDeviceInstance ActiveDeviceInstance { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
public MassiveKnobOrchestrator(Settings.Settings settings)
|
||||||
|
{
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IMassiveKnobDeviceInstance SetActiveDevice(IMassiveKnobDevice device)
|
||||||
|
{
|
||||||
|
ActiveDeviceInstance?.Dispose();
|
||||||
|
ActiveDeviceInstance = device?.Create(new Context(settings));
|
||||||
|
|
||||||
|
return ActiveDeviceInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class Context : IMassiveKnobContext
|
||||||
|
{
|
||||||
|
private readonly Settings.Settings settings;
|
||||||
|
|
||||||
|
|
||||||
|
public Context(Settings.Settings settings)
|
||||||
|
{
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetSettings<T>() where T : class, new()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetSettings<T>(T settings) where T : class, new()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
Windows/MassiveKnob/Model/PluginManager.cs
Normal file
79
Windows/MassiveKnob/Model/PluginManager.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using MassiveKnob.Plugin;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Model
|
||||||
|
{
|
||||||
|
public class PluginManager : IPluginManager
|
||||||
|
{
|
||||||
|
private readonly List<IMassiveKnobPlugin> plugins = new List<IMassiveKnobPlugin>();
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerable<IMassiveKnobPlugin> Plugins => plugins;
|
||||||
|
|
||||||
|
public IEnumerable<IMassiveKnobDevicePlugin> GetDevicePlugins()
|
||||||
|
{
|
||||||
|
return plugins.Where(p => p is IMassiveKnobDevicePlugin).Cast<IMassiveKnobDevicePlugin>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
var codeBase = Assembly.GetEntryAssembly()?.CodeBase;
|
||||||
|
if (!string.IsNullOrEmpty(codeBase))
|
||||||
|
{
|
||||||
|
var localPath = Path.GetDirectoryName(new Uri(codeBase).LocalPath);
|
||||||
|
if (!string.IsNullOrEmpty(localPath))
|
||||||
|
{
|
||||||
|
var applicationPluginPath = Path.Combine(localPath, @"Plugins");
|
||||||
|
LoadPlugins(applicationPluginPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var localPluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"MassiveKnob", @"Plugins");
|
||||||
|
LoadPlugins(localPluginPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void LoadPlugins(string path)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var filenames = Directory.GetFiles(path, "*.dll");
|
||||||
|
|
||||||
|
foreach (var filename in filenames)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var pluginAssembly = Assembly.LoadFrom(filename);
|
||||||
|
RegisterPlugins(pluginAssembly);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// TODO report error
|
||||||
|
// Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void RegisterPlugins(Assembly assembly)
|
||||||
|
{
|
||||||
|
var pluginTypes = assembly.GetTypes().Where(t => t.GetCustomAttribute<MassiveKnobPluginAttribute>() != null);
|
||||||
|
foreach (var pluginType in pluginTypes)
|
||||||
|
{
|
||||||
|
var pluginInstance = Activator.CreateInstance(pluginType);
|
||||||
|
if (!(pluginInstance is IMassiveKnobPlugin))
|
||||||
|
throw new InvalidCastException($"Type {pluginType.FullName} claims to be a MassiveKnobPlugin but does not implement IMassiveKnobPlugin");
|
||||||
|
|
||||||
|
plugins.Add((IMassiveKnobPlugin)pluginInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
Windows/MassiveKnob/Program.cs
Normal file
46
Windows/MassiveKnob/Program.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MassiveKnob.Model;
|
||||||
|
using MassiveKnob.Settings;
|
||||||
|
using MassiveKnob.View;
|
||||||
|
using MassiveKnob.ViewModel;
|
||||||
|
using SimpleInjector;
|
||||||
|
|
||||||
|
namespace MassiveKnob
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
MainAsync().GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static async Task MainAsync()
|
||||||
|
{
|
||||||
|
var container = new Container();
|
||||||
|
container.Options.EnableAutoVerification = false;
|
||||||
|
|
||||||
|
container.RegisterSingleton<IMassiveKnobOrchestrator, MassiveKnobOrchestrator>();
|
||||||
|
|
||||||
|
container.Register<App>();
|
||||||
|
container.Register<SettingsWindow>();
|
||||||
|
container.Register<SettingsViewModel>();
|
||||||
|
|
||||||
|
var settings = await SettingsJsonSerializer.Deserialize();
|
||||||
|
container.RegisterInstance(settings);
|
||||||
|
|
||||||
|
var pluginManager = new PluginManager();
|
||||||
|
pluginManager.Load();
|
||||||
|
container.RegisterInstance<IPluginManager>(pluginManager);
|
||||||
|
|
||||||
|
|
||||||
|
var app = container.GetInstance<App>();
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 165 KiB |
38
Windows/MassiveKnob/Settings/Settings.cs
Normal file
38
Windows/MassiveKnob/Settings/Settings.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace MassiveKnob.Settings
|
||||||
|
{
|
||||||
|
public class Settings
|
||||||
|
{
|
||||||
|
public DeviceSettings Device { get; set; }
|
||||||
|
public List<ActionSettings> Actions { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public static Settings Default()
|
||||||
|
{
|
||||||
|
return new Settings
|
||||||
|
{
|
||||||
|
Device = null,
|
||||||
|
Actions = new List<ActionSettings>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class DeviceSettings
|
||||||
|
{
|
||||||
|
public Guid? PluginId { get; set; }
|
||||||
|
public Guid? DeviceId { get; set; }
|
||||||
|
public JObject Settings { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ActionSettings
|
||||||
|
{
|
||||||
|
public Guid PluginId { get; set; }
|
||||||
|
public Guid ActionId { get; set; }
|
||||||
|
public JObject Settings { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -25,8 +24,7 @@ namespace MassiveKnob.Settings
|
|||||||
|
|
||||||
public static async Task Serialize(Settings settings, string filename)
|
public static async Task Serialize(Settings settings, string filename)
|
||||||
{
|
{
|
||||||
var serializedSettings = SerializedSettings.FromSettings(settings);
|
var json = JsonConvert.SerializeObject(settings);
|
||||||
var json = JsonConvert.SerializeObject(serializedSettings);
|
|
||||||
|
|
||||||
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, true))
|
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, true))
|
||||||
using (var streamWriter = new StreamWriter(stream, Encoding.UTF8))
|
using (var streamWriter = new StreamWriter(stream, Encoding.UTF8))
|
||||||
@ -58,49 +56,7 @@ namespace MassiveKnob.Settings
|
|||||||
if (string.IsNullOrEmpty(json))
|
if (string.IsNullOrEmpty(json))
|
||||||
return Settings.Default();
|
return Settings.Default();
|
||||||
|
|
||||||
var serializedSettings = JsonConvert.DeserializeObject<SerializedSettings>(json);
|
return JsonConvert.DeserializeObject<Settings>(json);
|
||||||
return serializedSettings.ToSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class SerializedSettings
|
|
||||||
{
|
|
||||||
// ReSharper disable MemberCanBePrivate.Local - used for JSON serialization
|
|
||||||
public string SerialPort;
|
|
||||||
public SerializedKnobSettings[] Knobs;
|
|
||||||
// ReSharper restore MemberCanBePrivate.Local
|
|
||||||
|
|
||||||
|
|
||||||
public static SerializedSettings FromSettings(Settings settings)
|
|
||||||
{
|
|
||||||
return new SerializedSettings
|
|
||||||
{
|
|
||||||
SerialPort = settings.SerialPort,
|
|
||||||
Knobs = settings.Knobs.Select(knob => new SerializedKnobSettings
|
|
||||||
{
|
|
||||||
DeviceId = knob.DeviceId
|
|
||||||
}).ToArray()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Settings ToSettings()
|
|
||||||
{
|
|
||||||
return new Settings
|
|
||||||
{
|
|
||||||
SerialPort = SerialPort,
|
|
||||||
Knobs = Knobs.Select(knob => new Settings.KnobSettings
|
|
||||||
{
|
|
||||||
DeviceId = knob.DeviceId
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class SerializedKnobSettings
|
|
||||||
{
|
|
||||||
public Guid? DeviceId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
22
Windows/MassiveKnob/Style.xaml
Normal file
22
Windows/MassiveKnob/Style.xaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style TargetType="MenuItem" x:Key="DefaultMenuItem">
|
||||||
|
<Setter Property="FontWeight" Value="Bold" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="TextBlock" x:Key="Header">
|
||||||
|
<Setter Property="Background" Value="SlateGray" />
|
||||||
|
<Setter Property="Foreground" Value="White" />
|
||||||
|
<Setter Property="FontSize" Value="16" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="Padding" Value="5" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="StackPanel" x:Key="Content">
|
||||||
|
<Setter Property="Margin" Value="8" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="TextBlock" x:Key="ComboBoxDescription">
|
||||||
|
<Setter Property="Foreground" Value="{x:Static SystemColors.GrayTextBrush}" />
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
45
Windows/MassiveKnob/View/SettingsWindow.xaml
Normal file
45
Windows/MassiveKnob/View/SettingsWindow.xaml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<Window x:Class="MassiveKnob.View.SettingsWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:helpers="clr-namespace:MassiveKnob.Helpers"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Massive Knob - Settings" Height="555" Width="704.231"
|
||||||
|
WindowStartupLocation="CenterScreen">
|
||||||
|
<Window.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="../Style.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<DataTemplate x:Key="DeviceDropdownItem">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{Binding Name}" />
|
||||||
|
<TextBlock Text="{Binding Description}" Style="{StaticResource ComboBoxDescription}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
|
||||||
|
<DataTemplate x:Key="DeviceSelectedItem">
|
||||||
|
<TextBlock Text="{Binding Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<ScrollViewer>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Style="{StaticResource Header}">Device</TextBlock>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Vertical" Style="{StaticResource Content}">
|
||||||
|
<ComboBox SelectedItem="{Binding SelectedDevice}" ItemsSource="{Binding Devices}" ItemTemplateSelector="{helpers:ComboBoxTemplateSelector
|
||||||
|
SelectedItemTemplate={StaticResource DeviceSelectedItem},
|
||||||
|
DropdownItemsTemplate={StaticResource DeviceDropdownItem}}" />
|
||||||
|
|
||||||
|
<ContentControl Focusable="False" Content="{Binding SettingsControl}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource Header}">Controls</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Window>
|
16
Windows/MassiveKnob/View/SettingsWindow.xaml.cs
Normal file
16
Windows/MassiveKnob/View/SettingsWindow.xaml.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using MassiveKnob.ViewModel;
|
||||||
|
|
||||||
|
namespace MassiveKnob.View
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for SettingsWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class SettingsWindow
|
||||||
|
{
|
||||||
|
public SettingsWindow(SettingsViewModel settingsViewModel)
|
||||||
|
{
|
||||||
|
DataContext = settingsViewModel;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
Windows/MassiveKnob/ViewModel/SettingsViewModel.cs
Normal file
109
Windows/MassiveKnob/ViewModel/SettingsViewModel.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using MassiveKnob.Model;
|
||||||
|
using MassiveKnob.Plugin;
|
||||||
|
|
||||||
|
namespace MassiveKnob.ViewModel
|
||||||
|
{
|
||||||
|
public class SettingsViewModel : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
private readonly Settings.Settings settings;
|
||||||
|
private readonly IMassiveKnobOrchestrator orchestrator;
|
||||||
|
private DeviceViewModel selectedDevice;
|
||||||
|
private UserControl settingsControl;
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerable<DeviceViewModel> Devices { get; }
|
||||||
|
public DeviceViewModel SelectedDevice
|
||||||
|
{
|
||||||
|
get => selectedDevice;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == selectedDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
|
selectedDevice = value;
|
||||||
|
var deviceInstance = orchestrator.SetActiveDevice(value?.Device);
|
||||||
|
|
||||||
|
if (value == null)
|
||||||
|
settings.Device = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings.Device = new Settings.Settings.DeviceSettings
|
||||||
|
{
|
||||||
|
PluginId = value.Plugin.PluginId,
|
||||||
|
DeviceId = value.Device.DeviceId,
|
||||||
|
Settings = null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
|
||||||
|
SettingsControl = deviceInstance?.CreateSettingsControl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserControl SettingsControl
|
||||||
|
{
|
||||||
|
get => settingsControl;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == settingsControl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
settingsControl = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SettingsViewModel(IPluginManager pluginManager, Settings.Settings settings, IMassiveKnobOrchestrator orchestrator)
|
||||||
|
{
|
||||||
|
this.settings = settings;
|
||||||
|
this.orchestrator = orchestrator;
|
||||||
|
|
||||||
|
Devices = pluginManager.GetDevicePlugins().SelectMany(dp => dp.Devices.Select(d => new DeviceViewModel(dp, d)));
|
||||||
|
|
||||||
|
if (settings.Device != null)
|
||||||
|
SelectedDevice = Devices.FirstOrDefault(d =>
|
||||||
|
d.Plugin.PluginId == settings.Device.PluginId &&
|
||||||
|
d.Device.DeviceId == settings.Device.DeviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class DeviceViewModel
|
||||||
|
{
|
||||||
|
// ReSharper disable UnusedMember.Global - used by WPF Binding
|
||||||
|
public string Name => Device.Name;
|
||||||
|
public string Description => Device.Description;
|
||||||
|
// ReSharper restore UnusedMember.Global
|
||||||
|
|
||||||
|
public IMassiveKnobDevicePlugin Plugin { get; }
|
||||||
|
public IMassiveKnobDevice Device { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public DeviceViewModel(IMassiveKnobDevicePlugin plugin, IMassiveKnobDevice device)
|
||||||
|
{
|
||||||
|
Plugin = plugin;
|
||||||
|
Device = device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using MassiveKnob.Forms;
|
|
||||||
using MassiveKnob.Hardware;
|
|
||||||
using SimpleInjector;
|
|
||||||
using SimpleInjector.Diagnostics;
|
|
||||||
|
|
||||||
namespace MassiveKnob
|
|
||||||
{
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The main entry point for the application.
|
|
||||||
/// </summary>
|
|
||||||
[STAThread]
|
|
||||||
public static void Main()
|
|
||||||
{
|
|
||||||
var container = BuildContainer();
|
|
||||||
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
Application.Run(container.GetInstance<SettingsForm>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Container BuildContainer()
|
|
||||||
{
|
|
||||||
var container = new Container();
|
|
||||||
container.Options.EnableAutoVerification = false;
|
|
||||||
|
|
||||||
container.Register<SettingsForm>();
|
|
||||||
container.GetRegistration(typeof(SettingsForm))?.Registration
|
|
||||||
.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, "Windows Form implements IDisposable");
|
|
||||||
|
|
||||||
container.Register<IAudioDeviceManagerFactory, CoreAudioDeviceManagerFactory>();
|
|
||||||
|
|
||||||
// For testing without the hardware:
|
|
||||||
container.Register<IMassiveKnobHardwareFactory, SerialMassiveKnobHardwareFactory>();
|
|
||||||
//container.Register<IMassiveKnobHardwareFactory>(() => new MockMassiveKnobHardwareFactory(3, TimeSpan.FromSeconds(1), 25));
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
70
Windows/Properties/Resources.Designer.cs
generated
70
Windows/Properties/Resources.Designer.cs
generated
@ -1,70 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Runtime Version:4.0.30319.42000
|
|
||||||
//
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
namespace MassiveKnob.Properties
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
|
||||||
/// </summary>
|
|
||||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
|
||||||
// class via a tool like ResGen or Visual Studio.
|
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
|
||||||
// with the /str option, or rebuild your VS project.
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
|
||||||
internal class Resources
|
|
||||||
{
|
|
||||||
|
|
||||||
private static global::System.Resources.ResourceManager resourceMan;
|
|
||||||
|
|
||||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
|
||||||
|
|
||||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
|
||||||
internal Resources()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the cached ResourceManager instance used by this class.
|
|
||||||
/// </summary>
|
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
|
||||||
internal static global::System.Resources.ResourceManager ResourceManager
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ((resourceMan == null))
|
|
||||||
{
|
|
||||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MassiveKnob.Properties.Resources", typeof(Resources).Assembly);
|
|
||||||
resourceMan = temp;
|
|
||||||
}
|
|
||||||
return resourceMan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Overrides the current thread's CurrentUICulture property for all
|
|
||||||
/// resource lookups using this strongly typed resource class.
|
|
||||||
/// </summary>
|
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
|
||||||
internal static global::System.Globalization.CultureInfo Culture
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return resourceCulture;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
resourceCulture = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
29
Windows/Properties/Settings.Designer.cs
generated
29
Windows/Properties/Settings.Designer.cs
generated
@ -1,29 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Runtime Version:4.0.30319.42000
|
|
||||||
//
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
namespace MassiveKnob.Properties
|
|
||||||
{
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
|
||||||
{
|
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
|
||||||
|
|
||||||
public static Settings Default
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return defaultInstance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
|
||||||
<Profiles>
|
|
||||||
<Profile Name="(Default)" />
|
|
||||||
</Profiles>
|
|
||||||
<Settings />
|
|
||||||
</SettingsFile>
|
|
@ -1,26 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MassiveKnob.Settings
|
|
||||||
{
|
|
||||||
public class Settings
|
|
||||||
{
|
|
||||||
public string SerialPort { get; set; }
|
|
||||||
public List<KnobSettings> Knobs { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
public static Settings Default()
|
|
||||||
{
|
|
||||||
return new Settings
|
|
||||||
{
|
|
||||||
Knobs = new List<KnobSettings>()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class KnobSettings
|
|
||||||
{
|
|
||||||
public Guid? DeviceId { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user