notify property changed with magic

master
logchan 2020-02-13 11:03:04 -05:00
parent f2e37b7afe
commit 126691c780
7 changed files with 57 additions and 8 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
.vs/
bin/
obj/
obj/
packages/

View File

@ -1,5 +1,9 @@
namespace chuni_hands {
public sealed class Config {
public sealed class Config : Helpers.PropertyChangedInvoker {
static Config() {
Helpers.PatchNotifyPropertyChanged<Config>();
}
public int OffsetX { get; set; }
public int OffsetY { get; set; }
public int Exposure { get; set; } = -6;

View File

@ -1,6 +1,11 @@
using System.Diagnostics;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Threading;
using Harmony;
using Newtonsoft.Json;
namespace chuni_hands {
@ -18,5 +23,34 @@ namespace chuni_hands {
public static string GetVersion() {
return FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
}
private static HarmonyInstance _harmony = HarmonyInstance.Create("co.logu.chuni-hands.helpers");
public static void PatchNotifyPropertyChanged<T>() where T : PropertyChangedInvoker {
var type = typeof(T);
var patch = typeof(Helpers).GetMethod("PropertyChangedPostfix", BindingFlags.NonPublic | BindingFlags.Static);
Debug.Assert(patch != null, nameof(patch) + " != null");
patch = patch.MakeGenericMethod(type);
foreach (var method in type.GetProperties().Select(p => p.SetMethod)) {
_harmony.Patch(method, new HarmonyMethod(patch));
}
}
// ReSharper disable InconsistentNaming
// ReSharper disable once UnusedMember.Local
private static void PropertyChangedPostfix<T>(MethodBase __originalMethod, T __instance) where T : PropertyChangedInvoker {
__instance.InvokePropertyChanged(__originalMethod.Name.Substring(4)); // remove set_
}
// ReSharper restore InconsistentNaming
public abstract class PropertyChangedInvoker : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public virtual void InvokePropertyChanged(string propertyName) {
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}));
}
}
}
}

View File

@ -16,7 +16,7 @@
<Grid Grid.Column="0" Margin="12">
<local:ChuniCanvas x:Name="TheCanvas"></local:ChuniCanvas>
</Grid>
<DockPanel Grid.Column="1" LastChildFill="True">
<DockPanel Grid.Column="1" LastChildFill="True" DataContext="{Binding ElementName=TheWindow, Path=Config}">
<StackPanel DockPanel.Dock="Top" Margin="12">
<Button x:Name="ResetButton" Click="ResetButton_Click">Reset</Button>
<DockPanel LastChildFill="True">
@ -26,17 +26,18 @@
</DockPanel>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left">Distance </TextBlock>
<Slider DockPanel.Dock="Right" Value="{Binding ElementName=TheWindow, Path=Config.Distance, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="20" Maximum="100"></Slider>
<Slider DockPanel.Dock="Right" Value="{Binding Path=Distance, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="20" Maximum="100"></Slider>
</DockPanel>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left">X</TextBlock>
<Slider DockPanel.Dock="Right" Value="{Binding ElementName=TheWindow, Path=Config.OffsetX, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="-320" Maximum="320"></Slider>
<Slider DockPanel.Dock="Right" Value="{Binding Path=OffsetX, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="-320" Maximum="320"></Slider>
</DockPanel>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left">Y</TextBlock>
<Slider DockPanel.Dock="Right" Value="{Binding ElementName=TheWindow, Path=Config.OffsetY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="-240" Maximum="240"></Slider>
<Slider DockPanel.Dock="Right" Value="{Binding Path=OffsetY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="-240" Maximum="240"></Slider>
</DockPanel>
<CheckBox IsChecked="{Binding ElementName=TheWindow, Path=Config.LogDiff, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">Log diff</CheckBox>
<Button x:Name="CenterButton" Click="CenterButton_Click">Center</Button>
<CheckBox IsChecked="{Binding Path=LogDiff, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">Log diff</CheckBox>
</StackPanel>
<RichTextBox DockPanel.Dock="Bottom" x:Name="LogBox">

View File

@ -150,5 +150,10 @@ namespace chuni_hands {
_config.Threshold = v;
}
}
private void CenterButton_Click(object sender, RoutedEventArgs e) {
_config.OffsetX = 0;
_config.OffsetY = 0;
}
}
}

View File

@ -57,6 +57,9 @@
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony, Version=1.2.0.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Lib.Harmony.1.2.0.1\lib\net472\0Harmony.dll</HintPath>
</Reference>
<Reference Include="Emgu.CV.World.Netstandard">
<HintPath>C:\Emgu\emgucv-windesktop 4.2.0.3662\bin\Emgu.CV.World.Netstandard.dll</HintPath>
</Reference>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Lib.Harmony" version="1.2.0.1" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
</packages>