mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Layer refactor (#118)
* Expanded Trace logging for Overwatch and RL, updated The Witcher 3 mod for 1.22 * Events WIP * Moved some views around, added event views * Implemented events * Some improvements to Overwatch parsing.. some. * Improved Overwatch parsing to work well with events * Fixed ultimate ready false positive during ultimate usage * Added debug window which currently shows Razer SDK keyboard output * Expanded Overwatch data model (todo: sticky values to avoid false-positives) * Added sticky values to Overwatch datamodel, should resolve most flickering/false positives * Layer refactor WIP * Moved layer types, animations, conditions and events to interfaces. (WIP) * Code cleanup, moved all profile related models to their own folder/namespace * Finished most of the profile refactoring * More profile refactoring, app compiles again * Switched from XML to JSON for profiles (refactor broke existing profiles anyway) * Made animation event expiration generic and fixed all serialization issues I've come across so far * Cleaned up settings, rigged basic LayerEditorView(Model) to refactored models * Rigged most layer type viewmodels back up to the new models * Fixed most view(models). Added animations to mice and headset. Replaced serialization-based cloning with NClone Fixed some rendering issues that came up with refactoring * Added Current Time to WindowsProfile * Cloning fixes Replaced glitchy cloning package with a simple serialization clone (that package looked so good :c) Removed serialization cloning from render process * Expanded Trace logging for Overwatch and RL, updated The Witcher 3 mod for 1.22 * Events WIP * Moved some views around, added event views * Implemented events * Some improvements to Overwatch parsing.. some. * Improved Overwatch parsing to work well with events * Fixed ultimate ready false positive during ultimate usage * Added debug window which currently shows Razer SDK keyboard output * Expanded Overwatch data model (todo: sticky values to avoid false-positives) * Added sticky values to Overwatch datamodel, should resolve most flickering/false positives * Layer refactor WIP * Moved layer types, animations, conditions and events to interfaces. (WIP) * Code cleanup, moved all profile related models to their own folder/namespace * Finished most of the profile refactoring * More profile refactoring, app compiles again * Switched from XML to JSON for profiles (refactor broke existing profiles anyway) * Made animation event expiration generic and fixed all serialization issues I've come across so far * Cleaned up settings, rigged basic LayerEditorView(Model) to refactored models * Rigged most layer type viewmodels back up to the new models * Fixed most view(models). Added animations to mice and headset. Replaced serialization-based cloning with NClone Fixed some rendering issues that came up with refactoring * Added Current Time to WindowsProfile * Cloning fixes Replaced glitchy cloning package with a simple serialization clone (that package looked so good :c) Removed serialization cloning from render process
This commit is contained in:
parent
13122f8df7
commit
8d9272f47c
@ -52,38 +52,11 @@
|
||||
<setting name="Enabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="GameDirectory" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="CanCastAbility" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ShowHealth" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ShowDayCycle" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ShowMana" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ShowEvents" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="MainColor" serializeAs="String">
|
||||
<value>#FFFF0000</value>
|
||||
</setting>
|
||||
<setting name="ManaColor" serializeAs="String">
|
||||
<value>#FF0000FF</value>
|
||||
</setting>
|
||||
<setting name="KeyboardLayout" serializeAs="String">
|
||||
<setting name="LastProfile" serializeAs="String">
|
||||
<value>Default</value>
|
||||
</setting>
|
||||
<setting name="AbilityReadyColor" serializeAs="String">
|
||||
<value>#FF00FF00</value>
|
||||
</setting>
|
||||
<setting name="AbilityCooldownColor" serializeAs="String">
|
||||
<value>#FF6A5ACD</value>
|
||||
<setting name="GameDirectory" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</Artemis.Modules.Games.Dota2.Dota2>
|
||||
<Artemis.Modules.Overlays.VolumeDisplay.VolumeDisplay>
|
||||
@ -145,33 +118,12 @@
|
||||
<setting name="Enabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="GameDirectory" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="AmmoEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="AmmoMainColor" serializeAs="String">
|
||||
<value>#FFFF2900</value>
|
||||
</setting>
|
||||
<setting name="AmmoSecondaryColor" serializeAs="String">
|
||||
<value>#FF26F600</value>
|
||||
</setting>
|
||||
<setting name="TeamColorEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="FlashEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="SmokeEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="LowHpEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="LastProfile" serializeAs="String">
|
||||
<value>Default</value>
|
||||
</setting>
|
||||
<setting name="GameDirectory" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</Artemis.Modules.Games.CounterStrike.CounterStrike>
|
||||
<Artemis.Settings.CounterStrike>
|
||||
<setting name="GameDirectory" serializeAs="String">
|
||||
@ -344,6 +296,10 @@
|
||||
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:artemis="clr-namespace:Artemis"
|
||||
xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
|
||||
DispatcherUnhandledException="Application_DispatcherUnhandledException"
|
||||
ShutdownMode="OnExplicitShutdown">
|
||||
<Application.Resources>
|
||||
@ -21,6 +22,7 @@
|
||||
<ResourceDictionary Source="/Resources/Icons.xaml" />
|
||||
<ResourceDictionary Source="Styles/ColorBox.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<converters:MilliSecondTimespanConverter x:Key="MilliSecondTimespanConverter" />
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Security.Principal;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using Artemis.Utilities;
|
||||
using NLog;
|
||||
using WpfExceptionViewer;
|
||||
|
||||
@ -14,8 +15,8 @@ namespace Artemis
|
||||
{
|
||||
public App()
|
||||
{
|
||||
//if (!IsRunAsAdministrator())
|
||||
// GeneralHelpers.RunAsAdministrator();
|
||||
if (!IsRunAsAdministrator())
|
||||
GeneralHelpers.RunAsAdministrator();
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@ -38,8 +38,8 @@
|
||||
<SupportUrl>https://github.com/SpoinkyNL/Artemis/wiki/Frequently-Asked-Questions-%28FAQ%29</SupportUrl>
|
||||
<ProductName>Artemis</ProductName>
|
||||
<PublisherName>Artemis</PublisherName>
|
||||
<ApplicationRevision>2</ApplicationRevision>
|
||||
<ApplicationVersion>1.1.3.2</ApplicationVersion>
|
||||
<ApplicationRevision>3</ApplicationRevision>
|
||||
<ApplicationVersion>1.1.3.3</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<CreateDesktopShortcut>true</CreateDesktopShortcut>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
@ -276,9 +276,9 @@
|
||||
<Compile Include="DeviceProviders\Corsair\CorsairHeadsets.cs" />
|
||||
<Compile Include="DeviceProviders\DeviceProvider.cs" />
|
||||
<Compile Include="Events\ActiveKeyboardChanged.cs" />
|
||||
<Compile Include="Events\RazerColorArrayChanged.cs" />
|
||||
<Compile Include="Events\ToggleEnabled.cs" />
|
||||
<Compile Include="Events\ActiveEffectChanged.cs" />
|
||||
<Compile Include="Events\ChangeBitmap.cs" />
|
||||
<Compile Include="InjectionFactories\ILayerEditorVmFactory.cs" />
|
||||
<Compile Include="InjectionFactories\IProfileEditorVmFactory.cs" />
|
||||
<Compile Include="ItemBehaviours\BindableSelectedItemBehavior.cs" />
|
||||
@ -301,15 +301,14 @@
|
||||
<Compile Include="Models\GameSettings.cs" />
|
||||
<Compile Include="Models\Interfaces\GameDataModel.cs" />
|
||||
<Compile Include="Models\OverlaySettings.cs" />
|
||||
<Compile Include="Models\Profiles\LayerConditionModel.cs" />
|
||||
<Compile Include="Models\Profiles\LayerModel.cs" />
|
||||
<Compile Include="Models\Profiles\ProfileModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\DynamicPropertiesModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\HeadsetPropertiesModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\KeyboardPropertiesModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\LayerPropertiesModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\FolderPropertiesModel.cs" />
|
||||
<Compile Include="Models\Profiles\Properties\MousePropertiesModel.cs" />
|
||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualization.cs" />
|
||||
<Compile Include="Modules\Effects\Bubbles\Bubbles.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\NoneAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\EventPropertiesModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\KeyboardEventPropertiesModel.cs" />
|
||||
<Compile Include="Profiles\ProfileModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\SimplePropertiesModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\Keyboard\KeyboardPropertiesModel.cs" />
|
||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualization.Designer.cs">
|
||||
<DependentUpon>AudioVisualization.settings</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
@ -420,6 +419,26 @@
|
||||
<Compile Include="InjectionModules\ArtemisModules.cs" />
|
||||
<Compile Include="InjectionModules\BaseModules.cs" />
|
||||
<Compile Include="InjectionModules\ManagerModules.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\GrowAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\PulseAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\SlideDownAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\SlideLeftAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\SlideRightAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Animations\SlideUpAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Conditions\DataModelCondition.cs" />
|
||||
<Compile Include="Profiles\Layers\Conditions\EventCondition.cs" />
|
||||
<Compile Include="Profiles\Layers\Interfaces\ILayerAnimation.cs" />
|
||||
<Compile Include="Profiles\Layers\Interfaces\ILayerCondition.cs" />
|
||||
<Compile Include="Profiles\Layers\Interfaces\ILayerType.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\DynamicPropertiesModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\LayerConditionModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\LayerModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Models\LayerPropertiesModel.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\Folder\FolderType.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\Headset\HeadsetType.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\KeyboardGif\KeyboardGifType.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\Keyboard\KeyboardType.cs" />
|
||||
<Compile Include="Profiles\Layers\Types\Mouse\MouseType.cs" />
|
||||
<Compile Include="Properties\Annotations.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
@ -442,6 +461,8 @@
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.cs" />
|
||||
<Compile Include="Utilities\ColorHelpers.cs" />
|
||||
<Compile Include="Utilities\Converters\JsonConverters.cs" />
|
||||
<Compile Include="Utilities\Converters\ValueConverters.cs" />
|
||||
<Compile Include="Utilities\DataReaders\MmfReader.cs" />
|
||||
<Compile Include="Utilities\ExtensionMethods.cs" />
|
||||
<Compile Include="Utilities\GameState\GameDataReceivedEventArgs.cs" />
|
||||
@ -450,8 +471,6 @@
|
||||
<Compile Include="Utilities\GifImage.cs" />
|
||||
<Compile Include="Utilities\ImageUtilities.cs" />
|
||||
<Compile Include="Utilities\Keyboard\KeyboardHook.cs" />
|
||||
<Compile Include="Utilities\Layers\AnimationUpdater.cs" />
|
||||
<Compile Include="Utilities\Layers\Drawer.cs" />
|
||||
<Compile Include="Utilities\Logging.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\DllManager.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\NamedPipeServer.cs" />
|
||||
@ -467,11 +486,11 @@
|
||||
<Compile Include="Utilities\ShellLink.cs" />
|
||||
<Compile Include="Utilities\StickyValue.cs" />
|
||||
<Compile Include="Utilities\Updater.cs" />
|
||||
<Compile Include="Utilities\ValueConverters.cs" />
|
||||
<Compile Include="ViewModels\Abstract\BaseViewModel.cs" />
|
||||
<Compile Include="ViewModels\Abstract\OverlayViewModel.cs" />
|
||||
<Compile Include="ViewModels\Abstract\EffectViewModel.cs" />
|
||||
<Compile Include="ViewModels\Abstract\GameViewModel.cs" />
|
||||
<Compile Include="ViewModels\DebugViewModel.cs" />
|
||||
<Compile Include="ViewModels\EffectsViewModel.cs" />
|
||||
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerViewModel.cs" />
|
||||
<Compile Include="Modules\Effects\TypeWave\TypeWaveViewModel.cs" />
|
||||
@ -482,21 +501,25 @@
|
||||
<Compile Include="Modules\Games\Dota2\Dota2ViewModel.cs" />
|
||||
<Compile Include="Modules\Games\RocketLeague\RocketLeagueViewModel.cs" />
|
||||
<Compile Include="Modules\Games\Witcher3\Witcher3ViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Events\EventPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\ProfileViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Properties\KeyboardPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Layers\KeyboardPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\LayerConditionViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\LayerDynamicPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\LayerEditorViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Properties\LayerPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Properties\HeadsetPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Properties\FolderPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Properties\MousePropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Layers\LayerPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Layers\HeadsetPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Layers\FolderPropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\Layers\MousePropertiesViewModel.cs" />
|
||||
<Compile Include="ViewModels\OverlaysViewModel.cs" />
|
||||
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
|
||||
<Compile Include="ViewModels\Profiles\ProfileEditorViewModel.cs" />
|
||||
<Compile Include="ViewModels\ShellViewModel.cs" />
|
||||
<Compile Include="ViewModels\SystemTrayViewModel.cs" />
|
||||
<Compile Include="ViewModels\WelcomeViewModel.cs" />
|
||||
<Compile Include="Views\DebugView.xaml.cs">
|
||||
<DependentUpon>DebugView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\EffectsView.xaml.cs">
|
||||
<DependentUpon>EffectsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -524,13 +547,16 @@
|
||||
<Compile Include="Modules\Games\Witcher3\Witcher3View.xaml.cs">
|
||||
<DependentUpon>Witcher3View.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\Properties\FolderPropertiesView.xaml.cs">
|
||||
<Compile Include="Views\Profiles\Events\EventPropertiesView.xaml.cs">
|
||||
<DependentUpon>EventPropertiesView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\Layers\FolderPropertiesView.xaml.cs">
|
||||
<DependentUpon>FolderPropertiesView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\Properties\HeadsetPropertiesView.xaml.cs">
|
||||
<Compile Include="Views\Profiles\Layers\HeadsetPropertiesView.xaml.cs">
|
||||
<DependentUpon>HeadsetPropertiesView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\Properties\KeyboardPropertiesView.xaml.cs">
|
||||
<Compile Include="Views\Profiles\Layers\KeyboardPropertiesView.xaml.cs">
|
||||
<DependentUpon>KeyboardPropertiesView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\LayerConditionView.xaml.cs">
|
||||
@ -542,7 +568,7 @@
|
||||
<Compile Include="Views\Profiles\LayerEditorView.xaml.cs">
|
||||
<DependentUpon>LayerEditorView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\Profiles\Properties\MousePropertiesView.xaml.cs">
|
||||
<Compile Include="Views\Profiles\Layers\MousePropertiesView.xaml.cs">
|
||||
<DependentUpon>MousePropertiesView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\OverlaysView.xaml.cs">
|
||||
@ -660,7 +686,9 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Modules\Effects\Bubbles\BubblesView.xaml">
|
||||
@ -695,6 +723,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\DebugView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\EffectsView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@ -731,15 +763,19 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Profiles\Properties\FolderPropertiesView.xaml">
|
||||
<Page Include="Views\Profiles\Events\EventPropertiesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Profiles\Properties\HeadsetPropertiesView.xaml">
|
||||
<Page Include="Views\Profiles\Layers\FolderPropertiesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Profiles\Properties\KeyboardPropertiesView.xaml">
|
||||
<Page Include="Views\Profiles\Layers\HeadsetPropertiesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\Profiles\Layers\KeyboardPropertiesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
@ -755,7 +791,7 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Views\Profiles\Properties\MousePropertiesView.xaml">
|
||||
<Page Include="Views\Profiles\Layers\MousePropertiesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
@ -802,7 +838,9 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Folder Include="Utilities\ValueConverters\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets" Condition="Exists('..\packages\CUE.NET.1.0.3\build\net45\CUE.NET.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
||||
@ -5,9 +5,11 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using Artemis.InjectionModules;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels;
|
||||
using Caliburn.Micro;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
using Application = System.Windows.Application;
|
||||
using MessageBox = System.Windows.Forms.MessageBox;
|
||||
@ -22,7 +24,7 @@ namespace Artemis
|
||||
public ArtemisBootstrapper()
|
||||
{
|
||||
// Start logging before anything else
|
||||
Logging.SetupLogging(Settings.General.Default.LogLevel);
|
||||
Logging.SetupLogging(General.Default.LogLevel);
|
||||
|
||||
CheckDuplicateInstances();
|
||||
Initialize();
|
||||
@ -77,6 +79,7 @@ namespace Artemis
|
||||
|
||||
protected override void Configure()
|
||||
{
|
||||
JsonConvert.DefaultSettings = () => new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto};
|
||||
_kernel = new StandardKernel(new BaseModules(), new ArtemisModules(), new ManagerModules());
|
||||
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
|
||||
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
|
||||
@ -114,7 +117,7 @@ namespace Artemis
|
||||
private void CheckDuplicateInstances()
|
||||
{
|
||||
bool aIsNewInstance;
|
||||
Mutex = new Mutex(true, "ArtemisMutex", out aIsNewInstance);
|
||||
Mutex = new Mutex(true, "ArtemisMutex2", out aIsNewInstance);
|
||||
if (aIsNewInstance)
|
||||
return;
|
||||
|
||||
|
||||
@ -4,13 +4,13 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.DeviceProviders;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Profiles;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
|
||||
namespace Artemis.DAL
|
||||
@ -65,14 +65,8 @@ namespace Artemis.DAL
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
var serializer = new XmlSerializer(typeof(ProfileModel));
|
||||
|
||||
// Could use a StreamWriter but should serializing fail this method doesn't ruin the existing XML file
|
||||
using (var xml = new StringWriter())
|
||||
{
|
||||
serializer.Serialize(xml, prof);
|
||||
File.WriteAllText(path + $@"\{prof.Name}.xml", xml.ToString());
|
||||
}
|
||||
var json = JsonConvert.SerializeObject(prof, Formatting.Indented);
|
||||
File.WriteAllText(path + $@"\{prof.Name}.json", json);
|
||||
}
|
||||
|
||||
private static List<ProfileModel> ReadProfiles()
|
||||
@ -82,22 +76,18 @@ namespace Artemis.DAL
|
||||
var profiles = new List<ProfileModel>();
|
||||
|
||||
// Create the directory structure
|
||||
var profilePaths = Directory.GetFiles(ProfileFolder, "*.xml", SearchOption.AllDirectories);
|
||||
var profilePaths = Directory.GetFiles(ProfileFolder, "*.json", SearchOption.AllDirectories);
|
||||
|
||||
// Parse the JSON files into objects and add them if they are valid
|
||||
var deserializer = new XmlSerializer(typeof(ProfileModel));
|
||||
foreach (var path in profilePaths)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var file = new StreamReader(path))
|
||||
{
|
||||
var prof = (ProfileModel) deserializer.Deserialize(file);
|
||||
if (prof.GameName?.Length > 1 && prof.KeyboardSlug?.Length > 1 && prof.Name?.Length > 1)
|
||||
profiles.Add(prof);
|
||||
}
|
||||
var prof = LoadProfileIfValid(path);
|
||||
if (prof != null)
|
||||
profiles.Add(prof);
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Failed to load profile: {0} - {1}", path, e.InnerException.Message);
|
||||
}
|
||||
@ -144,7 +134,6 @@ namespace Artemis.DAL
|
||||
((KeyboardPropertiesModel) gifLayer.Properties).GifFile = gifPath;
|
||||
AddOrUpdate(demoProfile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -166,18 +155,17 @@ namespace Artemis.DAL
|
||||
/// <returns>The loaded profile, or null if invalid</returns>
|
||||
public static ProfileModel LoadProfileIfValid(string path)
|
||||
{
|
||||
// TODO: What exception on load failure?
|
||||
try
|
||||
{
|
||||
var deserializer = new XmlSerializer(typeof(ProfileModel));
|
||||
using (var file = new StreamReader(path))
|
||||
{
|
||||
var prof = (ProfileModel) deserializer.Deserialize(file);
|
||||
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Name?.Length > 1))
|
||||
return null;
|
||||
return prof;
|
||||
}
|
||||
var prof = JsonConvert.DeserializeObject<ProfileModel>(File.ReadAllText(path));
|
||||
if (prof == null)
|
||||
return null;
|
||||
if (prof.GameName.Length < 1 || prof.KeyboardSlug.Length < 1 || prof.Name.Length < 1)
|
||||
return null;
|
||||
return prof;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -186,15 +174,12 @@ namespace Artemis.DAL
|
||||
/// <summary>
|
||||
/// Exports the given profile to the provided path in XML
|
||||
/// </summary>
|
||||
/// <param name="selectedProfile">The profile to export</param>
|
||||
/// <param name="prof">The profile to export</param>
|
||||
/// <param name="path">The path to save the profile to</param>
|
||||
public static void ExportProfile(ProfileModel selectedProfile, string path)
|
||||
public static void ExportProfile(ProfileModel prof, string path)
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(ProfileModel));
|
||||
using (var file = new StreamWriter(path))
|
||||
{
|
||||
serializer.Serialize(file, selectedProfile);
|
||||
}
|
||||
var json = JsonConvert.SerializeObject(prof);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -208,7 +193,7 @@ namespace Artemis.DAL
|
||||
return;
|
||||
|
||||
// Remove the old file
|
||||
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
|
||||
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.json";
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
|
||||
@ -220,7 +205,7 @@ namespace Artemis.DAL
|
||||
public static void DeleteProfile(ProfileModel profile)
|
||||
{
|
||||
// Remove the file
|
||||
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
|
||||
var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.json";
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Utilities;
|
||||
using CUE.NET;
|
||||
using CUE.NET.Devices.Generic.Enums;
|
||||
using Ninject.Extensions.Logging;
|
||||
@ -35,33 +34,30 @@ namespace Artemis.DeviceProviders.Corsair
|
||||
CueSDK.Reinitialize();
|
||||
}
|
||||
|
||||
public override void UpdateDevice(Brush brush)
|
||||
public override void UpdateDevice(Bitmap bitmap)
|
||||
{
|
||||
if (!CanUse || brush == null)
|
||||
if (!CanUse || bitmap == null)
|
||||
return;
|
||||
if (bitmap.Width != bitmap.Height)
|
||||
throw new ArgumentException("Bitmap must be a perfect square");
|
||||
|
||||
var leds = CueSDK.HeadsetSDK.Leds.Count();
|
||||
var rect = new Rect(new Size(leds*20, leds*20));
|
||||
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawRectangle(brush, null, rect);
|
||||
|
||||
using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
|
||||
var step = (double) bitmap.Width/leds;
|
||||
using (bitmap)
|
||||
{
|
||||
|
||||
var ledIndex = 0;
|
||||
// Color each LED according to one of the pixels
|
||||
foreach (var corsairLed in CueSDK.HeadsetSDK.Leds)
|
||||
{
|
||||
corsairLed.Color = ledIndex == 0
|
||||
? img.GetPixel(0, 0)
|
||||
: img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
|
||||
if (ledIndex == 0)
|
||||
corsairLed.Color = bitmap.GetPixel(0, 0);
|
||||
else
|
||||
corsairLed.Color = bitmap.GetPixel((int) ((ledIndex + 1)*step - 1),
|
||||
(int) ((ledIndex + 1)*step - 1));
|
||||
ledIndex++;
|
||||
}
|
||||
}
|
||||
// Flush is required for headset to work reliably on CUE2 for some reason
|
||||
CueSDK.HeadsetSDK.Update(true);
|
||||
CueSDK.HeadsetSDK.Update();
|
||||
}
|
||||
|
||||
private static bool CanInitializeSdk()
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Utilities;
|
||||
using CUE.NET;
|
||||
using CUE.NET.Devices.Generic.Enums;
|
||||
using Ninject.Extensions.Logging;
|
||||
@ -35,27 +34,26 @@ namespace Artemis.DeviceProviders.Corsair
|
||||
CueSDK.Reinitialize();
|
||||
}
|
||||
|
||||
public override void UpdateDevice(Brush brush)
|
||||
public override void UpdateDevice(Bitmap bitmap)
|
||||
{
|
||||
if (!CanUse || brush == null)
|
||||
if (!CanUse || bitmap == null)
|
||||
return;
|
||||
if (bitmap.Width != bitmap.Height)
|
||||
throw new ArgumentException("Bitmap must be a perfect square");
|
||||
|
||||
var leds = CueSDK.MouseSDK.Leds.Count();
|
||||
var rect = new Rect(new Size(leds*20, leds*20));
|
||||
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawRectangle(brush, null, rect);
|
||||
|
||||
using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
|
||||
var step = (double) bitmap.Width/leds;
|
||||
using (bitmap)
|
||||
{
|
||||
var ledIndex = 0;
|
||||
// Color each LED according to one of the pixels
|
||||
foreach (var corsairLed in CueSDK.MouseSDK.Leds)
|
||||
{
|
||||
corsairLed.Color = ledIndex == 0
|
||||
? img.GetPixel(0, 0)
|
||||
: img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
|
||||
if (ledIndex == 0)
|
||||
corsairLed.Color = bitmap.GetPixel(0, 0);
|
||||
else
|
||||
corsairLed.Color = bitmap.GetPixel((int) ((ledIndex + 1)*step - 1),
|
||||
(int) ((ledIndex + 1)*step - 1));
|
||||
ledIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Artemis.DeviceProviders
|
||||
{
|
||||
@ -16,10 +16,10 @@ namespace Artemis.DeviceProviders
|
||||
public bool CanUse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates a non-keyboard to take the colours of the provided brush
|
||||
/// Updates a non-keyboard to take the colours found in the provided bitmap
|
||||
/// </summary>
|
||||
/// <param name="brush"></param>
|
||||
public abstract void UpdateDevice(Brush brush);
|
||||
/// <param name="bitmap"></param>
|
||||
public abstract void UpdateDevice(Bitmap bitmap);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to enable the device and updates CanUse accordingly
|
||||
@ -32,7 +32,7 @@ namespace Artemis.DeviceProviders
|
||||
public abstract void Disable();
|
||||
|
||||
/// <summary>
|
||||
/// Tries to enable the device and updates CanUse accordingly asynchronously
|
||||
/// Tries to enable the device and updates CanUse accordingly asynchronously
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<bool> TryEnableAsync()
|
||||
|
||||
@ -4,7 +4,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using MahApps.Metro.Controls.Dialogs;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace Artemis.DeviceProviders
|
||||
@ -87,7 +86,7 @@ namespace Artemis.DeviceProviders
|
||||
return Task.Run(() => Enable());
|
||||
}
|
||||
|
||||
public override void UpdateDevice(Brush brush)
|
||||
public override void UpdateDevice(Bitmap bitmap)
|
||||
{
|
||||
throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Artemis.Events
|
||||
{
|
||||
public class ChangeBitmap
|
||||
{
|
||||
public ChangeBitmap(Bitmap bitmap)
|
||||
{
|
||||
Bitmap = bitmap;
|
||||
}
|
||||
|
||||
public Bitmap Bitmap { get; private set; }
|
||||
|
||||
public void ChangeTextMessage(Bitmap bitmap)
|
||||
{
|
||||
Bitmap = bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Artemis/Artemis/Events/RazerColorArrayChanged.cs
Normal file
14
Artemis/Artemis/Events/RazerColorArrayChanged.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Artemis.Events
|
||||
{
|
||||
public class RazerColorArrayChanged
|
||||
{
|
||||
public RazerColorArrayChanged(Color[,] colors)
|
||||
{
|
||||
Colors = colors;
|
||||
}
|
||||
|
||||
public Color[,] Colors { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.ViewModels.Profiles;
|
||||
|
||||
namespace Artemis.InjectionFactories
|
||||
|
||||
@ -13,6 +13,14 @@ using Artemis.Modules.Games.RocketLeague;
|
||||
using Artemis.Modules.Games.TheDivision;
|
||||
using Artemis.Modules.Games.Witcher3;
|
||||
using Artemis.Modules.Overlays.VolumeDisplay;
|
||||
using Artemis.Profiles.Layers.Animations;
|
||||
using Artemis.Profiles.Layers.Conditions;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Types.Folder;
|
||||
using Artemis.Profiles.Layers.Types.Headset;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Profiles.Layers.Types.KeyboardGif;
|
||||
using Artemis.Profiles.Layers.Types.Mouse;
|
||||
using Artemis.ViewModels.Abstract;
|
||||
using Ninject.Modules;
|
||||
|
||||
@ -55,6 +63,28 @@ namespace Artemis.InjectionModules
|
||||
Bind<DeviceProvider>().To<CorsairHeadsets>().InSingletonScope();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Layers
|
||||
|
||||
// Animations
|
||||
Bind<ILayerAnimation>().To<NoneAnimation>();
|
||||
Bind<ILayerAnimation>().To<GrowAnimation>();
|
||||
Bind<ILayerAnimation>().To<PulseAnimation>();
|
||||
Bind<ILayerAnimation>().To<SlideDownAnimation>();
|
||||
Bind<ILayerAnimation>().To<SlideLeftAnimation>();
|
||||
Bind<ILayerAnimation>().To<SlideRightAnimation>();
|
||||
Bind<ILayerAnimation>().To<SlideUpAnimation>();
|
||||
// Conditions
|
||||
Bind<ILayerCondition>().To<DataModelCondition>();
|
||||
Bind<ILayerCondition>().To<EventCondition>();
|
||||
// Types
|
||||
Bind<ILayerType>().To<FolderType>();
|
||||
Bind<ILayerType>().To<HeadsetType>();
|
||||
Bind<ILayerType>().To<KeyboardType>();
|
||||
Bind<ILayerType>().To<KeyboardGifType>();
|
||||
Bind<ILayerType>().To<MouseType>();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,7 @@ namespace Artemis.InjectionModules
|
||||
Bind<IProfileEditorVmFactory>().ToFactory();
|
||||
Bind<ILayerEditorVmFactory>().ToFactory();
|
||||
Bind<ProfileViewModel>().ToSelf();
|
||||
Bind<DebugViewModel>().ToSelf().InSingletonScope();
|
||||
|
||||
Bind<BaseViewModel>().To<WelcomeViewModel>().InSingletonScope();
|
||||
Bind<BaseViewModel>().To<EffectsViewModel>().InSingletonScope();
|
||||
|
||||
@ -6,7 +6,6 @@ using System.Timers;
|
||||
using Artemis.Events;
|
||||
using Caliburn.Micro;
|
||||
using Ninject.Extensions.Logging;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Managers
|
||||
{
|
||||
@ -21,7 +20,8 @@ namespace Artemis.Managers
|
||||
private readonly Timer _loopTimer;
|
||||
private Bitmap _keyboardBitmap;
|
||||
|
||||
public LoopManager(IEventAggregator events, ILogger logger, EffectManager effectManager, DeviceManager deviceManager)
|
||||
public LoopManager(IEventAggregator events, ILogger logger, EffectManager effectManager,
|
||||
DeviceManager deviceManager)
|
||||
{
|
||||
events.Subscribe(this);
|
||||
_logger = logger;
|
||||
@ -48,6 +48,18 @@ namespace Artemis.Managers
|
||||
_keyboardBitmap?.Dispose();
|
||||
}
|
||||
|
||||
public void Handle(ActiveEffectChanged message)
|
||||
{
|
||||
if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
|
||||
_keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
|
||||
}
|
||||
|
||||
public void Handle(ActiveKeyboardChanged message)
|
||||
{
|
||||
if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
|
||||
_keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
|
||||
}
|
||||
|
||||
public Task StartAsync()
|
||||
{
|
||||
return Task.Run(() => Start());
|
||||
@ -132,50 +144,31 @@ namespace Artemis.Managers
|
||||
renderEffect.Update();
|
||||
|
||||
// Get ActiveEffect's bitmap
|
||||
Brush mouseBrush = null;
|
||||
Brush headsetBrush = null;
|
||||
Bitmap mouseBitmap = null;
|
||||
Bitmap headsetBitmap = null;
|
||||
var mice = _deviceManager.MiceProviders.Where(m => m.CanUse).ToList();
|
||||
var headsets = _deviceManager.HeadsetProviders.Where(m => m.CanUse).ToList();
|
||||
|
||||
using (Graphics keyboardGraphics = Graphics.FromImage(_keyboardBitmap))
|
||||
if (renderEffect.Initialized)
|
||||
renderEffect.Render(_keyboardBitmap, out mouseBitmap, out headsetBitmap, mice.Any(), headsets.Any());
|
||||
|
||||
// Draw enabled overlays on top of the renderEffect
|
||||
foreach (var overlayModel in _effectManager.EnabledOverlays)
|
||||
{
|
||||
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
||||
keyboardGraphics.Clear(Color.Black);
|
||||
|
||||
if (renderEffect.Initialized)
|
||||
renderEffect.Render(keyboardGraphics, out mouseBrush, out headsetBrush, mice.Any(),
|
||||
headsets.Any());
|
||||
|
||||
// Draw enabled overlays on top of the renderEffect
|
||||
foreach (var overlayModel in _effectManager.EnabledOverlays)
|
||||
{
|
||||
overlayModel.Update();
|
||||
overlayModel.RenderOverlay(keyboardGraphics, ref mouseBrush, ref headsetBrush, mice.Any(),
|
||||
headsets.Any());
|
||||
}
|
||||
|
||||
// Update mice and headsets
|
||||
foreach (var mouse in mice)
|
||||
mouse.UpdateDevice(mouseBrush);
|
||||
foreach (var headset in headsets)
|
||||
headset.UpdateDevice(headsetBrush);
|
||||
overlayModel.Update();
|
||||
overlayModel.RenderOverlay(_keyboardBitmap, ref mouseBitmap, ref headsetBitmap, mice.Any(),
|
||||
headsets.Any());
|
||||
}
|
||||
|
||||
// Update mice and headsets
|
||||
foreach (var mouse in mice)
|
||||
mouse.UpdateDevice(mouseBitmap);
|
||||
foreach (var headset in headsets)
|
||||
headset.UpdateDevice(headsetBitmap);
|
||||
|
||||
// Update the keyboard
|
||||
_deviceManager.ActiveKeyboard?.DrawBitmap(_keyboardBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(ActiveKeyboardChanged message)
|
||||
{
|
||||
if (_deviceManager.ActiveKeyboard != null &&_effectManager.ActiveEffect != null)
|
||||
_keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
|
||||
}
|
||||
|
||||
public void Handle(ActiveEffectChanged message)
|
||||
{
|
||||
if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
|
||||
_keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,12 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Headset;
|
||||
using Artemis.Profiles.Layers.Types.Mouse;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Models
|
||||
{
|
||||
@ -15,12 +17,7 @@ namespace Artemis.Models
|
||||
{
|
||||
public delegate void SettingsUpdateHandler(EffectSettings settings);
|
||||
|
||||
public bool Initialized { get; set; }
|
||||
public MainManager MainManager { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int KeyboardScale { get; set; } = 4;
|
||||
|
||||
private DateTime _lastTrace;
|
||||
protected DateTime LastTrace;
|
||||
|
||||
protected EffectModel(MainManager mainManager, IDataModel dataModel)
|
||||
{
|
||||
@ -28,6 +25,11 @@ namespace Artemis.Models
|
||||
DataModel = dataModel;
|
||||
}
|
||||
|
||||
public bool Initialized { get; set; }
|
||||
public MainManager MainManager { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int KeyboardScale { get; set; } = 4;
|
||||
|
||||
// Used by profile system
|
||||
public IDataModel DataModel { get; set; }
|
||||
public ProfileModel Profile { get; set; }
|
||||
@ -41,7 +43,8 @@ namespace Artemis.Models
|
||||
public abstract void Update();
|
||||
|
||||
// Called after every update
|
||||
public virtual void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
|
||||
public virtual void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
mouse = null;
|
||||
headset = null;
|
||||
@ -52,24 +55,41 @@ namespace Artemis.Models
|
||||
// Get all enabled layers who's conditions are met
|
||||
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
|
||||
|
||||
// Trace debugging
|
||||
if (DateTime.Now.AddSeconds(-2) > _lastTrace)
|
||||
// Render the keyboard layer-by-layer
|
||||
var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
_lastTrace = DateTime.Now;
|
||||
MainManager.Logger.Trace("Effect datamodel as JSON: \r\n{0}",
|
||||
JsonConvert.SerializeObject(DataModel, Formatting.Indented));
|
||||
MainManager.Logger.Trace("Effect {0} has to render {1} layers", Name, renderLayers.Count);
|
||||
foreach (var renderLayer in renderLayers)
|
||||
MainManager.Logger.Trace(" Layer name: {0}, layer type: {1}", renderLayer.Name,
|
||||
renderLayer.LayerType);
|
||||
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
||||
g.Clear(Color.Black);
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.MustDraw()), DataModel, keyboardRect, false, true);
|
||||
}
|
||||
|
||||
// Render the keyboard layer-by-layer
|
||||
Profile.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), false, true);
|
||||
// Render the first enabled mouse (will default to null if renderMice was false)
|
||||
mouse = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
|
||||
// Render the first enabled headset (will default to null if renderHeadsets was false)
|
||||
headset = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset), DataModel);
|
||||
// Render the mouse layer-by-layer
|
||||
var smallRect = new Rect(0, 0, 40, 40);
|
||||
mouse = new Bitmap(40, 40);
|
||||
using (var g = Graphics.FromImage(mouse))
|
||||
{
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is MouseType), DataModel, smallRect,
|
||||
false, true);
|
||||
}
|
||||
|
||||
// Render the headset layer-by-layer
|
||||
headset = new Bitmap(40, 40);
|
||||
using (var g = Graphics.FromImage(headset))
|
||||
{
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is HeadsetType), DataModel, smallRect,
|
||||
false, true);
|
||||
}
|
||||
|
||||
// Trace debugging
|
||||
if (DateTime.Now.AddSeconds(-2) <= LastTrace)
|
||||
return;
|
||||
LastTrace = DateTime.Now;
|
||||
MainManager.Logger.Trace("Effect datamodel as JSON: \r\n{0}",
|
||||
JsonConvert.SerializeObject(DataModel, Formatting.Indented));
|
||||
MainManager.Logger.Trace("Effect {0} has to render {1} layers", Name, renderLayers.Count);
|
||||
foreach (var renderLayer in renderLayers)
|
||||
MainManager.Logger.Trace("- Layer name: {0}, layer type: {1}", renderLayer.Name, renderLayer.LayerType);
|
||||
}
|
||||
|
||||
public abstract List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using System.Drawing;
|
||||
using Artemis.Managers;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Models
|
||||
{
|
||||
@ -29,7 +28,7 @@ namespace Artemis.Models
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
|
||||
public abstract void RenderOverlay(Bitmap keyboard, ref Bitmap mouse, ref Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets);
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
{
|
||||
public class FolderPropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||
{
|
||||
return new AppliedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
{
|
||||
public class HeadsetPropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||
{
|
||||
return new AppliedProperties {Brush = Brush};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
{
|
||||
public class KeyboardPropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public KeyboardPropertiesModel()
|
||||
{
|
||||
DynamicProperties = new List<DynamicPropertiesModel>();
|
||||
}
|
||||
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public double Opacity { get; set; }
|
||||
public bool Contain { get; set; }
|
||||
public LayerAnimation Animation { get; set; }
|
||||
public double AnimationSpeed { get; set; }
|
||||
public string GifFile { get; set; }
|
||||
public List<DynamicPropertiesModel> DynamicProperties { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public double AnimationProgress { get; set; }
|
||||
|
||||
public Rect GetRect(int scale = 4)
|
||||
{
|
||||
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
||||
}
|
||||
|
||||
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||
{
|
||||
var applied = new AppliedProperties
|
||||
{
|
||||
X = X,
|
||||
Y = Y,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
Opacity = Opacity,
|
||||
Brush = Brush.CloneCurrentValue()
|
||||
};
|
||||
|
||||
if (ignoreDynamic)
|
||||
return applied;
|
||||
|
||||
foreach (var dynamicProperty in DynamicProperties)
|
||||
dynamicProperty.ApplyProperty(dataModel, ref applied);
|
||||
|
||||
if (Math.Abs(applied.Opacity - 1) > 0.001)
|
||||
{
|
||||
applied.Brush = Brush.CloneCurrentValue();
|
||||
applied.Brush.Opacity = applied.Opacity;
|
||||
}
|
||||
|
||||
return applied;
|
||||
}
|
||||
}
|
||||
|
||||
public enum LayerAnimation
|
||||
{
|
||||
[Description("None")] None,
|
||||
[Description("Slide left")] SlideLeft,
|
||||
[Description("Slide right")] SlideRight,
|
||||
[Description("Slide up")] SlideUp,
|
||||
[Description("Slide down")] SlideDown,
|
||||
[Description("Grow")] Grow,
|
||||
[Description("Pulse")] Pulse
|
||||
}
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
{
|
||||
[XmlInclude(typeof(SolidColorBrush))]
|
||||
[XmlInclude(typeof(LinearGradientBrush))]
|
||||
[XmlInclude(typeof(RadialGradientBrush))]
|
||||
[XmlInclude(typeof(MatrixTransform))]
|
||||
[XmlInclude(typeof(KeyboardPropertiesModel))]
|
||||
[XmlInclude(typeof(MousePropertiesModel))]
|
||||
[XmlInclude(typeof(HeadsetPropertiesModel))]
|
||||
[XmlInclude(typeof(FolderPropertiesModel))]
|
||||
public abstract class LayerPropertiesModel
|
||||
{
|
||||
private Brush _brush;
|
||||
|
||||
protected LayerPropertiesModel()
|
||||
{
|
||||
Conditions = new List<LayerConditionModel>();
|
||||
}
|
||||
|
||||
public List<LayerConditionModel> Conditions { get; set; }
|
||||
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false);
|
||||
}
|
||||
|
||||
public struct AppliedProperties
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public double Opacity { get; set; }
|
||||
public Brush Brush { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
{
|
||||
public class MousePropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
|
||||
{
|
||||
return new AppliedProperties {Brush = Brush};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
namespace Artemis.Modules.Effects.AudioVisualizer {
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
internal sealed partial class AudioVisualization {
|
||||
|
||||
public AudioVisualization() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,13 +5,12 @@ using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Modules.Effects.AudioVisualizer.Utilities;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.Keyboard;
|
||||
using NAudio.CoreAudioApi;
|
||||
using NAudio.Wave;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
{
|
||||
@ -78,7 +77,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
ColorHelpers.ToDrawingColor(Settings.BottomColor)
|
||||
},
|
||||
LinearGradientMode.Vertical)
|
||||
{ ContainedBrush = false, Height = 0 });
|
||||
{ContainedBrush = false, Height = 0});
|
||||
}
|
||||
_sensitivity = Settings.Sensitivity;
|
||||
_fromBottom = Settings.FromBottom;
|
||||
@ -118,22 +117,22 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
if (SpectrumData.Count - 1 < i || SpectrumData[i] == 0)
|
||||
height = 0;
|
||||
else
|
||||
height = (int)Math.Round(SpectrumData[i] / 2.55);
|
||||
height = (int) Math.Round(SpectrumData[i]/2.55);
|
||||
|
||||
// Apply Sensitivity setting
|
||||
height = height * _sensitivity;
|
||||
height = height*_sensitivity;
|
||||
var keyboardHeight =
|
||||
(int)Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height / 100.00 * height * KeyboardScale);
|
||||
(int) Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height/100.00*height*KeyboardScale);
|
||||
if (keyboardHeight > SoundRectangles[i].Height)
|
||||
SoundRectangles[i].Height = keyboardHeight;
|
||||
else
|
||||
SoundRectangles[i].Height = SoundRectangles[i].Height - Settings.FadeSpeed;
|
||||
// Apply Bars setting
|
||||
SoundRectangles[i].X = i * KeyboardScale;
|
||||
SoundRectangles[i].X = i*KeyboardScale;
|
||||
SoundRectangles[i].Width = KeyboardScale;
|
||||
|
||||
if (_fromBottom)
|
||||
SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height * KeyboardScale -
|
||||
SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height*KeyboardScale -
|
||||
SoundRectangles[i].Height;
|
||||
}
|
||||
_generating = false;
|
||||
@ -164,7 +163,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
for (x = 0; x < Lines; x++)
|
||||
{
|
||||
float peak = 0;
|
||||
var b1 = (int)Math.Pow(2, x * 10.0 / (Lines - 1));
|
||||
var b1 = (int) Math.Pow(2, x*10.0/(Lines - 1));
|
||||
if (b1 > 2047)
|
||||
b1 = 2047;
|
||||
if (b1 <= b0)
|
||||
@ -174,12 +173,12 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
if (peak < e.Result[1 + b0].X)
|
||||
peak = e.Result[1 + b0].X;
|
||||
}
|
||||
var y = (int)(Math.Sqrt(peak) * 3 * 255 - 4);
|
||||
var y = (int) (Math.Sqrt(peak)*3*255 - 4);
|
||||
if (y > 255)
|
||||
y = 255;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
SpectrumData.Add((byte)y);
|
||||
SpectrumData.Add((byte) y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +187,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||
public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
mouse = null;
|
||||
@ -200,8 +199,11 @@ namespace Artemis.Modules.Effects.AudioVisualizer
|
||||
// Lock the _spectrumData array while busy with it
|
||||
_generating = true;
|
||||
|
||||
foreach (var soundRectangle in SoundRectangles)
|
||||
soundRectangle.Draw(keyboard);
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
foreach (var soundRectangle in SoundRectangles)
|
||||
soundRectangle.Draw(g);
|
||||
}
|
||||
|
||||
_generating = false;
|
||||
}
|
||||
|
||||
@ -6,11 +6,24 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
{
|
||||
public class Bubble
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public Bubble(Color color, int radius, Point position, Vector direction)
|
||||
{
|
||||
Color = color;
|
||||
Radius = radius;
|
||||
Position = position;
|
||||
Direction = direction;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private Brush _brush;
|
||||
|
||||
private Color _color;
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get { return _color; }
|
||||
@ -27,27 +40,15 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Bubble(Color color, int radius, Point position, Vector direction)
|
||||
{
|
||||
this.Color = color;
|
||||
this.Radius = radius;
|
||||
this.Position = position;
|
||||
this.Direction = direction;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void CheckCollision(Rect border)
|
||||
{
|
||||
if (Position.X - Radius < border.X || Position.X + Radius > border.X + border.Width)
|
||||
Direction = new Vector(Direction.X * -1, Direction.Y);
|
||||
Direction = new Vector(Direction.X*-1, Direction.Y);
|
||||
|
||||
if (Position.Y - Radius < border.Y || Position.Y + Radius > border.Y + border.Height)
|
||||
Direction = new Vector(Direction.X, Direction.Y * -1);
|
||||
Direction = new Vector(Direction.X, Direction.Y*-1);
|
||||
}
|
||||
|
||||
public void Move()
|
||||
@ -57,9 +58,9 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
|
||||
public void Draw(Graphics g)
|
||||
{
|
||||
g.FillEllipse(_brush, (float)Position.X - Radius, (float)Position.Y - Radius, Radius * 2, Radius * 2);
|
||||
g.FillEllipse(_brush, (float) Position.X - Radius, (float) Position.Y - Radius, Radius*2, Radius*2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs
Normal file
28
Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace Artemis.Modules.Effects.Bubbles {
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
internal sealed partial class Bubbles {
|
||||
|
||||
public Bubbles() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Artemis.Modules.Effects.Bubbles" GeneratedClassName="Bubbles">
|
||||
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||
GeneratedClassNamespace="Artemis.Modules.Effects.Bubbles" GeneratedClassName="Bubbles">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="IsRandomColors" Type="System.Boolean" Scope="User">
|
||||
|
||||
@ -4,24 +4,14 @@ using System.Drawing;
|
||||
using System.Windows;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
namespace Artemis.Modules.Effects.Bubbles
|
||||
{
|
||||
public class BubblesModel : EffectModel
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
private readonly List<Bubble> _bubbles = new List<Bubble>();
|
||||
|
||||
public BubblesSettings Settings { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public BubblesModel(MainManager mainManager, BubblesSettings settings)
|
||||
@ -34,27 +24,43 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
private readonly List<Bubble> _bubbles = new List<Bubble>();
|
||||
|
||||
public BubblesSettings Settings { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
KeyboardScale = Settings.Smoothness;
|
||||
|
||||
Rect rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
var rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
|
||||
double scaleFactor = Settings.Smoothness / 25.0;
|
||||
var scaleFactor = Settings.Smoothness/25.0;
|
||||
|
||||
for (int i = 0; i < Settings.BubbleCount; i++)
|
||||
for (var i = 0; i < Settings.BubbleCount; i++)
|
||||
{
|
||||
Color color = Settings.IsRandomColors ? ColorHelpers.GetRandomRainbowColor() : ColorHelpers.ToDrawingColor(Settings.BubbleColor);
|
||||
var color = Settings.IsRandomColors
|
||||
? ColorHelpers.GetRandomRainbowColor()
|
||||
: ColorHelpers.ToDrawingColor(Settings.BubbleColor);
|
||||
// -Settings.MoveSpeed because we want to spawn at least one move away from borders
|
||||
double initialPositionX = ((rect.Width - (Settings.BubbleSize * scaleFactor * 2) - Settings.MoveSpeed * scaleFactor) * _random.NextDouble()) + Settings.BubbleSize * scaleFactor;
|
||||
double initialPositionY = ((rect.Height - (Settings.BubbleSize * scaleFactor * 2) - Settings.MoveSpeed * scaleFactor) * _random.NextDouble()) + Settings.BubbleSize * scaleFactor;
|
||||
double initialDirectionX = (Settings.MoveSpeed * scaleFactor * _random.NextDouble()) * (_random.Next(1) == 0 ? -1 : 1);
|
||||
double initialDirectionY = (Settings.MoveSpeed * scaleFactor - Math.Abs(initialDirectionX)) * (_random.Next(1) == 0 ? -1 : 1);
|
||||
var initialPositionX = (rect.Width - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
|
||||
_random.NextDouble() + Settings.BubbleSize*scaleFactor;
|
||||
var initialPositionY = (rect.Height - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
|
||||
_random.NextDouble() + Settings.BubbleSize*scaleFactor;
|
||||
var initialDirectionX = Settings.MoveSpeed*scaleFactor*_random.NextDouble()*
|
||||
(_random.Next(1) == 0 ? -1 : 1);
|
||||
var initialDirectionY = (Settings.MoveSpeed*scaleFactor - Math.Abs(initialDirectionX))*
|
||||
(_random.Next(1) == 0 ? -1 : 1);
|
||||
|
||||
_bubbles.Add(new Bubble(color, (int)Math.Round(Settings.BubbleSize * scaleFactor),
|
||||
new System.Windows.Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
|
||||
_bubbles.Add(new Bubble(color, (int) Math.Round(Settings.BubbleSize*scaleFactor),
|
||||
new Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
@ -68,24 +74,31 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
Rect keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
foreach (Bubble bubble in _bubbles)
|
||||
var keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
foreach (var bubble in _bubbles)
|
||||
{
|
||||
if (Settings.IsShiftColors)
|
||||
bubble.Color = ColorHelpers.ShiftColor(bubble.Color, Settings.IsRandomColors ? (int)Math.Round(Settings.ShiftColorSpeed * _random.NextDouble()) : Settings.ShiftColorSpeed);
|
||||
bubble.Color = ColorHelpers.ShiftColor(bubble.Color,
|
||||
Settings.IsRandomColors
|
||||
? (int) Math.Round(Settings.ShiftColorSpeed*_random.NextDouble())
|
||||
: Settings.ShiftColorSpeed);
|
||||
|
||||
bubble.CheckCollision(keyboardRectangle);
|
||||
bubble.Move();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
|
||||
public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
mouse = null;
|
||||
headset = null;
|
||||
|
||||
foreach (Bubble bubble in _bubbles)
|
||||
bubble.Draw(keyboard);
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
foreach (var bubble in _bubbles)
|
||||
bubble.Draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
@ -95,4 +108,4 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,4 +57,4 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
Smoothness = 25;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,7 +120,7 @@
|
||||
HorizontalAlignment="Right" Width="110" TickPlacement="None" TickFrequency="1"
|
||||
Value="{Binding Path=EffectSettings.MoveSpeed, Mode=TwoWay}" Minimum="1" Maximum="15"
|
||||
SmallChange="10" IsSnapToTickEnabled="True" />
|
||||
|
||||
|
||||
<!-- Smoothness -->
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Height="16" Margin="0,9,0,10">
|
||||
|
||||
@ -9,4 +9,4 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
events.Subscribe(this);
|
||||
|
||||
MainManager.EffectManager.EffectModels.Add(EffectModel);
|
||||
EffectSettings = ((BubblesModel)EffectModel).Settings;
|
||||
EffectSettings = ((BubblesModel) EffectModel).Settings;
|
||||
}
|
||||
|
||||
public void Handle(ActiveEffectChanged message)
|
||||
@ -22,4 +22,4 @@ namespace Artemis.Modules.Effects.Bubbles
|
||||
NotifyOfPropertyChange(() => EffectEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Headset;
|
||||
using Artemis.Profiles.Layers.Types.Mouse;
|
||||
|
||||
namespace Artemis.Modules.Effects.ProfilePreview
|
||||
{
|
||||
@ -32,10 +34,10 @@ namespace Artemis.Modules.Effects.ProfilePreview
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<ProfilePreviewDataModel>(DataModel, renderMice, renderHeadsets, true);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, true);
|
||||
}
|
||||
|
||||
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||
public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
mouse = null;
|
||||
@ -48,12 +50,30 @@ namespace Artemis.Modules.Effects.ProfilePreview
|
||||
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
|
||||
|
||||
// Render the keyboard layer-by-layer
|
||||
Profile?.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), true, true);
|
||||
// Render the first enabled mouse (will default to null if renderMice was false)
|
||||
mouse = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
|
||||
// Render the first enabled headset (will default to null if renderHeadsets was false)
|
||||
headset = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset),
|
||||
DataModel);
|
||||
var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
// Fill the bitmap's background with black to avoid trailing colors on some keyboards
|
||||
g.Clear(Color.Black);
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.MustDraw()), DataModel, keyboardRect, true, true);
|
||||
}
|
||||
|
||||
// Render the mouse layer-by-layer
|
||||
var smallRect = new Rect(0, 0, 40, 40);
|
||||
mouse = new Bitmap(40, 40);
|
||||
using (var g = Graphics.FromImage(mouse))
|
||||
{
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is MouseType), DataModel, smallRect,
|
||||
true, true);
|
||||
}
|
||||
|
||||
// Render the headset layer-by-layer
|
||||
headset = new Bitmap(40, 40);
|
||||
using (var g = Graphics.FromImage(headset))
|
||||
{
|
||||
Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is HeadsetType), DataModel, smallRect,
|
||||
true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,9 +7,8 @@ using Artemis.DeviceProviders.Corsair;
|
||||
using Artemis.DeviceProviders.Logitech.Utilities;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Modules.Effects.TypeWave
|
||||
{
|
||||
@ -46,8 +45,8 @@ namespace Artemis.Modules.Effects.TypeWave
|
||||
return;
|
||||
|
||||
_waves.Add(Settings.IsRandomColors
|
||||
? new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0, _randomColor)
|
||||
: new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0,
|
||||
? new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0, _randomColor)
|
||||
: new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0,
|
||||
ColorHelpers.ToDrawingColor(Settings.WaveColor)));
|
||||
}
|
||||
|
||||
@ -71,12 +70,12 @@ namespace Artemis.Modules.Effects.TypeWave
|
||||
// TODO: Get from settings
|
||||
var fps = 25;
|
||||
|
||||
_waves[i].Size += Settings.SpreadSpeed * KeyboardScale;
|
||||
_waves[i].Size += Settings.SpreadSpeed*KeyboardScale;
|
||||
|
||||
if (Settings.IsShiftColors)
|
||||
_waves[i].Color = ColorHelpers.ShiftColor(_waves[i].Color, Settings.ShiftColorSpeed);
|
||||
|
||||
var decreaseAmount = 255 / (Settings.TimeToLive / fps);
|
||||
var decreaseAmount = 255/(Settings.TimeToLive/fps);
|
||||
_waves[i].Color = Color.FromArgb(
|
||||
_waves[i].Color.A - decreaseAmount, _waves[i].Color.R,
|
||||
_waves[i].Color.G,
|
||||
@ -95,7 +94,7 @@ namespace Artemis.Modules.Effects.TypeWave
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
|
||||
public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
mouse = null;
|
||||
@ -111,7 +110,7 @@ namespace Artemis.Modules.Effects.TypeWave
|
||||
if (_waves[i].Size == 0)
|
||||
continue;
|
||||
var path = new GraphicsPath();
|
||||
path.AddEllipse(_waves[i].Point.X - _waves[i].Size / 2, _waves[i].Point.Y - _waves[i].Size / 2,
|
||||
path.AddEllipse(_waves[i].Point.X - _waves[i].Size/2, _waves[i].Point.Y - _waves[i].Size/2,
|
||||
_waves[i].Size, _waves[i].Size);
|
||||
|
||||
Color fillColor;
|
||||
@ -122,16 +121,19 @@ namespace Artemis.Modules.Effects.TypeWave
|
||||
|
||||
var pthGrBrush = new PathGradientBrush(path)
|
||||
{
|
||||
SurroundColors = new[] { _waves[i].Color },
|
||||
SurroundColors = new[] {_waves[i].Color},
|
||||
CenterColor = fillColor
|
||||
};
|
||||
|
||||
keyboard.FillPath(pthGrBrush, path);
|
||||
pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
g.FillPath(pthGrBrush, path);
|
||||
pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
|
||||
|
||||
keyboard.FillPath(pthGrBrush, path);
|
||||
keyboard.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size / 2,
|
||||
_waves[i].Point.Y - _waves[i].Size / 2, _waves[i].Size, _waves[i].Size);
|
||||
g.FillPath(pthGrBrush, path);
|
||||
g.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size/2,
|
||||
_waves[i].Point.Y - _waves[i].Size/2, _waves[i].Size, _waves[i].Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,16 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
public CpuDataModel Cpu { get; set; }
|
||||
public PerformanceDataModel Performance { get; set; }
|
||||
public Spotify Spotify { get; set; }
|
||||
public CurrentTime CurrentTime { get; set; }
|
||||
}
|
||||
|
||||
class CurrentTime
|
||||
{
|
||||
public int Hours24 { get; set; }
|
||||
public int Hours12 { get; set; }
|
||||
public int Minutes { get; set; }
|
||||
public int Seconds { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class CpuDataModel
|
||||
|
||||
@ -6,7 +6,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Ninject.Extensions.Logging;
|
||||
using SpotifyAPI.Local;
|
||||
|
||||
@ -16,7 +16,8 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
{
|
||||
[DllImport("psapi.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation, [In] int size);
|
||||
public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation,
|
||||
[In] int size);
|
||||
|
||||
public static long GetPhysicalAvailableMemoryInMiB()
|
||||
{
|
||||
@ -58,6 +59,8 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class WindowsProfileModel : EffectModel
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
@ -95,6 +98,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
var dataModel = (WindowsProfileDataModel) DataModel;
|
||||
UpdateCpu(dataModel);
|
||||
UpdateSpotify(dataModel);
|
||||
UpdateDay(dataModel);
|
||||
}
|
||||
|
||||
#region CPU
|
||||
@ -161,7 +165,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<WindowsProfileDataModel>(DataModel, renderMice, renderHeadsets, false);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, false);
|
||||
}
|
||||
|
||||
public static PerformanceCounter GetOverallPerformanceCounter()
|
||||
@ -190,6 +194,19 @@ namespace Artemis.Modules.Effects.WindowsProfile
|
||||
|
||||
#endregion
|
||||
|
||||
#region Current Time
|
||||
private void UpdateDay(WindowsProfileDataModel dataModel)
|
||||
{
|
||||
|
||||
var now = DateTime.Now;
|
||||
dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
|
||||
dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh"));
|
||||
dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm"));
|
||||
dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss"));
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Spotify
|
||||
|
||||
public void SetupSpotify()
|
||||
|
||||
@ -35,102 +35,6 @@ namespace Artemis.Modules.Games.CounterStrike {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string GameDirectory {
|
||||
get {
|
||||
return ((string)(this["GameDirectory"]));
|
||||
}
|
||||
set {
|
||||
this["GameDirectory"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool AmmoEnabled {
|
||||
get {
|
||||
return ((bool)(this["AmmoEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["AmmoEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FFFF2900")]
|
||||
public global::System.Windows.Media.Color AmmoMainColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["AmmoMainColor"]));
|
||||
}
|
||||
set {
|
||||
this["AmmoMainColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FF26F600")]
|
||||
public global::System.Windows.Media.Color AmmoSecondaryColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["AmmoSecondaryColor"]));
|
||||
}
|
||||
set {
|
||||
this["AmmoSecondaryColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool TeamColorEnabled {
|
||||
get {
|
||||
return ((bool)(this["TeamColorEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["TeamColorEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool FlashEnabled {
|
||||
get {
|
||||
return ((bool)(this["FlashEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["FlashEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool SmokeEnabled {
|
||||
get {
|
||||
return ((bool)(this["SmokeEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["SmokeEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool LowHpEnabled {
|
||||
get {
|
||||
return ((bool)(this["LowHpEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["LowHpEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
|
||||
@ -142,5 +46,17 @@ namespace Artemis.Modules.Games.CounterStrike {
|
||||
this["LastProfile"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string GameDirectory {
|
||||
get {
|
||||
return ((string)(this["GameDirectory"]));
|
||||
}
|
||||
set {
|
||||
this["GameDirectory"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||
GeneratedClassNamespace="Artemis.Modules.Games.CounterStrike" GeneratedClassName="CounterStrike">
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Artemis.Modules.Games.CounterStrike" GeneratedClassName="CounterStrike">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
||||
@ -13,26 +11,5 @@
|
||||
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="AmmoEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="AmmoMainColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FFFF2900</Value>
|
||||
</Setting>
|
||||
<Setting Name="AmmoSecondaryColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FF26F600</Value>
|
||||
</Setting>
|
||||
<Setting Name="TeamColorEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="FlashEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="SmokeEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="LowHpEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities.GameState;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject.Extensions.Logging;
|
||||
@ -66,7 +66,7 @@ namespace Artemis.Modules.Games.CounterStrike
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<CounterStrikeDataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models;
|
||||
|
||||
namespace Artemis.Modules.Games.CounterStrike
|
||||
{
|
||||
@ -12,29 +11,11 @@ namespace Artemis.Modules.Games.CounterStrike
|
||||
|
||||
public string GameDirectory { get; set; }
|
||||
|
||||
public bool AmmoEnabled { get; set; }
|
||||
public Color AmmoMainColor { get; set; }
|
||||
public Color AmmoSecondaryColor { get; set; }
|
||||
|
||||
public bool TeamColorEnabled { get; set; }
|
||||
public bool FlashEnabled { get; set; }
|
||||
public bool SmokeEnabled { get; set; }
|
||||
public bool LowHpEnabled { get; set; }
|
||||
|
||||
public sealed override void Load()
|
||||
{
|
||||
Enabled = CounterStrike.Default.Enabled;
|
||||
LastProfile = CounterStrike.Default.LastProfile;
|
||||
GameDirectory = CounterStrike.Default.GameDirectory;
|
||||
|
||||
AmmoEnabled = CounterStrike.Default.AmmoEnabled;
|
||||
AmmoMainColor = CounterStrike.Default.AmmoMainColor;
|
||||
AmmoSecondaryColor = CounterStrike.Default.AmmoSecondaryColor;
|
||||
|
||||
TeamColorEnabled = CounterStrike.Default.TeamColorEnabled;
|
||||
FlashEnabled = CounterStrike.Default.FlashEnabled;
|
||||
SmokeEnabled = CounterStrike.Default.SmokeEnabled;
|
||||
LowHpEnabled = CounterStrike.Default.LowHpEnabled;
|
||||
}
|
||||
|
||||
public sealed override void Save()
|
||||
@ -42,15 +23,6 @@ namespace Artemis.Modules.Games.CounterStrike
|
||||
CounterStrike.Default.Enabled = Enabled;
|
||||
CounterStrike.Default.GameDirectory = GameDirectory;
|
||||
|
||||
CounterStrike.Default.AmmoEnabled = AmmoEnabled;
|
||||
CounterStrike.Default.AmmoMainColor = AmmoMainColor;
|
||||
CounterStrike.Default.AmmoSecondaryColor = AmmoSecondaryColor;
|
||||
|
||||
CounterStrike.Default.TeamColorEnabled = TeamColorEnabled;
|
||||
CounterStrike.Default.FlashEnabled = FlashEnabled;
|
||||
CounterStrike.Default.SmokeEnabled = SmokeEnabled;
|
||||
CounterStrike.Default.LowHpEnabled = LowHpEnabled;
|
||||
|
||||
CounterStrike.Default.Save();
|
||||
}
|
||||
|
||||
@ -58,15 +30,6 @@ namespace Artemis.Modules.Games.CounterStrike
|
||||
{
|
||||
Enabled = true;
|
||||
GameDirectory = string.Empty;
|
||||
|
||||
AmmoEnabled = true;
|
||||
AmmoMainColor = Color.FromArgb(255, 38, 246, 0);
|
||||
AmmoSecondaryColor = Color.FromArgb(255, 255, 41, 0);
|
||||
|
||||
TeamColorEnabled = true;
|
||||
FlashEnabled = true;
|
||||
SmokeEnabled = true;
|
||||
LowHpEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs
generated
120
Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs
generated
@ -58,125 +58,5 @@ namespace Artemis.Modules.Games.Dota2 {
|
||||
this["GameDirectory"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool CanCastAbility {
|
||||
get {
|
||||
return ((bool)(this["CanCastAbility"]));
|
||||
}
|
||||
set {
|
||||
this["CanCastAbility"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool ShowHealth {
|
||||
get {
|
||||
return ((bool)(this["ShowHealth"]));
|
||||
}
|
||||
set {
|
||||
this["ShowHealth"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool ShowDayCycle {
|
||||
get {
|
||||
return ((bool)(this["ShowDayCycle"]));
|
||||
}
|
||||
set {
|
||||
this["ShowDayCycle"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool ShowMana {
|
||||
get {
|
||||
return ((bool)(this["ShowMana"]));
|
||||
}
|
||||
set {
|
||||
this["ShowMana"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool ShowEvents {
|
||||
get {
|
||||
return ((bool)(this["ShowEvents"]));
|
||||
}
|
||||
set {
|
||||
this["ShowEvents"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FFFF0000")]
|
||||
public global::System.Windows.Media.Color MainColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["MainColor"]));
|
||||
}
|
||||
set {
|
||||
this["MainColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FF0000FF")]
|
||||
public global::System.Windows.Media.Color ManaColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["ManaColor"]));
|
||||
}
|
||||
set {
|
||||
this["ManaColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
|
||||
public string KeyboardLayout {
|
||||
get {
|
||||
return ((string)(this["KeyboardLayout"]));
|
||||
}
|
||||
set {
|
||||
this["KeyboardLayout"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FF00FF00")]
|
||||
public global::System.Windows.Media.Color AbilityReadyColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["AbilityReadyColor"]));
|
||||
}
|
||||
set {
|
||||
this["AbilityReadyColor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#FF6A5ACD")]
|
||||
public global::System.Windows.Media.Color AbilityCooldownColor {
|
||||
get {
|
||||
return ((global::System.Windows.Media.Color)(this["AbilityCooldownColor"]));
|
||||
}
|
||||
set {
|
||||
this["AbilityCooldownColor"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||
GeneratedClassNamespace="Artemis.Modules.Games.Dota2" GeneratedClassName="Dota2">
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Artemis.Modules.Games.Dota2" GeneratedClassName="Dota2">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
|
||||
@ -13,35 +11,5 @@
|
||||
<Setting Name="GameDirectory" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="CanCastAbility" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowHealth" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowDayCycle" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowMana" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ShowEvents" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="MainColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FFFF0000</Value>
|
||||
</Setting>
|
||||
<Setting Name="ManaColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FF0000FF</Value>
|
||||
</Setting>
|
||||
<Setting Name="KeyboardLayout" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">Default</Value>
|
||||
</Setting>
|
||||
<Setting Name="AbilityReadyColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FF00FF00</Value>
|
||||
</Setting>
|
||||
<Setting Name="AbilityCooldownColor" Type="System.Windows.Media.Color" Scope="User">
|
||||
<Value Profile="(Default)">#FF6A5ACD</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities.GameState;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Artemis.Modules.Games.Dota2
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<Dota2DataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models;
|
||||
|
||||
namespace Artemis.Modules.Games.Dota2
|
||||
{
|
||||
@ -10,74 +9,28 @@ namespace Artemis.Modules.Games.Dota2
|
||||
Load();
|
||||
}
|
||||
|
||||
public string GameDirectory { get; set; }
|
||||
|
||||
public override void Load()
|
||||
|
||||
public sealed override void Load()
|
||||
{
|
||||
KeyboardLayout = Dota2.Default.KeyboardLayout;
|
||||
MainColor = Dota2.Default.MainColor;
|
||||
ManaColor = Dota2.Default.ManaColor;
|
||||
ShowHealth = Dota2.Default.ShowHealth;
|
||||
CanCastAbility = Dota2.Default.CanCastAbility;
|
||||
Enabled = Dota2.Default.Enabled;
|
||||
GameDirectory = Dota2.Default.GameDirectory;
|
||||
ShowDayCycle = Dota2.Default.ShowDayCycle;
|
||||
ShowMana = Dota2.Default.ShowMana;
|
||||
ShowEvents = Dota2.Default.ShowEvents;
|
||||
AbilityReadyColor = Dota2.Default.AbilityReadyColor;
|
||||
AbilityCooldownColor = Dota2.Default.AbilityCooldownColor;
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
public sealed override void Save()
|
||||
{
|
||||
Dota2.Default.Enabled = Enabled;
|
||||
Dota2.Default.LastProfile = LastProfile;
|
||||
Dota2.Default.GameDirectory = GameDirectory;
|
||||
|
||||
Dota2.Default.KeyboardLayout = KeyboardLayout;
|
||||
Dota2.Default.MainColor = MainColor;
|
||||
Dota2.Default.ManaColor = ManaColor;
|
||||
Dota2.Default.ShowDayCycle = ShowDayCycle;
|
||||
Dota2.Default.ShowHealth = ShowHealth;
|
||||
Dota2.Default.CanCastAbility = CanCastAbility;
|
||||
Dota2.Default.ShowMana = ShowMana;
|
||||
Dota2.Default.ShowEvents = ShowEvents;
|
||||
Dota2.Default.AbilityCooldownColor = AbilityCooldownColor;
|
||||
Dota2.Default.AbilityReadyColor = AbilityReadyColor;
|
||||
|
||||
Dota2.Default.Save();
|
||||
}
|
||||
|
||||
public override void ToDefault()
|
||||
public sealed override void ToDefault()
|
||||
{
|
||||
Enabled = true;
|
||||
GameDirectory = string.Empty;
|
||||
|
||||
KeyboardLayout = "Default";
|
||||
MainColor = Color.FromArgb(255, 255, 0, 0);
|
||||
ManaColor = Color.FromArgb(255, 0, 0, 255);
|
||||
AbilityCooldownColor = Color.FromArgb(255, 106, 90, 205);
|
||||
AbilityReadyColor = Color.FromArgb(255, 0, 255, 0);
|
||||
ShowHealth = true;
|
||||
CanCastAbility = true;
|
||||
ShowDayCycle = true;
|
||||
ShowMana = true;
|
||||
ShowEvents = true;
|
||||
}
|
||||
|
||||
#region Variables
|
||||
|
||||
public string GameDirectory { get; set; }
|
||||
public bool CanCastAbility { get; set; }
|
||||
public bool ShowHealth { get; set; }
|
||||
public bool ShowDayCycle { get; set; }
|
||||
public bool ShowMana { get; set; }
|
||||
public bool ShowEvents { get; set; }
|
||||
public Color MainColor { get; set; }
|
||||
public Color ManaColor { get; set; }
|
||||
public string KeyboardLayout { get; set; }
|
||||
public Color AbilityCooldownColor { get; set; }
|
||||
public Color AbilityReadyColor { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -9,13 +9,16 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
public bool UltimateReady { get; set; }
|
||||
public bool Ability1Ready { get; set; }
|
||||
public bool Ability2Ready { get; set; }
|
||||
public bool UltimateUsed { get; set; }
|
||||
public bool CanChangeHero { get; set; }
|
||||
}
|
||||
|
||||
public enum OverwatchStatus
|
||||
{
|
||||
Unkown,
|
||||
Unknown,
|
||||
InMainMenu,
|
||||
InGame
|
||||
InGame,
|
||||
InCharacterSelect
|
||||
}
|
||||
|
||||
public enum OverwatchCharacter
|
||||
|
||||
@ -1,21 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.DataReaders;
|
||||
using Caliburn.Micro;
|
||||
using Color = System.Windows.Media.Color;
|
||||
|
||||
namespace Artemis.Modules.Games.Overwatch
|
||||
{
|
||||
public class OverwatchModel : GameModel
|
||||
{
|
||||
private readonly IEventAggregator _events;
|
||||
private DateTime _characterChange;
|
||||
// Using sticky values on these since they can cause flickering
|
||||
private StickyValue<OverwatchStatus> _stickyStatus;
|
||||
private StickyValue<bool> _stickyUltimateReady;
|
||||
private StickyValue<bool> _stickyUltimateUsed;
|
||||
private DateTime _ultimateReady;
|
||||
private DateTime _ultimateUsed;
|
||||
|
||||
public OverwatchModel(IEventAggregator events, MainManager mainManager, OverwatchSettings settings)
|
||||
: base(mainManager, settings, new OverwatchDataModel())
|
||||
@ -27,7 +34,7 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
Enabled = Settings.Enabled;
|
||||
Initialized = false;
|
||||
|
||||
MmfReader = new MmfReader("overwatchMmf");
|
||||
MmfReader = new MmfReader("overwatchMmf", MainManager.Logger);
|
||||
LoadOverwatchCharacters();
|
||||
}
|
||||
|
||||
@ -46,102 +53,184 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
{
|
||||
OverwatchCharacters = new List<CharacterColor>
|
||||
{
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Genji, Color = Color.FromRgb(13, 61, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mccree, Color = Color.FromRgb(24, 1, 1)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Pharah, Color = Color.FromRgb(0, 6, 32)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Reaper, Color = Color.FromRgb(7, 0, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Soldier76, Color = Color.FromRgb(3, 5, 11)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Tracer, Color = Color.FromRgb(46, 12, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Bastion, Color = Color.FromRgb(6, 10, 5)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Hanzo, Color = Color.FromRgb(28, 24, 8)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Junkrat, Color = Color.FromRgb(59, 28, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mei, Color = Color.FromRgb(3, 20, 55)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Torbjörn, Color = Color.FromRgb(31, 4, 3)},
|
||||
new CharacterColor
|
||||
{
|
||||
OverwatchCharacter = OverwatchCharacter.Widowmaker,
|
||||
Color = Color.FromRgb(16, 3, 17)
|
||||
},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Dva, Color = Color.FromRgb(62, 12, 32)},
|
||||
new CharacterColor
|
||||
{
|
||||
OverwatchCharacter = OverwatchCharacter.Reinhardt,
|
||||
Color = Color.FromRgb(12, 16, 16)
|
||||
},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Roadhog, Color = Color.FromRgb(26, 10, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Winston, Color = Color.FromRgb(17, 18, 26)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zarya, Color = Color.FromRgb(58, 7, 24)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Lúcio, Color = Color.FromRgb(8, 35, 0)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mercy, Color = Color.FromRgb(60, 56, 26)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Symmetra, Color = Color.FromRgb(11, 29, 37)},
|
||||
new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(62, 54, 6)}
|
||||
new CharacterColor {Character = OverwatchCharacter.Genji, Color = Color.FromRgb(55, 245, 0)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Mccree, Color = Color.FromRgb(97, 5, 5)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Pharah, Color = Color.FromRgb(0, 24, 128)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Reaper, Color = Color.FromRgb(28, 0, 2)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Soldier76, Color = Color.FromRgb(14, 21, 45)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Tracer, Color = Color.FromRgb(186, 49, 0)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Bastion, Color = Color.FromRgb(26, 43, 20)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Hanzo, Color = Color.FromRgb(113, 99, 33)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Junkrat, Color = Color.FromRgb(237, 113, 2)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Mei, Color = Color.FromRgb(15, 82, 222)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Torbjörn, Color = Color.FromRgb(125, 18, 12)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Widowmaker, Color = Color.FromRgb(65, 12, 70)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Dva, Color = Color.FromRgb(248, 48, 129)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Reinhardt, Color = Color.FromRgb(51, 65, 66)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Roadhog, Color = Color.FromRgb(107, 40, 2)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Winston, Color = Color.FromRgb(70, 73, 107)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Zarya, Color = Color.FromRgb(235, 28, 97)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Lúcio, Color = Color.FromRgb(34, 142, 2)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Mercy, Color = Color.FromRgb(243, 226, 106)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Symmetra, Color = Color.FromRgb(46, 116, 148)},
|
||||
new CharacterColor {Character = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(248, 218, 26)}
|
||||
};
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Initialized = false;
|
||||
}
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
_stickyStatus = new StickyValue<OverwatchStatus>(300);
|
||||
_stickyUltimateReady = new StickyValue<bool>(350);
|
||||
_stickyUltimateUsed = new StickyValue<bool>(350);
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_stickyStatus.Dispose();
|
||||
_stickyUltimateReady.Dispose();
|
||||
_stickyUltimateUsed.Dispose();
|
||||
Initialized = false;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateOverwatch();
|
||||
ApplyStickyValues();
|
||||
}
|
||||
|
||||
private void ApplyStickyValues()
|
||||
{
|
||||
var gameDataModel = (OverwatchDataModel) DataModel;
|
||||
gameDataModel.Status = _stickyStatus.Value;
|
||||
gameDataModel.UltimateReady = _stickyUltimateReady.Value;
|
||||
gameDataModel.UltimateUsed = _stickyUltimateUsed.Value;
|
||||
}
|
||||
|
||||
public void UpdateOverwatch()
|
||||
{
|
||||
var gameDataModel = (OverwatchDataModel) DataModel;
|
||||
var colors = MmfReader.GetColorArray();
|
||||
if (colors == null)
|
||||
return;
|
||||
|
||||
var bitmap = new Bitmap(22, 6);
|
||||
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
{
|
||||
for (var y = 0; y < 6; y++)
|
||||
{
|
||||
for (var x = 0; x < 22; x++)
|
||||
{
|
||||
g.DrawRectangle(new Pen(ColorHelpers.ToDrawingColor(colors[y, x])), y, x, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||
_events.PublishOnUIThread(new RazerColorArrayChanged(colors));
|
||||
//MainManager.Logger.Trace("DataModel: \r\n{0}",
|
||||
// JsonConvert.SerializeObject(gameDataModel, Formatting.Indented));
|
||||
|
||||
// Determine general game state
|
||||
gameDataModel.Status = colors[0, 0].Equals(Color.FromRgb(55, 30, 0))
|
||||
? OverwatchStatus.InMainMenu
|
||||
: OverwatchStatus.Unkown;
|
||||
ParseGameSate(gameDataModel, colors);
|
||||
|
||||
if (gameDataModel.Status == OverwatchStatus.InMainMenu)
|
||||
// Parse the lighting
|
||||
var characterMatch = ParseCharacter(gameDataModel, colors);
|
||||
|
||||
// Ult can't possibly be ready within 2 seconds of changing, this avoids false positives.
|
||||
// Filtering on ultReady and ultUsed removes false positives from the native ultimate effects
|
||||
// The control keys don't show during character select, so don't continue on those either.
|
||||
if (_characterChange.AddSeconds(2) >= DateTime.Now ||
|
||||
_ultimateUsed.AddSeconds(2) >= DateTime.Now ||
|
||||
_ultimateReady.AddSeconds(2) >= DateTime.Now ||
|
||||
_stickyStatus.Value == OverwatchStatus.InCharacterSelect)
|
||||
return;
|
||||
|
||||
// If ingame, look for a character
|
||||
var characterMatch = OverwatchCharacters.FirstOrDefault(c => c.Color == colors[0, 0]);
|
||||
if (characterMatch.OverwatchCharacter == OverwatchCharacter.None)
|
||||
ParseSpecialKeys(gameDataModel, characterMatch, colors);
|
||||
ParseAbilities(gameDataModel, colors);
|
||||
}
|
||||
|
||||
private void ParseGameSate(OverwatchDataModel gameDataModel, Color[,] colors)
|
||||
{
|
||||
if (_ultimateUsed.AddSeconds(5) >= DateTime.Now)
|
||||
return;
|
||||
|
||||
gameDataModel.Status = OverwatchStatus.InGame;
|
||||
gameDataModel.Character = characterMatch.OverwatchCharacter;
|
||||
if (colors[0, 0].Equals(Color.FromRgb(55, 30, 0)))
|
||||
_stickyStatus.Value = OverwatchStatus.InMainMenu;
|
||||
|
||||
if (_stickyStatus.Value != OverwatchStatus.InMainMenu)
|
||||
return;
|
||||
|
||||
gameDataModel.Character = OverwatchCharacter.None;
|
||||
gameDataModel.Ability1Ready = false;
|
||||
gameDataModel.Ability2Ready = false;
|
||||
_stickyUltimateReady.Value = false;
|
||||
_stickyUltimateUsed.Value = false;
|
||||
}
|
||||
|
||||
private CharacterColor? ParseCharacter(OverwatchDataModel gameDataModel, Color[,] colors)
|
||||
{
|
||||
var characterMatch = OverwatchCharacters.FirstOrDefault(c => c.Color == colors[0, 20]);
|
||||
// If a new character was chosen, let the other methods know
|
||||
if (characterMatch.Character != gameDataModel.Character)
|
||||
_characterChange = DateTime.Now;
|
||||
|
||||
// If no character was found, this method shouldn't continue
|
||||
if (characterMatch.Character == OverwatchCharacter.None)
|
||||
return characterMatch;
|
||||
|
||||
// If WASD isn't orange (any of them will do), player is in character select
|
||||
_stickyStatus.Value = ControlsShown(colors) ? OverwatchStatus.InGame : OverwatchStatus.InCharacterSelect;
|
||||
|
||||
// Update the datamodel
|
||||
gameDataModel.Character = characterMatch.Character;
|
||||
return characterMatch;
|
||||
}
|
||||
|
||||
private bool ControlsShown(Color[,] colors)
|
||||
{
|
||||
var keyColor = Color.FromRgb(222, 153, 0);
|
||||
return colors[2, 3] == keyColor || colors[3, 2] == keyColor ||
|
||||
colors[3, 3] == keyColor || colors[3, 4] == keyColor;
|
||||
}
|
||||
|
||||
private void ParseSpecialKeys(OverwatchDataModel gameDataModel, CharacterColor? characterMatch, Color[,] colors)
|
||||
{
|
||||
if (characterMatch == null || characterMatch.Value.Character == OverwatchCharacter.None)
|
||||
return;
|
||||
|
||||
// Ability1 is ready when LShift is lid
|
||||
gameDataModel.Ability1Ready = colors[4, 1].Equals(Color.FromRgb(4, 141, 144));
|
||||
// Ability2 is ready when E is lid
|
||||
gameDataModel.Ability2Ready = colors[2, 4].Equals(Color.FromRgb(4, 141, 144));
|
||||
// Ultimate is ready when Q is blinking
|
||||
gameDataModel.UltimateReady = !characterMatch.Color.Equals(colors[2, 2]);
|
||||
var charCol = characterMatch.Value.Color;
|
||||
var backlidColor = Color.FromRgb((byte) (charCol.R*0.25), (byte) (charCol.G*0.25), (byte) (charCol.B*0.25));
|
||||
var ultReady = !backlidColor.Equals(colors[2, 2]);
|
||||
|
||||
if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
|
||||
{
|
||||
// Player can change hero if H is blinking
|
||||
gameDataModel.CanChangeHero = !colors[3, 7].Equals(backlidColor);
|
||||
|
||||
if (!_stickyUltimateReady.Value && ultReady && ControlsShown(colors))
|
||||
{
|
||||
_ultimateReady = DateTime.Now;
|
||||
_stickyUltimateReady.Value = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If ult no longer ready but it was ready before, it was used.
|
||||
if (_stickyUltimateReady.Value && !ultReady)
|
||||
{
|
||||
_stickyUltimateReady.Value = false;
|
||||
if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
|
||||
_ultimateUsed = DateTime.Now;
|
||||
}
|
||||
|
||||
// UltimateUsed is true for 10 seconds after ultimate went on cooldown
|
||||
if (_ultimateUsed != DateTime.MinValue)
|
||||
_stickyUltimateUsed.Value = _ultimateUsed.AddSeconds(10) >= DateTime.Now;
|
||||
}
|
||||
|
||||
private void ParseAbilities(OverwatchDataModel gameDataModel, Color[,] colors)
|
||||
{
|
||||
gameDataModel.Ability1Ready = colors[4, 1].Equals(Color.FromRgb(4, 141, 144));
|
||||
gameDataModel.Ability2Ready = colors[2, 4].Equals(Color.FromRgb(4, 141, 144));
|
||||
}
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<OverwatchDataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
|
||||
public struct CharacterColor
|
||||
{
|
||||
public OverwatchCharacter OverwatchCharacter { get; set; }
|
||||
public OverwatchCharacter Character { get; set; }
|
||||
public Color Color { get; set; }
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.Memory;
|
||||
@ -66,11 +66,20 @@ namespace Artemis.Modules.Games.RocketLeague
|
||||
((RocketLeagueDataModel) DataModel).Boost = 0;
|
||||
if (((RocketLeagueDataModel) DataModel).Boost > 100)
|
||||
((RocketLeagueDataModel) DataModel).Boost = 100;
|
||||
|
||||
if (DateTime.Now.AddSeconds(-2) <= LastTrace)
|
||||
return;
|
||||
|
||||
MainManager.Logger.Trace("Offsets as JSON: \r\n{0}",
|
||||
JsonConvert.SerializeObject(_pointer.GameAddresses, Formatting.Indented));
|
||||
MainManager.Logger.Trace("RL specific offsets: {0}", offsets);
|
||||
MainManager.Logger.Trace("Boost address: {0}", boostAddress);
|
||||
MainManager.Logger.Trace("Boost float: {0}", boostFloat);
|
||||
}
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<RocketLeagueDataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.LogitechDll;
|
||||
|
||||
@ -131,7 +131,7 @@ namespace Artemis.Modules.Games.TheDivision
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<TheDivisionDataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Modules.Games.Witcher3
|
||||
{
|
||||
public class Witcher3Model : GameModel
|
||||
{
|
||||
private readonly Stopwatch _updateSw;
|
||||
private readonly Regex _configRegex;
|
||||
private readonly Stopwatch _updateSw;
|
||||
private string _witcherSettings;
|
||||
|
||||
public Witcher3Model(MainManager mainManager, Witcher3Settings settings)
|
||||
@ -139,7 +138,7 @@ namespace Artemis.Modules.Games.Witcher3
|
||||
|
||||
public override List<LayerModel> GetRenderLayers(bool renderMice, bool renderHeadsets)
|
||||
{
|
||||
return Profile.GetRenderLayers<Witcher3DataModel>(DataModel, renderMice, renderHeadsets);
|
||||
return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using NAudio.CoreAudioApi;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Artemis.Modules.Overlays.VolumeDisplay
|
||||
{
|
||||
@ -46,10 +45,10 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
|
||||
if (VolumeDisplay.Ttl < 1)
|
||||
return;
|
||||
|
||||
var decreaseAmount = 500 / fps;
|
||||
var decreaseAmount = 500/fps;
|
||||
VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount;
|
||||
if (VolumeDisplay.Ttl < 128)
|
||||
VolumeDisplay.Transparancy = (byte)(VolumeDisplay.Transparancy - 20);
|
||||
VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20);
|
||||
|
||||
try
|
||||
{
|
||||
@ -57,7 +56,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
|
||||
var volumeFloat =
|
||||
enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console)
|
||||
.AudioEndpointVolume.MasterVolumeLevelScalar;
|
||||
VolumeDisplay.Volume = (int)(volumeFloat * 100);
|
||||
VolumeDisplay.Volume = (int) (volumeFloat*100);
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
@ -78,11 +77,16 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
|
||||
VolumeDisplay.Transparancy = 255;
|
||||
}
|
||||
|
||||
public override void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
|
||||
public override void RenderOverlay(Bitmap keyboard, ref Bitmap mouse, ref Bitmap headset, bool renderMice,
|
||||
bool renderHeadsets)
|
||||
{
|
||||
if (MainManager.DeviceManager.ActiveKeyboard != null && VolumeDisplay != null && VolumeDisplay.Ttl >= 1)
|
||||
VolumeDisplay.Draw(keyboard);
|
||||
if (MainManager.DeviceManager.ActiveKeyboard == null || VolumeDisplay == null || VolumeDisplay.Ttl < 1)
|
||||
return;
|
||||
|
||||
using (var g = Graphics.FromImage(keyboard))
|
||||
{
|
||||
VolumeDisplay.Draw(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs
Normal file
61
Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class GrowAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Grow";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed/2.5;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
// Take an offset of 4 to allow layers to slightly leave their bounds
|
||||
var progress = (6.0 - props.AnimationProgress)*10.0;
|
||||
if (progress < 0)
|
||||
{
|
||||
// Can't meddle with the original brush because it's frozen.
|
||||
var brush = applied.Brush.Clone();
|
||||
brush.Opacity = 1 + 0.025*progress;
|
||||
if (brush.Opacity < 0)
|
||||
brush.Opacity = 0;
|
||||
if (brush.Opacity > 1)
|
||||
brush.Opacity = 1;
|
||||
applied.Brush = brush;
|
||||
}
|
||||
rect.Inflate(-rect.Width/100.0*progress, -rect.Height/100.0*progress);
|
||||
clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, rect);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 10;
|
||||
}
|
||||
}
|
||||
24
Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs
Normal file
24
Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class NoneAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "None";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
Normal file
50
Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class PulseAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Pulse";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed/2;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
// Can't meddle with the original brush because it's frozen.
|
||||
var brush = applied.Brush.Clone();
|
||||
brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2);
|
||||
applied.Brush = brush;
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, rect);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 2;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class SlideDownAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Slide down";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed*2;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||
var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, s1);
|
||||
c.DrawRectangle(applied.Brush, null, s2);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer)
|
||||
{
|
||||
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class SlideLeftAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Slide left";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed*2;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y),
|
||||
new Size(rect.Width + 0.05, rect.Height));
|
||||
var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, s1);
|
||||
c.DrawRectangle(applied.Brush, null, s2);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer)
|
||||
{
|
||||
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class SlideRightAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Slide right";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed*2;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
|
||||
var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height));
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, s1);
|
||||
c.DrawRectangle(applied.Brush, null, s2);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer)
|
||||
{
|
||||
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Animations
|
||||
{
|
||||
public class SlideUpAnimation : ILayerAnimation
|
||||
{
|
||||
public string Name { get; } = "Slide up";
|
||||
|
||||
public void Update(LayerModel layerModel, bool updateAnimations)
|
||||
{
|
||||
var progress = layerModel.Properties.AnimationProgress;
|
||||
if (MustExpire(layerModel))
|
||||
progress = 0;
|
||||
progress = progress + layerModel.Properties.AnimationSpeed*2;
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
layerModel.Properties.AnimationProgress = progress;
|
||||
}
|
||||
|
||||
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||
var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, s1);
|
||||
c.DrawRectangle(applied.Brush, null, s2);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public bool MustExpire(LayerModel layer)
|
||||
{
|
||||
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
using System.Linq;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Conditions
|
||||
{
|
||||
public class DataModelCondition : ILayerCondition
|
||||
{
|
||||
public bool ConditionsMet(LayerModel layer, IDataModel dataModel)
|
||||
{
|
||||
return layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
Normal file
21
Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Linq;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Conditions
|
||||
{
|
||||
public class EventCondition : ILayerCondition
|
||||
{
|
||||
public bool ConditionsMet(LayerModel layer, IDataModel dataModel)
|
||||
{
|
||||
var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
|
||||
layer.EventProperties.Update(layer, conditionsMet);
|
||||
|
||||
if (conditionsMet && layer.EventProperties.MustTrigger)
|
||||
layer.EventProperties.TriggerEvent(layer);
|
||||
|
||||
return conditionsMet && layer.EventProperties.MustDraw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using System.Windows.Media;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Interfaces
|
||||
{
|
||||
public interface ILayerAnimation
|
||||
{
|
||||
string Name { get; }
|
||||
void Update(LayerModel layerModel, bool updateAnimations);
|
||||
void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c);
|
||||
bool MustExpire(LayerModel layer);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Interfaces
|
||||
{
|
||||
public interface ILayerCondition
|
||||
{
|
||||
bool ConditionsMet(LayerModel layer, IDataModel dataModel);
|
||||
}
|
||||
}
|
||||
57
Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs
Normal file
57
Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Interfaces
|
||||
{
|
||||
public interface ILayerType
|
||||
{
|
||||
/// <summary>
|
||||
/// Layer type name
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether this type must be drawn on the keyboard/the editor or not
|
||||
/// </summary>
|
||||
bool MustDraw { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The the thumbnail for this layer type
|
||||
/// </summary>
|
||||
/// <param name="layer">The layer to draw the thumbnail for</param>
|
||||
ImageSource DrawThumbnail(LayerModel layer);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the layer
|
||||
/// </summary>
|
||||
/// <param name="layer">The layer to draw</param>
|
||||
/// <param name="c">The drawing context to draw with</param>
|
||||
void Draw(LayerModel layer, DrawingContext c);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the provided layer layerModel according to this type
|
||||
/// </summary>
|
||||
/// <param name="layerModel">The layerModel to apply to</param>
|
||||
/// <param name="dataModel">The datamodel to base the layer on</param>
|
||||
/// <param name="isPreview">Set to true if previewing this layer</param>
|
||||
void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false);
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the layer's properties to accommodate this layerType
|
||||
/// </summary>
|
||||
/// <param name="layerModel"></param>
|
||||
void SetupProperties(LayerModel layerModel);
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a viewmodel to accomodate this layerType
|
||||
/// </summary>
|
||||
/// <param name="layerPropertiesViewModel">The current viewmodel</param>
|
||||
/// <param name="layerAnimations"></param>
|
||||
/// <param name="dataModel">The datamodel to use in the new viewmodel</param>
|
||||
/// <param name="proposedLayer">The layer to use in the new viewmodel</param>
|
||||
LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel, List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer);
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
using System.ComponentModel;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Utilities;
|
||||
using static System.Decimal;
|
||||
|
||||
namespace Artemis.Models.Profiles.Properties
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class DynamicPropertiesModel
|
||||
{
|
||||
@ -37,31 +36,31 @@ namespace Artemis.Models.Profiles.Properties
|
||||
/// </summary>
|
||||
public LayerPropertyOptions LayerPropertyOptions { get; set; }
|
||||
|
||||
internal void ApplyProperty(IDataModel dataModel, ref AppliedProperties properties)
|
||||
internal void ApplyProperty(IDataModel dataModel, LayerPropertiesModel properties)
|
||||
{
|
||||
if (LayerPropertyType == LayerPropertyType.PercentageOf)
|
||||
ApplyPercentageOf(dataModel, ref properties, PercentageSource);
|
||||
ApplyPercentageOf(dataModel, properties, PercentageSource);
|
||||
if (LayerPropertyType == LayerPropertyType.PercentageOfProperty)
|
||||
ApplyPercentageOfProperty(dataModel, ref properties);
|
||||
ApplyPercentageOfProperty(dataModel, properties);
|
||||
}
|
||||
|
||||
private void ApplyPercentageOf(IDataModel dataModel, ref AppliedProperties properties, double src)
|
||||
private void ApplyPercentageOf(IDataModel dataModel, LayerPropertiesModel properties, double src)
|
||||
{
|
||||
if (GameProperty == null)
|
||||
return;
|
||||
|
||||
var gameProperty = dataModel.GetPropValue<int>(GameProperty);
|
||||
var percentage = ToDouble(gameProperty)/src;
|
||||
var percentage = decimal.ToDouble(gameProperty)/src;
|
||||
|
||||
if (LayerProperty == "Width")
|
||||
ApplyWidth(ref properties, percentage);
|
||||
ApplyWidth(properties, percentage);
|
||||
else if (LayerProperty == "Height")
|
||||
ApplyHeight(ref properties, percentage);
|
||||
ApplyHeight(properties, percentage);
|
||||
else if (LayerProperty == "Opacity")
|
||||
ApplyOpacity(ref properties, percentage);
|
||||
ApplyOpacity(properties, percentage);
|
||||
}
|
||||
|
||||
private void ApplyWidth(ref AppliedProperties properties, double percentage)
|
||||
private void ApplyWidth(LayerPropertiesModel properties, double percentage)
|
||||
{
|
||||
var newWidth = percentage*properties.Width;
|
||||
var difference = properties.Width - newWidth;
|
||||
@ -72,7 +71,7 @@ namespace Artemis.Models.Profiles.Properties
|
||||
properties.X = properties.X + difference;
|
||||
}
|
||||
|
||||
private void ApplyHeight(ref AppliedProperties properties, double percentage)
|
||||
private void ApplyHeight(LayerPropertiesModel properties, double percentage)
|
||||
{
|
||||
var newHeight = percentage*properties.Height;
|
||||
var difference = properties.Height - newHeight;
|
||||
@ -82,7 +81,7 @@ namespace Artemis.Models.Profiles.Properties
|
||||
properties.Y = properties.Y + difference;
|
||||
}
|
||||
|
||||
private void ApplyOpacity(ref AppliedProperties properties, double percentage)
|
||||
private void ApplyOpacity(LayerPropertiesModel properties, double percentage)
|
||||
{
|
||||
properties.Opacity = percentage*properties.Opacity;
|
||||
if (properties.Opacity < 0.0)
|
||||
@ -93,12 +92,16 @@ namespace Artemis.Models.Profiles.Properties
|
||||
// Apply the inverse/decrease option
|
||||
if (LayerPropertyOptions == LayerPropertyOptions.Decrease)
|
||||
properties.Opacity = 1.0 - properties.Opacity;
|
||||
|
||||
var brush = properties.Brush.Clone();
|
||||
brush.Opacity = properties.Opacity;
|
||||
properties.Brush = brush;
|
||||
}
|
||||
|
||||
private void ApplyPercentageOfProperty(IDataModel dataModel, ref AppliedProperties properties)
|
||||
private void ApplyPercentageOfProperty(IDataModel dataModel, LayerPropertiesModel properties)
|
||||
{
|
||||
var value = dataModel.GetPropValue<int>(PercentageProperty);
|
||||
ApplyPercentageOf(dataModel, ref properties, value);
|
||||
ApplyPercentageOf(dataModel, properties, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public abstract class EventPropertiesModel
|
||||
{
|
||||
public ExpirationType ExpirationType { get; set; }
|
||||
public TimeSpan Length { get; set; }
|
||||
public TimeSpan TriggerDelay { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool MustTrigger { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime AnimationStart { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool MustDraw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resets the event's properties and triggers it
|
||||
/// </summary>
|
||||
public abstract void TriggerEvent(LayerModel layer);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the event should stop
|
||||
/// </summary>
|
||||
/// <param name="layer"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool MustStop(LayerModel layer);
|
||||
|
||||
// Called every frame, if parent conditions met.
|
||||
public void Update(LayerModel layerModel, bool conditionsMet)
|
||||
{
|
||||
if (MustStop(layerModel))
|
||||
MustDraw = false;
|
||||
|
||||
if (!conditionsMet)
|
||||
MustTrigger = true;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ExpirationType
|
||||
{
|
||||
Time,
|
||||
Animation
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Profiles.Layers.Types.KeyboardGif;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class KeyboardEventPropertiesModel : EventPropertiesModel
|
||||
{
|
||||
public override void TriggerEvent(LayerModel layer)
|
||||
{
|
||||
var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
|
||||
if (keyboardProperties == null)
|
||||
throw new ArgumentException("Layer's properties cannot be null " +
|
||||
"and must be of type KeyboardPropertiesModel");
|
||||
if (!MustTrigger)
|
||||
return;
|
||||
|
||||
MustTrigger = false;
|
||||
MustDraw = true;
|
||||
keyboardProperties.AnimationProgress = 0.0;
|
||||
if (layer.GifImage != null)
|
||||
layer.GifImage.CurrentFrame = 0;
|
||||
}
|
||||
|
||||
public override bool MustStop(LayerModel layer)
|
||||
{
|
||||
var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
|
||||
if (keyboardProperties == null)
|
||||
throw new ArgumentException("Layer's properties cannot be null " +
|
||||
"and must be of type KeyboardPropertiesModel");
|
||||
|
||||
switch (ExpirationType)
|
||||
{
|
||||
case ExpirationType.Time:
|
||||
if (AnimationStart == DateTime.MinValue)
|
||||
return false;
|
||||
return DateTime.Now - Length > AnimationStart;
|
||||
case ExpirationType.Animation:
|
||||
if (layer.LayerType is KeyboardGifType)
|
||||
return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1;
|
||||
return layer.LayerAnimation == null || layer.LayerAnimation.MustExpire(layer);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,58 +1,58 @@
|
||||
using System;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Utilities;
|
||||
using DynamicExpresso;
|
||||
|
||||
namespace Artemis.Models.Profiles
|
||||
{
|
||||
public class LayerConditionModel
|
||||
{
|
||||
private readonly Interpreter _interpreter;
|
||||
|
||||
public LayerConditionModel()
|
||||
{
|
||||
_interpreter = new Interpreter();
|
||||
}
|
||||
|
||||
public string Field { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string Operator { get; set; }
|
||||
public string Type { get; set; }
|
||||
|
||||
public bool ConditionMet<T>(IDataModel subject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
|
||||
return false;
|
||||
|
||||
var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
|
||||
if (inspect == null)
|
||||
return false;
|
||||
|
||||
// Put the subject in a list, allowing Dynamic Linq to be used.
|
||||
if (Type == "String")
|
||||
{
|
||||
return _interpreter.Eval<bool>($"subject.{Field}.ToLower() {Operator} value",
|
||||
new Parameter("subject", typeof(T), subject),
|
||||
new Parameter("value", Value.ToLower()));
|
||||
}
|
||||
|
||||
Parameter rightParam = null;
|
||||
switch (Type)
|
||||
{
|
||||
case "Enum":
|
||||
var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType();
|
||||
rightParam = new Parameter("value", Enum.Parse(enumType, Value));
|
||||
break;
|
||||
case "Boolean":
|
||||
rightParam = new Parameter("value", bool.Parse(Value));
|
||||
break;
|
||||
case "Int32":
|
||||
rightParam = new Parameter("value", int.Parse(Value));
|
||||
break;
|
||||
}
|
||||
|
||||
return _interpreter.Eval<bool>($"subject.{Field} {Operator} value",
|
||||
new Parameter("subject", typeof(T), subject), rightParam);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Utilities;
|
||||
using DynamicExpresso;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class LayerConditionModel
|
||||
{
|
||||
private readonly Interpreter _interpreter;
|
||||
|
||||
public LayerConditionModel()
|
||||
{
|
||||
_interpreter = new Interpreter();
|
||||
}
|
||||
|
||||
public string Field { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string Operator { get; set; }
|
||||
public string Type { get; set; }
|
||||
|
||||
public bool ConditionMet(IDataModel subject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
|
||||
return false;
|
||||
|
||||
var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
|
||||
if (inspect == null)
|
||||
return false;
|
||||
|
||||
// Put the subject in a list, allowing Dynamic Linq to be used.
|
||||
if (Type == "String")
|
||||
{
|
||||
return _interpreter.Eval<bool>($"subject.{Field}.ToLower() {Operator} value",
|
||||
new Parameter("subject", subject.GetType(), subject),
|
||||
new Parameter("value", Value.ToLower()));
|
||||
}
|
||||
|
||||
Parameter rightParam = null;
|
||||
switch (Type)
|
||||
{
|
||||
case "Enum":
|
||||
var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType();
|
||||
rightParam = new Parameter("value", Enum.Parse(enumType, Value));
|
||||
break;
|
||||
case "Boolean":
|
||||
rightParam = new Parameter("value", bool.Parse(Value));
|
||||
break;
|
||||
case "Int32":
|
||||
rightParam = new Parameter("value", int.Parse(Value));
|
||||
break;
|
||||
}
|
||||
|
||||
return _interpreter.Eval<bool>($"subject.{Field} {Operator} value",
|
||||
new Parameter("subject", subject.GetType(), subject), rightParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,276 +1,259 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.Layers;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
|
||||
namespace Artemis.Models.Profiles
|
||||
{
|
||||
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
||||
{
|
||||
public LayerModel()
|
||||
{
|
||||
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public int Order { get; set; }
|
||||
public LayerType LayerType { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool Expanded { get; set; }
|
||||
public LayerPropertiesModel Properties { get; set; }
|
||||
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
||||
|
||||
[XmlIgnore]
|
||||
public ImageSource LayerImage => Drawer.DrawThumbnail(this);
|
||||
|
||||
[XmlIgnore]
|
||||
public LayerModel Parent { get; internal set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public ProfileModel Profile { get; internal set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public GifImage GifImage { get; set; }
|
||||
|
||||
public bool ConditionsMet<T>(IDataModel dataModel)
|
||||
{
|
||||
return Enabled && Properties.Conditions.All(cm => cm.ConditionMet<T>(dataModel));
|
||||
}
|
||||
|
||||
public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (LayerType != LayerType.Keyboard && LayerType != LayerType.KeyboardGif)
|
||||
return;
|
||||
|
||||
// Preview simply shows the properties as they are. When not previewing they are applied
|
||||
var appliedProperties = !preview
|
||||
? Properties.GetAppliedProperties(dataModel)
|
||||
: Properties.GetAppliedProperties(dataModel, true);
|
||||
|
||||
// Update animations
|
||||
AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties, updateAnimations);
|
||||
|
||||
if (LayerType == LayerType.Keyboard)
|
||||
Drawer.Draw(c, (KeyboardPropertiesModel) Properties, appliedProperties);
|
||||
else if (LayerType == LayerType.KeyboardGif)
|
||||
GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) Properties, appliedProperties, GifImage);
|
||||
}
|
||||
|
||||
public Brush GenerateBrush<T>(LayerType type, IDataModel dataModel, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (!Enabled)
|
||||
return null;
|
||||
if (LayerType != LayerType.Folder && LayerType != type)
|
||||
return null;
|
||||
|
||||
// Preview simply shows the properties as they are. When not previewing they are applied
|
||||
AppliedProperties appliedProperties;
|
||||
if (!preview)
|
||||
{
|
||||
if (!ConditionsMet<T>(dataModel))
|
||||
return null; // Return null when not previewing and the conditions arent met
|
||||
appliedProperties = Properties.GetAppliedProperties(dataModel);
|
||||
}
|
||||
else
|
||||
appliedProperties = Properties.GetAppliedProperties(dataModel, true);
|
||||
|
||||
// TODO: Mouse/headset animations
|
||||
|
||||
if (LayerType != LayerType.Folder)
|
||||
return appliedProperties.Brush;
|
||||
|
||||
Brush res = null;
|
||||
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
||||
{
|
||||
var brush = layerModel.GenerateBrush<T>(type, dataModel, preview, updateAnimations);
|
||||
if (brush != null)
|
||||
res = brush;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void SetupProperties()
|
||||
{
|
||||
if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
|
||||
!(Properties is KeyboardPropertiesModel))
|
||||
{
|
||||
Properties = new KeyboardPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||
Animation = LayerAnimation.None,
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Opacity = 1
|
||||
};
|
||||
}
|
||||
else if (LayerType == LayerType.Mouse && !(Properties is MousePropertiesModel))
|
||||
Properties = new MousePropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
|
||||
};
|
||||
else if (LayerType == LayerType.Headset && !(Properties is HeadsetPropertiesModel))
|
||||
Properties = new HeadsetPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
|
||||
};
|
||||
}
|
||||
|
||||
public void FixOrder()
|
||||
{
|
||||
Children.Sort(l => l.Order);
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
Children[i].Order = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the layer meets the requirements to be drawn
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool MustDraw()
|
||||
{
|
||||
// If any of the parents are disabled, this layer must not be drawn
|
||||
var parent = Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (!parent.Enabled)
|
||||
return false;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif);
|
||||
}
|
||||
|
||||
public IEnumerable<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children)
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
public static LayerModel CreateLayer()
|
||||
{
|
||||
return new LayerModel
|
||||
{
|
||||
Name = "New layer",
|
||||
Enabled = true,
|
||||
Order = -1,
|
||||
LayerType = LayerType.Keyboard,
|
||||
Properties = new KeyboardPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||
Animation = LayerAnimation.None,
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Opacity = 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void InsertBefore(LayerModel source)
|
||||
{
|
||||
source.Order = Order;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
public void InsertAfter(LayerModel source)
|
||||
{
|
||||
source.Order = Order + 1;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
private void Insert(LayerModel source)
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
foreach (var child in Parent.Children.OrderBy(c => c.Order))
|
||||
{
|
||||
if (child.Order >= source.Order)
|
||||
child.Order++;
|
||||
}
|
||||
Parent.Children.Add(source);
|
||||
}
|
||||
else if (Profile != null)
|
||||
{
|
||||
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
|
||||
{
|
||||
if (layer.Order >= source.Order)
|
||||
layer.Order++;
|
||||
}
|
||||
Profile.Layers.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers<T>(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||
bool ignoreConditions = false)
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children.OrderByDescending(c => c.Order))
|
||||
{
|
||||
if (!layerModel.Enabled ||
|
||||
!includeMice && layerModel.LayerType == LayerType.Mouse ||
|
||||
!includeHeadsets && layerModel.LayerType == LayerType.Headset)
|
||||
continue;
|
||||
|
||||
if (!ignoreConditions)
|
||||
{
|
||||
if (!layerModel.ConditionsMet<T>(dataModel))
|
||||
continue;
|
||||
}
|
||||
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetRenderLayers<T>(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
#region IChildItem<Parent> Members
|
||||
|
||||
LayerModel IChildItem<LayerModel>.Parent
|
||||
{
|
||||
get { return Parent; }
|
||||
set { Parent = value; }
|
||||
}
|
||||
|
||||
ProfileModel IChildItem<ProfileModel>.Parent
|
||||
{
|
||||
get { return Profile; }
|
||||
set { Profile = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum LayerType
|
||||
{
|
||||
[Description("Folder")] Folder,
|
||||
[Description("Keyboard")] Keyboard,
|
||||
[Description("Keyboard - GIF")] KeyboardGif,
|
||||
[Description("Mouse")] Mouse,
|
||||
[Description("Headset")] Headset
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Conditions;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Types.Headset;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Profiles.Layers.Types.Mouse;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
||||
{
|
||||
public LayerModel()
|
||||
{
|
||||
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
||||
|
||||
var model = Properties as KeyboardPropertiesModel;
|
||||
if (model != null)
|
||||
GifImage = new GifImage(model.GifFile);
|
||||
}
|
||||
|
||||
public ILayerType LayerType { get; set; }
|
||||
public ILayerCondition LayerCondition { get; set; }
|
||||
public ILayerAnimation LayerAnimation { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
public bool Expanded { get; set; }
|
||||
public bool IsEvent { get; set; }
|
||||
public LayerPropertiesModel Properties { get; set; }
|
||||
public EventPropertiesModel EventProperties { get; set; }
|
||||
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
public LayerPropertiesModel AppliedProperties { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ImageSource LayerImage => LayerType.DrawThumbnail(this);
|
||||
|
||||
[JsonIgnore]
|
||||
public LayerModel Parent { get; internal set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ProfileModel Profile { get; internal set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public GifImage GifImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this layers conditions are met.
|
||||
/// If they are met and this layer is an event, this also triggers that event.
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <returns></returns>
|
||||
public bool ConditionsMet(IDataModel dataModel)
|
||||
{
|
||||
// Conditions are not even checked if the layer isn't enabled
|
||||
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
|
||||
}
|
||||
|
||||
public void Update(IDataModel dataModel, bool preview, bool updateAnimations)
|
||||
{
|
||||
LayerType.Update(this, dataModel, preview);
|
||||
LayerAnimation?.Update(this, updateAnimations);
|
||||
}
|
||||
|
||||
public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||
{
|
||||
LayerType.Draw(this, c);
|
||||
}
|
||||
|
||||
public void SetupProperties()
|
||||
{
|
||||
LayerType.SetupProperties(this);
|
||||
|
||||
// If the type is an event, set it up
|
||||
if (IsEvent && EventProperties == null)
|
||||
{
|
||||
EventProperties = new KeyboardEventPropertiesModel
|
||||
{
|
||||
ExpirationType = ExpirationType.Time,
|
||||
Length = new TimeSpan(0, 0, 1),
|
||||
TriggerDelay = new TimeSpan(0)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void FixOrder()
|
||||
{
|
||||
Children.Sort(l => l.Order);
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
Children[i].Order = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the layer meets the requirements to be drawn in the profile editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool MustDraw()
|
||||
{
|
||||
// If any of the parents are disabled, this layer must not be drawn
|
||||
var parent = Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (!parent.Enabled)
|
||||
return false;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return Enabled && LayerType.MustDraw;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns every descendant of this layer
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children)
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Keyboard layer with default settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LayerModel CreateLayer()
|
||||
{
|
||||
return new LayerModel
|
||||
{
|
||||
Name = "New layer",
|
||||
Enabled = true,
|
||||
Order = -1,
|
||||
LayerType = new KeyboardType(),
|
||||
LayerCondition = new DataModelCondition(),
|
||||
Properties = new KeyboardPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Opacity = 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void InsertBefore(LayerModel source)
|
||||
{
|
||||
source.Order = Order;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
public void InsertAfter(LayerModel source)
|
||||
{
|
||||
source.Order = Order + 1;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
private void Insert(LayerModel source)
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
foreach (var child in Parent.Children.OrderBy(c => c.Order))
|
||||
{
|
||||
if (child.Order >= source.Order)
|
||||
child.Order++;
|
||||
}
|
||||
Parent.Children.Add(source);
|
||||
}
|
||||
else if (Profile != null)
|
||||
{
|
||||
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
|
||||
{
|
||||
if (layer.Order >= source.Order)
|
||||
layer.Order++;
|
||||
}
|
||||
Profile.Layers.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void Replace(LayerModel layer)
|
||||
{
|
||||
layer.Order = Order;
|
||||
layer.Parent = null;
|
||||
layer.Profile = null;
|
||||
|
||||
if (Parent != null)
|
||||
{
|
||||
Parent.Children.Add(layer);
|
||||
Parent.Children.Remove(this);
|
||||
}
|
||||
else if (Profile != null)
|
||||
{
|
||||
Profile.Layers.Add(layer);
|
||||
Profile.Layers.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||
bool ignoreConditions = false)
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children.OrderByDescending(c => c.Order))
|
||||
{
|
||||
if (!layerModel.Enabled || !includeMice && layerModel.LayerType is MouseType ||
|
||||
!includeHeadsets && layerModel.LayerType is HeadsetType)
|
||||
continue;
|
||||
|
||||
if (!ignoreConditions && !layerModel.ConditionsMet(dataModel))
|
||||
continue;
|
||||
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
#region IChildItem<Parent> Members
|
||||
|
||||
LayerModel IChildItem<LayerModel>.Parent
|
||||
{
|
||||
get { return Parent; }
|
||||
set { Parent = value; }
|
||||
}
|
||||
|
||||
ProfileModel IChildItem<ProfileModel>.Parent
|
||||
{
|
||||
get { return Profile; }
|
||||
set { Profile = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Utilities.Converters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public abstract class LayerPropertiesModel
|
||||
{
|
||||
public LayerPropertiesModel(LayerPropertiesModel source = null)
|
||||
{
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
// Clone the source's properties onto the new properties model (useful when changing property type)
|
||||
X = source.X;
|
||||
Y = source.Y;
|
||||
Width = source.Width;
|
||||
Height = source.Height;
|
||||
Contain = source.Contain;
|
||||
Opacity = source.Opacity;
|
||||
AnimationSpeed = source.AnimationSpeed;
|
||||
Conditions = source.Conditions;
|
||||
DynamicProperties = source.DynamicProperties;
|
||||
Brush = source.Brush;
|
||||
}
|
||||
|
||||
private Brush _brush;
|
||||
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public bool Contain { get; set; }
|
||||
public double Opacity { get; set; }
|
||||
public double AnimationSpeed { get; set; }
|
||||
public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>();
|
||||
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
|
||||
|
||||
[JsonIgnore]
|
||||
|
||||
public double AnimationProgress { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BrushJsonConverter))]
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty layer properties model used by layers that don't have their own special properties
|
||||
/// </summary>
|
||||
public class SimplePropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public SimplePropertiesModel(LayerPropertiesModel properties = null) : base(properties)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs
Normal file
53
Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.Folder
|
||||
{
|
||||
public class FolderType : ILayerType
|
||||
{
|
||||
public string Name { get; } = "Folder";
|
||||
public bool MustDraw { get; } = false;
|
||||
|
||||
public ImageSource DrawThumbnail(LayerModel layer)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.folder), thumbnailRect);
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void Draw(LayerModel layer, DrawingContext c)
|
||||
{
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
{
|
||||
if (layerModel.Properties is SimplePropertiesModel)
|
||||
return;
|
||||
|
||||
layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
|
||||
{
|
||||
if (layerPropertiesViewModel is FolderPropertiesViewModel)
|
||||
return layerPropertiesViewModel;
|
||||
return new FolderPropertiesViewModel(proposedLayer, dataModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs
Normal file
87
Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs
Normal file
@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Animations;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.Headset
|
||||
{
|
||||
public class HeadsetType : ILayerType
|
||||
{
|
||||
public string Name { get; } = "Headset";
|
||||
public bool MustDraw { get; } = false;
|
||||
|
||||
public ImageSource DrawThumbnail(LayerModel layer)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.headset), thumbnailRect);
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void Draw(LayerModel layer, DrawingContext c)
|
||||
{
|
||||
// If an animation is present, let it handle the drawing
|
||||
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
|
||||
{
|
||||
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise draw the rectangle with its applied dimensions and brush
|
||||
var rect = new Rect(layer.AppliedProperties.X * 4,
|
||||
layer.AppliedProperties.Y * 4,
|
||||
layer.AppliedProperties.Width * 4,
|
||||
layer.AppliedProperties.Height * 4);
|
||||
|
||||
c.PushClip(new RectangleGeometry(rect));
|
||||
c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
// Headset layers are always drawn 10*10 (which is 40*40 when scaled up)
|
||||
layerModel.Properties.Width = 10;
|
||||
layerModel.Properties.Height = 10;
|
||||
layerModel.Properties.X = 0;
|
||||
layerModel.Properties.Y = 0;
|
||||
layerModel.Properties.Contain = true;
|
||||
|
||||
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties);
|
||||
|
||||
if (isPreview || dataModel == null)
|
||||
return;
|
||||
|
||||
// If not previewing, apply dynamic properties according to datamodel
|
||||
var props = (SimplePropertiesModel)layerModel.AppliedProperties;
|
||||
foreach (var dynamicProperty in props.DynamicProperties)
|
||||
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
{
|
||||
if (layerModel.Properties is SimplePropertiesModel)
|
||||
return;
|
||||
|
||||
layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
|
||||
{
|
||||
if (layerPropertiesViewModel is HeadsetPropertiesViewModel)
|
||||
return layerPropertiesViewModel;
|
||||
return new HeadsetPropertiesViewModel(proposedLayer, dataModel, layerAnimations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
using System.Windows;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.Keyboard
|
||||
{
|
||||
public class KeyboardPropertiesModel : LayerPropertiesModel
|
||||
{
|
||||
public KeyboardPropertiesModel(LayerPropertiesModel properties = null) : base(properties)
|
||||
{
|
||||
}
|
||||
|
||||
public string GifFile { get; set; }
|
||||
|
||||
public Rect GetRect(int scale = 4)
|
||||
{
|
||||
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
100
Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs
Normal file
100
Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Animations;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.Keyboard
|
||||
{
|
||||
public class KeyboardType : ILayerType
|
||||
{
|
||||
public string Name { get; } = "Keyboard";
|
||||
public bool MustDraw { get; } = true;
|
||||
|
||||
public ImageSource DrawThumbnail(LayerModel layer)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
if (layer.Properties.Brush != null)
|
||||
{
|
||||
c.DrawRectangle(layer.Properties.Brush,
|
||||
new Pen(new SolidColorBrush(Colors.White), 1),
|
||||
thumbnailRect);
|
||||
}
|
||||
}
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void Draw(LayerModel layer, DrawingContext c)
|
||||
{
|
||||
// If an animation is present, let it handle the drawing
|
||||
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
|
||||
{
|
||||
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush
|
||||
var rect = layer.Properties.Contain
|
||||
? new Rect(layer.AppliedProperties.X*4,
|
||||
layer.AppliedProperties.Y*4,
|
||||
layer.AppliedProperties.Width*4,
|
||||
layer.AppliedProperties.Height*4)
|
||||
: new Rect(layer.Properties.X*4,
|
||||
layer.Properties.Y*4,
|
||||
layer.Properties.Width*4,
|
||||
layer.Properties.Height*4);
|
||||
|
||||
var clip = new Rect(layer.AppliedProperties.X*4, layer.AppliedProperties.Y*4,
|
||||
layer.AppliedProperties.Width*4, layer.AppliedProperties.Height*4);
|
||||
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties);
|
||||
if (isPreview || dataModel == null)
|
||||
return;
|
||||
|
||||
// If not previewing, apply dynamic properties according to datamodel
|
||||
var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties;
|
||||
foreach (var dynamicProperty in keyboardProps.DynamicProperties)
|
||||
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
{
|
||||
if (layerModel.Properties is KeyboardPropertiesModel)
|
||||
return;
|
||||
|
||||
layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
|
||||
{
|
||||
var model = layerPropertiesViewModel as KeyboardPropertiesViewModel;
|
||||
if (model == null)
|
||||
return new KeyboardPropertiesViewModel(proposedLayer, dataModel, layerAnimations)
|
||||
{
|
||||
IsGif = false
|
||||
};
|
||||
|
||||
model.IsGif = false;
|
||||
return layerPropertiesViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.KeyboardGif
|
||||
{
|
||||
internal class KeyboardGifType : ILayerType
|
||||
{
|
||||
public string Name { get; } = "Keyboard - GIF";
|
||||
public bool MustDraw { get; } = true;
|
||||
|
||||
public ImageSource DrawThumbnail(LayerModel layer)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect);
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void Draw(LayerModel layer, DrawingContext c)
|
||||
{
|
||||
var props = (KeyboardPropertiesModel) layer.Properties;
|
||||
if (string.IsNullOrEmpty(props.GifFile))
|
||||
return;
|
||||
if (!File.Exists(props.GifFile))
|
||||
return;
|
||||
|
||||
// Only reconstruct GifImage if the underlying source has changed
|
||||
if (layer.GifImage == null)
|
||||
layer.GifImage = new GifImage(props.GifFile);
|
||||
if (layer.GifImage.Source != props.GifFile)
|
||||
layer.GifImage = new GifImage(props.GifFile);
|
||||
|
||||
var rect = new Rect(layer.AppliedProperties.X*4,
|
||||
layer.AppliedProperties.Y*4,
|
||||
layer.AppliedProperties.Width*4,
|
||||
layer.AppliedProperties.Height*4);
|
||||
|
||||
lock (layer.GifImage)
|
||||
{
|
||||
var draw = layer.GifImage.GetNextFrame();
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), rect);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties);
|
||||
if (isPreview)
|
||||
return;
|
||||
|
||||
// If not previewing, apply dynamic properties according to datamodel
|
||||
var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties;
|
||||
foreach (var dynamicProperty in keyboardProps.DynamicProperties)
|
||||
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
{
|
||||
if (layerModel.Properties is KeyboardPropertiesModel)
|
||||
return;
|
||||
|
||||
layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
|
||||
{
|
||||
var model = layerPropertiesViewModel as KeyboardPropertiesViewModel;
|
||||
if (model == null)
|
||||
return new KeyboardPropertiesViewModel(proposedLayer, dataModel, layerAnimations)
|
||||
{
|
||||
IsGif = true
|
||||
};
|
||||
|
||||
model.IsGif = true;
|
||||
return layerPropertiesViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs
Normal file
88
Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Animations;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.Mouse
|
||||
{
|
||||
public class MouseType : ILayerType
|
||||
{
|
||||
public string Name { get; } = "Mouse";
|
||||
public bool MustDraw { get; } = false;
|
||||
|
||||
public ImageSource DrawThumbnail(LayerModel layer)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.mouse), thumbnailRect);
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void Draw(LayerModel layer, DrawingContext c)
|
||||
{
|
||||
// If an animation is present, let it handle the drawing
|
||||
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
|
||||
{
|
||||
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise draw the rectangle with its applied dimensions and brush
|
||||
var rect = new Rect(layer.AppliedProperties.X * 4,
|
||||
layer.AppliedProperties.Y * 4,
|
||||
layer.AppliedProperties.Width * 4,
|
||||
layer.AppliedProperties.Height * 4);
|
||||
|
||||
c.PushClip(new RectangleGeometry(rect));
|
||||
c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
// Mouse layers are always drawn 10*10 (which is 40*40 when scaled up)
|
||||
layerModel.Properties.Width = 10;
|
||||
layerModel.Properties.Height = 10;
|
||||
layerModel.Properties.X = 0;
|
||||
layerModel.Properties.Y = 0;
|
||||
layerModel.Properties.Contain = true;
|
||||
|
||||
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties);
|
||||
|
||||
if (isPreview || dataModel == null)
|
||||
return;
|
||||
|
||||
// If not previewing, apply dynamic properties according to datamodel
|
||||
var props = (SimplePropertiesModel)layerModel.AppliedProperties;
|
||||
foreach (var dynamicProperty in props.DynamicProperties)
|
||||
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
{
|
||||
if (layerModel.Properties is SimplePropertiesModel)
|
||||
return;
|
||||
|
||||
layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
|
||||
List<ILayerAnimation> layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
|
||||
{
|
||||
if (layerPropertiesViewModel is MousePropertiesViewModel)
|
||||
return layerPropertiesViewModel;
|
||||
return new MousePropertiesViewModel(proposedLayer, dataModel, layerAnimations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,223 +1,201 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using Point = System.Windows.Point;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace Artemis.Models.Profiles
|
||||
{
|
||||
public class ProfileModel
|
||||
{
|
||||
public ProfileModel()
|
||||
{
|
||||
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
|
||||
DrawingVisual = new DrawingVisual();
|
||||
}
|
||||
|
||||
public ChildItemCollection<ProfileModel, LayerModel> Layers { get; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string KeyboardSlug { get; set; }
|
||||
public string GameName { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public DrawingVisual DrawingVisual { get; set; }
|
||||
|
||||
protected bool Equals(ProfileModel other)
|
||||
{
|
||||
return string.Equals(Name, other.Name) &&
|
||||
string.Equals(KeyboardSlug, other.KeyboardSlug) &&
|
||||
string.Equals(GameName, other.GameName);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((ProfileModel)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Name?.GetHashCode() ?? 0;
|
||||
hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
|
||||
hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public void FixOrder()
|
||||
{
|
||||
Layers.Sort(l => l.Order);
|
||||
for (var i = 0; i < Layers.Count; i++)
|
||||
Layers[i].Order = i;
|
||||
}
|
||||
|
||||
public void DrawProfile<T>(Graphics keyboard, Rect keyboardRect, IDataModel dataModel, bool preview,
|
||||
bool updateAnimations)
|
||||
{
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
// Setup the DrawingVisual's size
|
||||
c.PushClip(new RectangleGeometry(keyboardRect));
|
||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||
|
||||
// Draw the layers
|
||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||
|
||||
// Remove the clip
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
|
||||
keyboard.DrawImage(bmp, new PointF(0, 0));
|
||||
}
|
||||
|
||||
public Brush GenerateBrush<T>(IDataModel dataModel, LayerType type, bool preview, bool updateAnimations)
|
||||
{
|
||||
Brush result = null;
|
||||
// Draw the layers
|
||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||
{
|
||||
var generated = layerModel.GenerateBrush<T>(type, dataModel, preview, updateAnimations);
|
||||
if (generated != null)
|
||||
result = generated;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives all the layers and their children in a flat list
|
||||
/// </summary>
|
||||
public List<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Layers)
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers<T>(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||
bool ignoreConditions = false)
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||
{
|
||||
if (!layerModel.Enabled ||
|
||||
!includeMice && layerModel.LayerType == LayerType.Mouse ||
|
||||
!includeHeadsets && layerModel.LayerType == LayerType.Headset)
|
||||
continue;
|
||||
|
||||
if (!ignoreConditions)
|
||||
{
|
||||
if (!layerModel.ConditionsMet<T>(dataModel))
|
||||
continue;
|
||||
}
|
||||
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetRenderLayers<T>(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
|
||||
/// </summary>
|
||||
/// <param name="keyboardRectangle"></param>
|
||||
public void FixBoundaries(Rect keyboardRectangle)
|
||||
{
|
||||
foreach (var layer in GetLayers())
|
||||
{
|
||||
if (layer.LayerType != LayerType.Keyboard && layer.LayerType != LayerType.KeyboardGif)
|
||||
continue;
|
||||
|
||||
var props = (KeyboardPropertiesModel)layer.Properties;
|
||||
var layerRect = new Rect(new Point(props.X, props.Y), new Size(props.Width, props.Height));
|
||||
if (keyboardRectangle.Contains(layerRect))
|
||||
continue;
|
||||
|
||||
props.X = 0;
|
||||
props.Y = 0;
|
||||
layer.Properties = props;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw all the provided layers of type Keyboard and KeyboardGif
|
||||
/// </summary>
|
||||
/// <param name="keyboard">The graphics to draw on</param>
|
||||
/// <param name="renderLayers">The layers to render</param>
|
||||
/// <param name="dataModel">The data model to base the layer's properties on</param>
|
||||
/// <param name="keyboardRect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param>
|
||||
/// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param>
|
||||
/// <param name="updateAnimations">Wheter or not to update the layer's animations</param>
|
||||
internal void DrawProfile(Graphics keyboard, List<LayerModel> renderLayers, IDataModel dataModel, Rect keyboardRect,
|
||||
bool preview,
|
||||
bool updateAnimations)
|
||||
{
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
// Setup the DrawingVisual's size
|
||||
c.PushClip(new RectangleGeometry(keyboardRect));
|
||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||
|
||||
// Draw the layers
|
||||
foreach (var layerModel in renderLayers
|
||||
.Where(l => l.LayerType == LayerType.Keyboard ||
|
||||
l.LayerType == LayerType.KeyboardGif))
|
||||
{
|
||||
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||
}
|
||||
|
||||
// Remove the clip
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
|
||||
keyboard.DrawImage(bmp, new PointF(0, 0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a brush out of the given layer, for usage with mice and headsets
|
||||
/// </summary>
|
||||
/// <param name="layerModel">The layer to base the brush on</param>
|
||||
/// <param name="dataModel">The game data model to base the layer's properties on</param>
|
||||
/// <returns>The generated brush</returns>
|
||||
public Brush GenerateBrush(LayerModel layerModel, IDataModel dataModel)
|
||||
{
|
||||
return layerModel?.Properties.GetAppliedProperties(dataModel).Brush;
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Headset;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Profiles.Layers.Types.Mouse;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
using Newtonsoft.Json;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using Point = System.Windows.Point;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace Artemis.Profiles
|
||||
{
|
||||
public class ProfileModel
|
||||
{
|
||||
public ProfileModel()
|
||||
{
|
||||
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
|
||||
DrawingVisual = new DrawingVisual();
|
||||
}
|
||||
|
||||
public ChildItemCollection<ProfileModel, LayerModel> Layers { get; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string KeyboardSlug { get; set; }
|
||||
public string GameName { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
|
||||
public DrawingVisual DrawingVisual { get; set; }
|
||||
|
||||
public void FixOrder()
|
||||
{
|
||||
Layers.Sort(l => l.Order);
|
||||
for (var i = 0; i < Layers.Count; i++)
|
||||
Layers[i].Order = i;
|
||||
}
|
||||
|
||||
public void DrawLayers(Graphics keyboard, Rect keyboardRect, IDataModel dataModel, bool preview,
|
||||
bool updateAnimations)
|
||||
{
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
// Setup the DrawingVisual's size
|
||||
c.PushClip(new RectangleGeometry(keyboardRect));
|
||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
|
||||
|
||||
// Draw the layers
|
||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||
{
|
||||
layerModel.Update(dataModel, preview, updateAnimations);
|
||||
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||
}
|
||||
// Remove the clip
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
|
||||
keyboard.DrawImage(bmp, new PointF(0, 0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives all the layers and their children in a flat list
|
||||
/// </summary>
|
||||
public List<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Layers)
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a flat list containing all layers that must be rendered on the keyboard,
|
||||
/// the first mouse layer to be rendered and the first headset layer to be rendered
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="includeMice">Whether or not to include mice in the list</param>
|
||||
/// <param name="includeHeadsets">Whether or not to include headsets in the list</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
|
||||
bool ignoreConditions = false)
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
|
||||
{
|
||||
if (!layerModel.Enabled || !includeMice && layerModel.LayerType is MouseType ||
|
||||
!includeHeadsets && layerModel.LayerType is HeadsetType)
|
||||
continue;
|
||||
|
||||
if (!ignoreConditions && !layerModel.ConditionsMet(dataModel))
|
||||
continue;
|
||||
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
|
||||
/// </summary>
|
||||
/// <param name="keyboardRectangle"></param>
|
||||
public void FixBoundaries(Rect keyboardRectangle)
|
||||
{
|
||||
foreach (var layer in GetLayers())
|
||||
{
|
||||
if (!layer.LayerType.MustDraw)
|
||||
continue;
|
||||
|
||||
var props = (KeyboardPropertiesModel) layer.Properties;
|
||||
var layerRect = new Rect(new Point(props.X, props.Y), new Size(props.Width, props.Height));
|
||||
if (keyboardRectangle.Contains(layerRect))
|
||||
continue;
|
||||
|
||||
props.X = 0;
|
||||
props.Y = 0;
|
||||
layer.Properties = props;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw all the given layers on the given rect
|
||||
/// </summary>
|
||||
/// <param name="g">The graphics to draw on</param>
|
||||
/// <param name="renderLayers">The layers to render</param>
|
||||
/// <param name="dataModel">The data model to base the layer's properties on</param>
|
||||
/// <param name="rect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param>
|
||||
/// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param>
|
||||
/// <param name="updateAnimations">Wheter or not to update the layer's animations</param>
|
||||
internal void DrawLayers(Graphics g, IEnumerable<LayerModel> renderLayers, IDataModel dataModel, Rect rect,
|
||||
bool preview, bool updateAnimations)
|
||||
{
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
// Setup the DrawingVisual's size
|
||||
c.PushClip(new RectangleGeometry(rect));
|
||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect);
|
||||
|
||||
// Draw the layers
|
||||
foreach (var layerModel in renderLayers)
|
||||
{
|
||||
layerModel.Update(dataModel, preview, updateAnimations);
|
||||
layerModel.Draw(dataModel, c, preview, updateAnimations);
|
||||
}
|
||||
|
||||
// Remove the clip
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, rect))
|
||||
g.DrawImage(bmp, new PointF(0, 0));
|
||||
}
|
||||
|
||||
#region Compare
|
||||
|
||||
protected bool Equals(ProfileModel other)
|
||||
{
|
||||
return string.Equals(Name, other.Name) &&
|
||||
string.Equals(KeyboardSlug, other.KeyboardSlug) &&
|
||||
string.Equals(GameName, other.GameName);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
return Equals((ProfileModel) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Name?.GetHashCode() ?? 0;
|
||||
hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
|
||||
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -1,5 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="General">
|
||||
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
|
||||
GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="General">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="LastEffect" Type="System.String" Scope="User">
|
||||
|
||||
@ -5,7 +5,6 @@ using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Windows;
|
||||
using Artemis.Utilities;
|
||||
using MahApps.Metro;
|
||||
using NLog;
|
||||
|
||||
namespace Artemis.Settings
|
||||
{
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{StaticResource SliderThumbStyle}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"/>
|
||||
BorderBrush="{TemplateBinding BorderBrush}" />
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</ControlTemplate>
|
||||
@ -491,7 +491,8 @@
|
||||
SelectedGradient="{Binding}"
|
||||
Margin="0,0,0,2">
|
||||
<nc:GradientStopSlider.Background>
|
||||
<SolidColorBrush Color="{Binding Color}"/>
|
||||
<SolidColorBrush
|
||||
Color="{Binding Color}" />
|
||||
</nc:GradientStopSlider.Background>
|
||||
</nc:GradientStopSlider>
|
||||
<ControlTemplate.Triggers>
|
||||
|
||||
@ -33,7 +33,7 @@ namespace Artemis.Utilities
|
||||
{
|
||||
var colors = new List<byte>();
|
||||
for (var i = 0; i < 3; i++)
|
||||
colors.Add((byte)_rand.Next(0, 256));
|
||||
colors.Add((byte) _rand.Next(0, 256));
|
||||
|
||||
var highest = colors.Max();
|
||||
var lowest = colors.Min();
|
||||
|
||||
43
Artemis/Artemis/Utilities/Converters/JsonConverters.cs
Normal file
43
Artemis/Artemis/Utilities/Converters/JsonConverters.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Artemis.Utilities.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores a brush by temporarily serializing it to XAML because Json.NET has trouble
|
||||
/// saving it as JSON
|
||||
/// </summary>
|
||||
public class BrushJsonConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
// Turn the brush into an XML node
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(XamlWriter.Save(value));
|
||||
|
||||
// Serialize the XML node as JSON
|
||||
var jo = JObject.Parse(JsonConvert.SerializeXmlNode(doc.DocumentElement));
|
||||
jo.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
|
||||
JsonSerializer serializer)
|
||||
{
|
||||
// Load JObject from stream
|
||||
var jObject = JObject.Load(reader);
|
||||
|
||||
// Seriaze the JSON node to XML
|
||||
var xml = JsonConvert.DeserializeXmlNode(jObject.ToString());
|
||||
return XamlReader.Parse(xml.InnerXml);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(Brush).IsAssignableFrom(objectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,66 +1,79 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Fredrik Hedblad - http://stackoverflow.com/a/3987099/5015269
|
||||
/// </summary>
|
||||
public class EnumDescriptionConverter : IValueConverter
|
||||
{
|
||||
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var myEnum = (Enum) value;
|
||||
var description = GetEnumDescription(myEnum);
|
||||
return description;
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetEnumDescription(Enum enumObj)
|
||||
{
|
||||
var fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
|
||||
|
||||
var attribArray = fieldInfo.GetCustomAttributes(false);
|
||||
|
||||
if (attribArray.Length == 0)
|
||||
{
|
||||
return enumObj.ToString();
|
||||
}
|
||||
var attrib = attribArray[0] as DescriptionAttribute;
|
||||
return attrib?.Description;
|
||||
}
|
||||
}
|
||||
|
||||
public class LayerOrderConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
IList collection;
|
||||
if (value is ChildItemCollection<LayerModel, LayerModel>)
|
||||
collection = ((ChildItemCollection<LayerModel, LayerModel>) value).ToList();
|
||||
else
|
||||
collection = (IList) value;
|
||||
|
||||
var view = new ListCollectionView(collection);
|
||||
var sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
|
||||
view.SortDescriptions.Add(sort);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
|
||||
namespace Artemis.Utilities.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Fredrik Hedblad - http://stackoverflow.com/a/3987099/5015269
|
||||
/// </summary>
|
||||
public class EnumDescriptionConverter : IValueConverter
|
||||
{
|
||||
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var myEnum = (Enum) value;
|
||||
var description = GetEnumDescription(myEnum);
|
||||
return description;
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string GetEnumDescription(Enum enumObj)
|
||||
{
|
||||
var fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
|
||||
|
||||
var attribArray = fieldInfo.GetCustomAttributes(false);
|
||||
|
||||
if (attribArray.Length == 0)
|
||||
{
|
||||
return enumObj.ToString();
|
||||
}
|
||||
var attrib = attribArray[0] as DescriptionAttribute;
|
||||
return attrib?.Description;
|
||||
}
|
||||
}
|
||||
|
||||
public class LayerOrderConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
IList collection;
|
||||
if (value is ChildItemCollection<LayerModel, LayerModel>)
|
||||
collection = ((ChildItemCollection<LayerModel, LayerModel>) value).ToList();
|
||||
else
|
||||
collection = (IList) value;
|
||||
|
||||
var view = new ListCollectionView(collection);
|
||||
var sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
|
||||
view.SortDescriptions.Add(sort);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class MilliSecondTimespanConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value == null ? 0.0 : ((TimeSpan)value).TotalMilliseconds;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value == null ? new TimeSpan() : TimeSpan.FromMilliseconds((double)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Media;
|
||||
using Ninject.Extensions.Logging;
|
||||
|
||||
namespace Artemis.Utilities.DataReaders
|
||||
{
|
||||
@ -12,10 +13,11 @@ namespace Artemis.Utilities.DataReaders
|
||||
/// </summary>
|
||||
public class MmfReader
|
||||
{
|
||||
private DateTime _lastFailure;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public MmfReader(string mmfName)
|
||||
public MmfReader(string mmfName, ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
MmfName = mmfName;
|
||||
}
|
||||
|
||||
@ -54,8 +56,9 @@ namespace Artemis.Utilities.DataReaders
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
catch (FormatException)
|
||||
catch (FormatException e)
|
||||
{
|
||||
_logger.Trace(e, "Failed to parse to color array");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -67,10 +70,6 @@ namespace Artemis.Utilities.DataReaders
|
||||
/// <returns></returns>
|
||||
private string ReadMmf(string fileName)
|
||||
{
|
||||
// Don't read the file within one second after failing
|
||||
//if (DateTime.Now - _lastFailure > new TimeSpan(0, 0, 1))
|
||||
// return null;
|
||||
|
||||
try
|
||||
{
|
||||
using (var mmf = MemoryMappedFile.OpenExisting(fileName))
|
||||
@ -85,9 +84,9 @@ namespace Artemis.Utilities.DataReaders
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_lastFailure = DateTime.Now;
|
||||
_logger.Trace(e, "Failed to read mff");
|
||||
return null;
|
||||
//ignored
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using static System.String;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
@ -39,7 +39,7 @@ namespace Artemis.Utilities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a deep Copy of the object.
|
||||
/// Perform a deep Copy of the object, using Json as a serialisation method.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object being copied.</typeparam>
|
||||
/// <param name="source">The object instance to copy.</param>
|
||||
@ -50,35 +50,20 @@ namespace Artemis.Utilities
|
||||
if (ReferenceEquals(source, null))
|
||||
return default(T);
|
||||
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
Stream stream = new MemoryStream();
|
||||
using (stream)
|
||||
var deserializeSettings = new JsonSerializerSettings
|
||||
{
|
||||
serializer.Serialize(stream, source);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
return (T) serializer.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T source)
|
||||
{
|
||||
// Don't serialize a null object, simply return the default for that object
|
||||
if (ReferenceEquals(source, null))
|
||||
return null;
|
||||
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
var stream = new StringWriter();
|
||||
using (stream)
|
||||
{
|
||||
serializer.Serialize(stream, source);
|
||||
return stream.ToString();
|
||||
}
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
||||
TypeNameHandling = TypeNameHandling.Auto
|
||||
};
|
||||
return (T)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source), source.GetType(),
|
||||
deserializeSettings);
|
||||
}
|
||||
|
||||
public static object GetPropertyValue(object o, string path)
|
||||
{
|
||||
var propertyNames = path.Split('.');
|
||||
var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);
|
||||
var prop = o.GetType().GetProperty(propertyNames[0]);
|
||||
var value = prop.GetValue(o, null);
|
||||
|
||||
if (propertyNames.Length == 1 || value == null)
|
||||
return value;
|
||||
|
||||
@ -8,9 +8,7 @@ namespace Artemis.Utilities
|
||||
{
|
||||
private readonly int _delay;
|
||||
private readonly FrameDimension _dimension;
|
||||
private readonly int _frameCount;
|
||||
private readonly Image _gifImage;
|
||||
private int _currentFrame = -1;
|
||||
private DateTime _lastRequest;
|
||||
private int _step = 1;
|
||||
|
||||
@ -19,7 +17,7 @@ namespace Artemis.Utilities
|
||||
_lastRequest = DateTime.Now;
|
||||
_gifImage = Image.FromFile(path); //initialize
|
||||
_dimension = new FrameDimension(_gifImage.FrameDimensionsList[0]); //gets the GUID
|
||||
_frameCount = _gifImage.GetFrameCount(_dimension); //total frames in the animation
|
||||
FrameCount = _gifImage.GetFrameCount(_dimension); //total frames in the animation
|
||||
|
||||
Source = path;
|
||||
|
||||
@ -27,7 +25,20 @@ namespace Artemis.Utilities
|
||||
_delay = (item.Value[0] + item.Value[1]*256)*10; // Time is in 1/100th of a second
|
||||
}
|
||||
|
||||
public string Source { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the path the GifImage is based on
|
||||
/// </summary>
|
||||
public string Source { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current frame, set to -1 to reset
|
||||
/// </summary>
|
||||
public int CurrentFrame { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total amount of frames in the GIF
|
||||
/// </summary>
|
||||
public int FrameCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the gif should play backwards when it reaches the end
|
||||
@ -39,23 +50,23 @@ namespace Artemis.Utilities
|
||||
// Only pass the next frame if the proper amount of time has passed
|
||||
if ((DateTime.Now - _lastRequest).Milliseconds > _delay)
|
||||
{
|
||||
_currentFrame += _step;
|
||||
CurrentFrame += _step;
|
||||
_lastRequest = DateTime.Now;
|
||||
}
|
||||
|
||||
//if the animation reaches a boundary...
|
||||
if (_currentFrame < _frameCount && _currentFrame >= 1)
|
||||
return GetFrame(_currentFrame);
|
||||
if (CurrentFrame < FrameCount && CurrentFrame >= 1)
|
||||
return GetFrame(CurrentFrame);
|
||||
|
||||
if (ReverseAtEnd)
|
||||
{
|
||||
_step *= -1; //...reverse the count
|
||||
_currentFrame += _step; //apply it
|
||||
CurrentFrame += _step; //apply it
|
||||
}
|
||||
else
|
||||
_currentFrame = 0; //...or start over
|
||||
CurrentFrame = 0; //...or start over
|
||||
|
||||
return GetFrame(_currentFrame);
|
||||
return GetFrame(CurrentFrame);
|
||||
}
|
||||
|
||||
public Image GetFrame(int index)
|
||||
|
||||
@ -70,5 +70,24 @@ namespace Artemis.Utilities
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the BowIcon from resources and colors it according to the current theme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static RenderTargetBitmap GenerateWindowIcon()
|
||||
{
|
||||
var iconImage = new System.Windows.Controls.Image
|
||||
{
|
||||
Source = (DrawingImage) Application.Current.MainWindow.Resources["BowIcon"],
|
||||
Stretch = Stretch.Uniform,
|
||||
Margin = new Thickness(20)
|
||||
};
|
||||
|
||||
iconImage.Arrange(new Rect(0, 0, 100, 100));
|
||||
var bitmap = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
|
||||
bitmap.Render(iconImage);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
|
||||
namespace Artemis.Utilities.Layers
|
||||
{
|
||||
public static class AnimationUpdater
|
||||
{
|
||||
public static void UpdateAnimation(KeyboardPropertiesModel properties, bool updateAnimations)
|
||||
{
|
||||
const int scale = 4;
|
||||
var progress = properties.AnimationProgress;
|
||||
|
||||
switch (properties.Animation)
|
||||
{
|
||||
case LayerAnimation.SlideRight:
|
||||
case LayerAnimation.SlideLeft:
|
||||
if (progress + properties.AnimationSpeed * 2 >= properties.Width*scale)
|
||||
progress = 0;
|
||||
progress = progress + properties.AnimationSpeed*2;
|
||||
break;
|
||||
case LayerAnimation.SlideDown:
|
||||
case LayerAnimation.SlideUp:
|
||||
if (progress + properties.AnimationSpeed * 2 >= properties.Height*scale)
|
||||
progress = 0;
|
||||
progress = progress + properties.AnimationSpeed*2;
|
||||
break;
|
||||
case LayerAnimation.Pulse:
|
||||
if (progress > 2)
|
||||
progress = 0;
|
||||
progress = progress + properties.AnimationSpeed/2;
|
||||
break;
|
||||
case LayerAnimation.Grow:
|
||||
if (progress > 10)
|
||||
progress = 0;
|
||||
progress = progress + properties.AnimationSpeed/2.5;
|
||||
break;
|
||||
default:
|
||||
progress = progress + properties.AnimationSpeed*2;
|
||||
break;
|
||||
}
|
||||
|
||||
// If not previewing, store the animation progress in the actual model for the next frame
|
||||
if (updateAnimations)
|
||||
properties.AnimationProgress = progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,161 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Properties;
|
||||
using Pen = System.Windows.Media.Pen;
|
||||
using Point = System.Windows.Point;
|
||||
using Size = System.Windows.Size;
|
||||
|
||||
namespace Artemis.Utilities.Layers
|
||||
{
|
||||
public static class Drawer
|
||||
{
|
||||
public static void Draw(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied)
|
||||
{
|
||||
if (applied.Brush == null)
|
||||
return;
|
||||
|
||||
const int scale = 4;
|
||||
// Set up variables for this frame
|
||||
var rect = props.Contain
|
||||
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale)
|
||||
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale);
|
||||
|
||||
var s1 = new Rect();
|
||||
var s2 = new Rect();
|
||||
|
||||
if (props.Animation == LayerAnimation.SlideRight)
|
||||
{
|
||||
s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
|
||||
s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height));
|
||||
}
|
||||
if (props.Animation == LayerAnimation.SlideLeft)
|
||||
{
|
||||
s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y),
|
||||
new Size(rect.Width + 0.05, rect.Height));
|
||||
s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
|
||||
}
|
||||
if (props.Animation == LayerAnimation.SlideDown)
|
||||
{
|
||||
s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||
s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
|
||||
}
|
||||
if (props.Animation == LayerAnimation.SlideUp)
|
||||
{
|
||||
s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), new Size(rect.Width, rect.Height));
|
||||
s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
|
||||
}
|
||||
|
||||
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
|
||||
DrawRectangle(c, props, applied, clip, rect, s1, s2);
|
||||
}
|
||||
|
||||
private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
|
||||
Rect clip, Rect rectangle, Rect slide1, Rect slide2)
|
||||
{
|
||||
// Apply the pulse animation
|
||||
if (props.Animation == LayerAnimation.Pulse)
|
||||
applied.Brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2);
|
||||
else
|
||||
applied.Brush.Opacity = props.Opacity;
|
||||
|
||||
if (props.Animation == LayerAnimation.Grow)
|
||||
{
|
||||
// Take an offset of 4 to allow layers to slightly leave their bounds
|
||||
var progress = (6.0 - props.AnimationProgress)*10.0;
|
||||
if (progress < 0)
|
||||
{
|
||||
applied.Brush.Opacity = 1 + 0.025*progress;
|
||||
if (applied.Brush.Opacity < 0)
|
||||
applied.Brush.Opacity = 0;
|
||||
if (applied.Brush.Opacity > 1)
|
||||
applied.Brush.Opacity = 1;
|
||||
}
|
||||
rectangle.Inflate(-rectangle.Width/100.0*progress, -rectangle.Height/100.0*progress);
|
||||
clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
|
||||
}
|
||||
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
// Most animation types can be drawn regularly
|
||||
if (props.Animation == LayerAnimation.None ||
|
||||
props.Animation == LayerAnimation.Grow ||
|
||||
props.Animation == LayerAnimation.Pulse)
|
||||
{
|
||||
c.DrawRectangle(applied.Brush, null, rectangle);
|
||||
}
|
||||
// Sliding animations however, require offsetting two rects
|
||||
else
|
||||
{
|
||||
c.PushClip(new RectangleGeometry(clip));
|
||||
c.DrawRectangle(applied.Brush, null, slide1);
|
||||
c.DrawRectangle(applied.Brush, null, slide2);
|
||||
c.Pop();
|
||||
}
|
||||
c.Pop();
|
||||
}
|
||||
|
||||
public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
|
||||
GifImage gifImage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(props.GifFile))
|
||||
return null;
|
||||
if (!File.Exists(props.GifFile))
|
||||
return null;
|
||||
|
||||
const int scale = 4;
|
||||
|
||||
// Only reconstruct GifImage if the underlying source has changed
|
||||
if (gifImage == null)
|
||||
gifImage = new GifImage(props.GifFile);
|
||||
if (gifImage.Source != props.GifFile)
|
||||
gifImage = new GifImage(props.GifFile);
|
||||
|
||||
var gifRect = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale,
|
||||
applied.Height*scale);
|
||||
|
||||
lock (gifImage)
|
||||
{
|
||||
var draw = gifImage.GetNextFrame();
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), gifRect);
|
||||
}
|
||||
|
||||
return gifImage;
|
||||
}
|
||||
|
||||
public static void UpdateMouse(LayerPropertiesModel properties)
|
||||
{
|
||||
}
|
||||
|
||||
public static void UpdateHeadset(LayerPropertiesModel properties)
|
||||
{
|
||||
}
|
||||
|
||||
public static ImageSource DrawThumbnail(LayerModel layerModel)
|
||||
{
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
// Draw the appropiate icon or draw the brush
|
||||
if (layerModel.LayerType == LayerType.Folder)
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.folder), thumbnailRect);
|
||||
else if (layerModel.LayerType == LayerType.Headset)
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.headset), thumbnailRect);
|
||||
else if (layerModel.LayerType == LayerType.Mouse)
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.mouse), thumbnailRect);
|
||||
else if (layerModel.LayerType == LayerType.KeyboardGif)
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect);
|
||||
else if (layerModel.LayerType == LayerType.Keyboard && layerModel.Properties.Brush != null)
|
||||
c.DrawRectangle(layerModel.Properties.Brush, new Pen(new SolidColorBrush(Colors.White), 1),
|
||||
thumbnailRect);
|
||||
}
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,14 +48,14 @@ namespace Artemis.Utilities
|
||||
{
|
||||
if (_waitTime < _stickyTime)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
Thread.Sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (_waitTime > 0)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
_waitTime -= 50;
|
||||
Thread.Sleep(10);
|
||||
_waitTime -= 10;
|
||||
}
|
||||
_value = _toStick;
|
||||
}
|
||||
|
||||
58
Artemis/Artemis/ViewModels/DebugViewModel.cs
Normal file
58
Artemis/Artemis/ViewModels/DebugViewModel.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Events;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.ViewModels
|
||||
{
|
||||
public class DebugViewModel : Screen, IHandle<RazerColorArrayChanged>
|
||||
{
|
||||
private readonly IEventAggregator _events;
|
||||
private DrawingImage _razerDisplay;
|
||||
|
||||
public DebugViewModel(IEventAggregator events)
|
||||
{
|
||||
_events = events;
|
||||
}
|
||||
|
||||
public DrawingImage RazerDisplay
|
||||
{
|
||||
get { return _razerDisplay; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _razerDisplay)) return;
|
||||
_razerDisplay = value;
|
||||
NotifyOfPropertyChange(() => RazerDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(RazerColorArrayChanged message)
|
||||
{
|
||||
var visual = new DrawingVisual();
|
||||
using (var dc = visual.RenderOpen())
|
||||
{
|
||||
dc.PushClip(new RectangleGeometry(new Rect(0, 0, 22, 6)));
|
||||
for (var y = 0; y < 6; y++)
|
||||
{
|
||||
for (var x = 0; x < 22; x++)
|
||||
dc.DrawRectangle(new SolidColorBrush(message.Colors[y, x]), null, new Rect(x, y, 1, 1));
|
||||
}
|
||||
}
|
||||
var drawnDisplay = new DrawingImage(visual.Drawing);
|
||||
drawnDisplay.Freeze();
|
||||
RazerDisplay = drawnDisplay;
|
||||
}
|
||||
|
||||
protected override void OnActivate()
|
||||
{
|
||||
_events.Subscribe(this);
|
||||
base.OnActivate();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate(bool close)
|
||||
{
|
||||
_events.Unsubscribe(this);
|
||||
base.OnDeactivate(close);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
using MahApps.Metro.Controls;
|
||||
using NLog;
|
||||
@ -14,15 +16,18 @@ namespace Artemis.ViewModels.Flyouts
|
||||
public sealed class FlyoutSettingsViewModel : FlyoutBaseViewModel, IHandle<ToggleEnabled>,
|
||||
IHandle<ActiveEffectChanged>
|
||||
{
|
||||
private readonly DebugViewModel _debugViewModel;
|
||||
private readonly ILogger _logger;
|
||||
private string _activeEffectName;
|
||||
private bool _enableDebug;
|
||||
private GeneralSettings _generalSettings;
|
||||
private string _selectedKeyboardProvider;
|
||||
|
||||
public FlyoutSettingsViewModel(MainManager mainManager, IEventAggregator events, ILogger logger)
|
||||
public FlyoutSettingsViewModel(MainManager mainManager, IEventAggregator events, ILogger logger,
|
||||
DebugViewModel debugViewModel)
|
||||
{
|
||||
_logger = logger;
|
||||
_debugViewModel = debugViewModel;
|
||||
|
||||
MainManager = mainManager;
|
||||
Header = "Settings";
|
||||
@ -178,6 +183,18 @@ namespace Artemis.ViewModels.Flyouts
|
||||
MainManager.EnableProgram();
|
||||
}
|
||||
|
||||
public void ShowDebug()
|
||||
{
|
||||
IWindowManager manager = new WindowManager();
|
||||
dynamic settings = new ExpandoObject();
|
||||
var icon = ImageUtilities.GenerateWindowIcon();
|
||||
|
||||
settings.Title = "Artemis | Debugger";
|
||||
settings.Icon = icon;
|
||||
|
||||
manager.ShowWindow(_debugViewModel, null, settings);
|
||||
}
|
||||
|
||||
public void ResetSettings()
|
||||
{
|
||||
GeneralSettings.ResetSettings();
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
|
||||
|
||||
namespace Artemis.ViewModels.Profiles.Events
|
||||
{
|
||||
public class EventPropertiesViewModel : PropertyChangedBase
|
||||
{
|
||||
private EventPropertiesModel _proposedProperties;
|
||||
|
||||
public EventPropertiesViewModel(EventPropertiesModel eventPropertiesModel)
|
||||
{
|
||||
if (eventPropertiesModel == null)
|
||||
ProposedProperties = new KeyboardEventPropertiesModel
|
||||
{
|
||||
ExpirationType = ExpirationType.Time,
|
||||
Length = new TimeSpan(0, 0, 1),
|
||||
TriggerDelay = new TimeSpan(0)
|
||||
};
|
||||
else
|
||||
ProposedProperties = GeneralHelpers.Clone(eventPropertiesModel);
|
||||
}
|
||||
|
||||
public EventPropertiesModel ProposedProperties
|
||||
{
|
||||
get { return _proposedProperties; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _proposedProperties)) return;
|
||||
_proposedProperties = value;
|
||||
NotifyOfPropertyChange(() => ProposedProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public EventPropertiesModel GetAppliedProperties()
|
||||
{
|
||||
return GeneralHelpers.Clone(ProposedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
using Castle.Core.Internal;
|
||||
|
||||
|
||||
namespace Artemis.ViewModels.Profiles
|
||||
{
|
||||
public sealed class LayerDynamicPropertiesViewModel : PropertyChangedBase
|
||||
@ -21,13 +22,13 @@ namespace Artemis.ViewModels.Profiles
|
||||
|
||||
public LayerDynamicPropertiesViewModel(string property,
|
||||
BindableCollection<GeneralHelpers.PropertyCollection> dataModelProps,
|
||||
KeyboardPropertiesModel keyboardProperties)
|
||||
LayerPropertiesModel layerPropertiesModel)
|
||||
{
|
||||
_property = property;
|
||||
|
||||
// Look for the existing property model
|
||||
Proposed = new DynamicPropertiesModel();
|
||||
var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
|
||||
var original = layerPropertiesModel.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
|
||||
if (original == null)
|
||||
{
|
||||
Proposed.LayerProperty = property;
|
||||
@ -161,22 +162,22 @@ namespace Artemis.ViewModels.Profiles
|
||||
case "Width":
|
||||
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
|
||||
{
|
||||
Models.Profiles.Properties.LayerPropertyOptions.LeftToRight,
|
||||
Models.Profiles.Properties.LayerPropertyOptions.RightToLeft
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.LeftToRight,
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.RightToLeft
|
||||
};
|
||||
break;
|
||||
case "Height":
|
||||
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
|
||||
{
|
||||
Models.Profiles.Properties.LayerPropertyOptions.Downwards,
|
||||
Models.Profiles.Properties.LayerPropertyOptions.Upwards
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.Downwards,
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.Upwards
|
||||
};
|
||||
break;
|
||||
case "Opacity":
|
||||
LayerPropertyOptions = new BindableCollection<LayerPropertyOptions>
|
||||
{
|
||||
Models.Profiles.Properties.LayerPropertyOptions.Increase,
|
||||
Models.Profiles.Properties.LayerPropertyOptions.Decrease
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.Increase,
|
||||
Artemis.Profiles.Layers.Models.LayerPropertyOptions.Decrease
|
||||
};
|
||||
break;
|
||||
}
|
||||
@ -206,14 +207,14 @@ namespace Artemis.ViewModels.Profiles
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply(KeyboardPropertiesModel keyboardProperties)
|
||||
public void Apply(LayerModel layerModel)
|
||||
{
|
||||
var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
|
||||
var original = layerModel.Properties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
|
||||
if (original != null)
|
||||
keyboardProperties.DynamicProperties.Remove(original);
|
||||
layerModel.Properties.DynamicProperties.Remove(original);
|
||||
|
||||
if (!Proposed.GameProperty.IsNullOrEmpty())
|
||||
keyboardProperties.DynamicProperties.Add(Proposed);
|
||||
layerModel.Properties.DynamicProperties.Add(Proposed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Models.Profiles.Properties;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Profiles.Layers.Types.KeyboardGif;
|
||||
using Artemis.Services;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Profiles.Properties;
|
||||
using Artemis.ViewModels.Profiles.Events;
|
||||
using Artemis.ViewModels.Profiles.Layers;
|
||||
using Caliburn.Micro;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.ViewModels.Profiles
|
||||
@ -16,15 +22,18 @@ namespace Artemis.ViewModels.Profiles
|
||||
public sealed class LayerEditorViewModel : Screen
|
||||
{
|
||||
private readonly IDataModel _dataModel;
|
||||
private readonly List<ILayerAnimation> _layerAnimations;
|
||||
private EventPropertiesViewModel _eventPropertiesViewModel;
|
||||
private LayerModel _layer;
|
||||
private LayerPropertiesViewModel _layerPropertiesViewModel;
|
||||
private LayerType _layerType;
|
||||
private LayerModel _proposedLayer;
|
||||
private LayerPropertiesModel _proposedProperties;
|
||||
private ILayerType _selectedLayerType;
|
||||
|
||||
public LayerEditorViewModel(IDataModel dataModel, LayerModel layer)
|
||||
public LayerEditorViewModel(IDataModel dataModel, LayerModel layer, IEnumerable<ILayerType> layerTypes,
|
||||
List<ILayerAnimation> layerAnimations)
|
||||
{
|
||||
_dataModel = dataModel;
|
||||
_layerAnimations = layerAnimations;
|
||||
|
||||
Layer = layer;
|
||||
ProposedLayer = GeneralHelpers.Clone(layer);
|
||||
@ -32,26 +41,28 @@ namespace Artemis.ViewModels.Profiles
|
||||
if (Layer.Properties == null)
|
||||
Layer.SetupProperties();
|
||||
|
||||
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>();
|
||||
DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap(dataModel));
|
||||
LayerConditionVms = new BindableCollection<LayerConditionViewModel>(layer.Properties.Conditions
|
||||
.Select(c => new LayerConditionViewModel(this, c, DataModelProps)));
|
||||
LayerTypes = new BindableCollection<ILayerType>(layerTypes);
|
||||
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>(
|
||||
GeneralHelpers.GenerateTypeMap(dataModel));
|
||||
LayerConditionVms = new BindableCollection<LayerConditionViewModel>(
|
||||
layer.Properties.Conditions.Select(c => new LayerConditionViewModel(this, c, DataModelProps)));
|
||||
|
||||
PropertyChanged += PropertiesViewModelHandler;
|
||||
|
||||
PreSelect();
|
||||
}
|
||||
|
||||
|
||||
public bool ModelChanged { get; set; }
|
||||
|
||||
[Inject]
|
||||
public MetroDialogService DialogService { get; set; }
|
||||
|
||||
public BindableCollection<ILayerType> LayerTypes { get; set; }
|
||||
public BindableCollection<GeneralHelpers.PropertyCollection> DataModelProps { get; set; }
|
||||
|
||||
public BindableCollection<string> LayerTypes => new BindableCollection<string>();
|
||||
|
||||
public BindableCollection<LayerConditionViewModel> LayerConditionVms { get; set; }
|
||||
public bool KeyboardGridIsVisible => ProposedLayer.LayerType is KeyboardType;
|
||||
public bool GifGridIsVisible => ProposedLayer.LayerType is KeyboardGifType;
|
||||
|
||||
public LayerModel Layer
|
||||
{
|
||||
@ -75,17 +86,6 @@ namespace Artemis.ViewModels.Profiles
|
||||
}
|
||||
}
|
||||
|
||||
public LayerType LayerType
|
||||
{
|
||||
get { return _layerType; }
|
||||
set
|
||||
{
|
||||
if (value == _layerType) return;
|
||||
_layerType = value;
|
||||
NotifyOfPropertyChange(() => LayerType);
|
||||
}
|
||||
}
|
||||
|
||||
public LayerPropertiesViewModel LayerPropertiesViewModel
|
||||
{
|
||||
get { return _layerPropertiesViewModel; }
|
||||
@ -97,59 +97,66 @@ namespace Artemis.ViewModels.Profiles
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeyboardGridIsVisible => ProposedLayer.LayerType == LayerType.Keyboard;
|
||||
public bool GifGridIsVisible => ProposedLayer.LayerType == LayerType.KeyboardGif;
|
||||
public EventPropertiesViewModel EventPropertiesViewModel
|
||||
{
|
||||
get { return _eventPropertiesViewModel; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _eventPropertiesViewModel)) return;
|
||||
_eventPropertiesViewModel = value;
|
||||
NotifyOfPropertyChange(() => EventPropertiesViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
public ILayerType SelectedLayerType
|
||||
{
|
||||
get { return _selectedLayerType; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _selectedLayerType)) return;
|
||||
_selectedLayerType = value;
|
||||
NotifyOfPropertyChange(() => SelectedLayerType);
|
||||
}
|
||||
}
|
||||
|
||||
public void PreSelect()
|
||||
{
|
||||
LayerType = ProposedLayer.LayerType;
|
||||
|
||||
if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_dataModel, ProposedLayer.Properties);
|
||||
SelectedLayerType = LayerTypes.FirstOrDefault(t => t.Name == ProposedLayer.LayerType.Name);
|
||||
ToggleIsEvent();
|
||||
}
|
||||
|
||||
private void PropertiesViewModelHandler(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName != "LayerType")
|
||||
if (e.PropertyName != "SelectedLayerType")
|
||||
return;
|
||||
|
||||
// Store the brush in case the user wants to reuse it
|
||||
var oldBrush = LayerPropertiesViewModel?.GetAppliedProperties().Brush;
|
||||
var oldBrush = ProposedLayer.Properties.Brush;
|
||||
|
||||
// Update the model
|
||||
if (ProposedLayer.LayerType != LayerType)
|
||||
if (ProposedLayer.LayerType.GetType() != SelectedLayerType.GetType())
|
||||
{
|
||||
ProposedLayer.LayerType = LayerType;
|
||||
ProposedLayer.LayerType = SelectedLayerType;
|
||||
ProposedLayer.SetupProperties();
|
||||
}
|
||||
|
||||
// Let the layer type handle the viewmodel setup
|
||||
LayerPropertiesViewModel = ProposedLayer.LayerType.SetupViewModel(LayerPropertiesViewModel, _layerAnimations,
|
||||
_dataModel, ProposedLayer);
|
||||
|
||||
if (oldBrush != null)
|
||||
ProposedLayer.Properties.Brush = oldBrush;
|
||||
|
||||
// Update the KeyboardPropertiesViewModel if it's being used
|
||||
var model = LayerPropertiesViewModel as KeyboardPropertiesViewModel;
|
||||
if (model != null)
|
||||
model.IsGif = LayerType == LayerType.KeyboardGif;
|
||||
|
||||
// Apply the proper PropertiesViewModel
|
||||
if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
|
||||
!(LayerPropertiesViewModel is KeyboardPropertiesViewModel))
|
||||
{
|
||||
LayerPropertiesViewModel = new KeyboardPropertiesViewModel(_dataModel, ProposedLayer.Properties)
|
||||
{
|
||||
IsGif = LayerType == LayerType.KeyboardGif
|
||||
};
|
||||
}
|
||||
else if (LayerType == LayerType.Mouse && !(LayerPropertiesViewModel is MousePropertiesViewModel))
|
||||
LayerPropertiesViewModel = new MousePropertiesViewModel(_dataModel, ProposedLayer.Properties);
|
||||
else if (LayerType == LayerType.Headset && !(LayerPropertiesViewModel is HeadsetPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new HeadsetPropertiesViewModel(_dataModel, ProposedLayer.Properties);
|
||||
else if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
|
||||
LayerPropertiesViewModel = new FolderPropertiesViewModel(_dataModel, ProposedLayer.Properties);
|
||||
|
||||
NotifyOfPropertyChange(() => LayerPropertiesViewModel);
|
||||
}
|
||||
|
||||
public void ToggleIsEvent()
|
||||
{
|
||||
EventPropertiesViewModel = ProposedLayer.IsEvent
|
||||
? new EventPropertiesViewModel(Layer.EventProperties)
|
||||
: null;
|
||||
}
|
||||
|
||||
public void AddCondition()
|
||||
{
|
||||
var condition = new LayerConditionModel();
|
||||
@ -158,19 +165,20 @@ namespace Artemis.ViewModels.Profiles
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
Layer.Name = ProposedLayer.Name;
|
||||
Layer.LayerType = ProposedLayer.LayerType;
|
||||
LayerPropertiesViewModel?.ApplyProperties();
|
||||
Layer = GeneralHelpers.Clone(ProposedLayer);
|
||||
|
||||
// TODO: EventPropVM must have layer too
|
||||
if (EventPropertiesViewModel != null)
|
||||
Layer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
|
||||
|
||||
if (LayerPropertiesViewModel != null)
|
||||
Layer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
|
||||
Layer.Properties.Conditions.Clear();
|
||||
foreach (var conditionViewModel in LayerConditionVms)
|
||||
{
|
||||
Layer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
|
||||
}
|
||||
|
||||
if (Layer.LayerType != LayerType.KeyboardGif)
|
||||
return; // Don't bother checking for a GIF path unless the type is GIF
|
||||
// Don't bother checking for a GIF path unless the type is GIF
|
||||
if (!(Layer.LayerType is KeyboardGifType))
|
||||
return;
|
||||
if (!File.Exists(((KeyboardPropertiesModel) Layer.Properties).GifFile))
|
||||
DialogService.ShowErrorMessageBox("Couldn't find or access the provided GIF file.");
|
||||
}
|
||||
@ -185,25 +193,26 @@ namespace Artemis.ViewModels.Profiles
|
||||
public override async void CanClose(Action<bool> callback)
|
||||
{
|
||||
// Create a fake layer and apply the properties to it
|
||||
var fakeLayer = GeneralHelpers.Clone(ProposedLayer);
|
||||
if (LayerPropertiesViewModel != null)
|
||||
fakeLayer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
|
||||
fakeLayer.Properties.Conditions.Clear();
|
||||
LayerPropertiesViewModel?.ApplyProperties();
|
||||
// TODO: EventPropVM must have layer too
|
||||
if (EventPropertiesViewModel != null)
|
||||
ProposedLayer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
|
||||
ProposedLayer.Properties.Conditions.Clear();
|
||||
foreach (var conditionViewModel in LayerConditionVms)
|
||||
fakeLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
|
||||
ProposedLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
|
||||
|
||||
|
||||
var fake = GeneralHelpers.Serialize(fakeLayer);
|
||||
var real = GeneralHelpers.Serialize(Layer);
|
||||
var current = JsonConvert.SerializeObject(Layer, Formatting.Indented);
|
||||
var proposed = JsonConvert.SerializeObject(ProposedLayer, Formatting.Indented);
|
||||
|
||||
if (fake.Equals(real))
|
||||
if (current.Equals(proposed))
|
||||
{
|
||||
callback(true);
|
||||
return;
|
||||
}
|
||||
|
||||
var close =
|
||||
await DialogService.ShowQuestionMessageBox("Unsaved changes", "Do you want to discard your changes?");
|
||||
var close = await DialogService
|
||||
.ShowQuestionMessageBox("Unsaved changes", "Do you want to discard your changes?");
|
||||
callback(close.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
|
||||
namespace Artemis.ViewModels.Profiles.Layers
|
||||
{
|
||||
public class FolderPropertiesViewModel : LayerPropertiesViewModel
|
||||
{
|
||||
public FolderPropertiesViewModel(LayerModel layerModel, IDataModel dataModel) : base(layerModel, dataModel)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ApplyProperties()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.ViewModels.Profiles.Layers
|
||||
{
|
||||
public class HeadsetPropertiesViewModel : LayerPropertiesViewModel
|
||||
{
|
||||
private ILayerAnimation _selectedLayerAnimation;
|
||||
|
||||
public HeadsetPropertiesViewModel(LayerModel layerModel, IDataModel dataModel,
|
||||
IEnumerable<ILayerAnimation> layerAnimations) : base(layerModel, dataModel)
|
||||
{
|
||||
LayerAnimations = new BindableCollection<ILayerAnimation>(layerAnimations);
|
||||
OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity",
|
||||
new BindableCollection<GeneralHelpers.PropertyCollection>(GeneralHelpers.GenerateTypeMap(dataModel)),
|
||||
layerModel.Properties);
|
||||
}
|
||||
|
||||
public BindableCollection<ILayerAnimation> LayerAnimations { get; set; }
|
||||
public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
|
||||
|
||||
public ILayerAnimation SelectedLayerAnimation
|
||||
{
|
||||
get { return _selectedLayerAnimation; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _selectedLayerAnimation)) return;
|
||||
_selectedLayerAnimation = value;
|
||||
NotifyOfPropertyChange(() => SelectedLayerAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ApplyProperties()
|
||||
{
|
||||
OpacityProperties.Apply(LayerModel);
|
||||
LayerModel.Properties.Brush = Brush;
|
||||
LayerModel.LayerAnimation = SelectedLayerAnimation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Artemis.Models.Interfaces;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Caliburn.Micro;
|
||||
using static Artemis.Utilities.GeneralHelpers;
|
||||
|
||||
namespace Artemis.ViewModels.Profiles.Layers
|
||||
{
|
||||
public class KeyboardPropertiesViewModel : LayerPropertiesViewModel
|
||||
{
|
||||
private bool _isGif;
|
||||
private ILayerAnimation _selectedLayerAnimation;
|
||||
|
||||
public KeyboardPropertiesViewModel(LayerModel layerModel, IDataModel dataModel,
|
||||
IEnumerable<ILayerAnimation> layerAnimations) : base(layerModel, dataModel)
|
||||
{
|
||||
LayerAnimations = new BindableCollection<ILayerAnimation>(layerAnimations);
|
||||
|
||||
var dataModelProps = new BindableCollection<PropertyCollection>(GenerateTypeMap(dataModel));
|
||||
HeightProperties = new LayerDynamicPropertiesViewModel("Height", dataModelProps, layerModel.Properties);
|
||||
WidthProperties = new LayerDynamicPropertiesViewModel("Width", dataModelProps, layerModel.Properties);
|
||||
OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity", dataModelProps, layerModel.Properties);
|
||||
|
||||
SelectedLayerAnimation = LayerAnimations.FirstOrDefault(l => l.Name == layerModel.LayerAnimation?.Name) ??
|
||||
LayerAnimations.First(l => l.Name == "None");
|
||||
}
|
||||
|
||||
public bool ShowGif => IsGif;
|
||||
public bool ShowBrush => !IsGif;
|
||||
public BindableCollection<PropertyCollection> DataModelProps { get; set; }
|
||||
public BindableCollection<ILayerAnimation> LayerAnimations { get; set; }
|
||||
public LayerDynamicPropertiesViewModel HeightProperties { get; set; }
|
||||
public LayerDynamicPropertiesViewModel WidthProperties { get; set; }
|
||||
public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
|
||||
|
||||
public bool IsGif
|
||||
{
|
||||
get { return _isGif; }
|
||||
set
|
||||
{
|
||||
_isGif = value;
|
||||
NotifyOfPropertyChange(() => ShowGif);
|
||||
NotifyOfPropertyChange(() => ShowBrush);
|
||||
}
|
||||
}
|
||||
|
||||
public ILayerAnimation SelectedLayerAnimation
|
||||
{
|
||||
get { return _selectedLayerAnimation; }
|
||||
set
|
||||
{
|
||||
if (Equals(value, _selectedLayerAnimation)) return;
|
||||
_selectedLayerAnimation = value;
|
||||
NotifyOfPropertyChange(() => SelectedLayerAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
public void BrowseGif()
|
||||
{
|
||||
var dialog = new OpenFileDialog {Filter = "Animated image file (*.gif)|*.gif"};
|
||||
var result = dialog.ShowDialog();
|
||||
if (result != DialogResult.OK)
|
||||
return;
|
||||
|
||||
((KeyboardPropertiesModel) LayerModel.Properties).GifFile = dialog.FileName;
|
||||
NotifyOfPropertyChange(() => LayerModel);
|
||||
}
|
||||
|
||||
public override void ApplyProperties()
|
||||
{
|
||||
HeightProperties.Apply(LayerModel);
|
||||
WidthProperties.Apply(LayerModel);
|
||||
OpacityProperties.Apply(LayerModel);
|
||||
LayerModel.Properties.Brush = Brush;
|
||||
|
||||
LayerModel.LayerAnimation = SelectedLayerAnimation;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user