mirror of
https://github.com/vale981/VoiDPlugins
synced 2025-03-05 17:21:38 -05:00
Fix relative mode issues
This commit is contained in:
parent
aa6c011fd8
commit
59eed1faa5
9 changed files with 84 additions and 90 deletions
|
@ -20,13 +20,17 @@ namespace VoiDPlugins.OutputMode
|
||||||
|
|
||||||
public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen)
|
public VMultiAbsolutePointer(TabletReference tabletReference, IVirtualScreen virtualScreen)
|
||||||
{
|
{
|
||||||
_instance = new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
|
|
||||||
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
||||||
if (!sharedStore.TryAdd(INSTANCE, _instance))
|
_instance = sharedStore.GetOrUpdate(ABS_INSTANCE, createInstance, out _);
|
||||||
_instance = sharedStore.Get<VMultiInstance<AbsoluteInputReport>>(INSTANCE);
|
|
||||||
|
|
||||||
_rawPointer = _instance.Pointer;
|
_rawPointer = _instance.Pointer;
|
||||||
_conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height);
|
_conversionFactor = new Vector2(32767, 32767) / new Vector2(virtualScreen.Width, virtualScreen.Height);
|
||||||
|
|
||||||
|
sharedStore.SetOrAdd(MODE, ABS_INSTANCE);
|
||||||
|
|
||||||
|
static VMultiInstance<AbsoluteInputReport> createInstance()
|
||||||
|
{
|
||||||
|
return new VMultiInstance<AbsoluteInputReport>("VMultiAbs", new AbsoluteInputReport());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPosition(Vector2 pos)
|
public void SetPosition(Vector2 pos)
|
||||||
|
|
|
@ -18,20 +18,22 @@ namespace VoiDPlugins.OutputMode
|
||||||
|
|
||||||
public VMultiRelativePointer(TabletReference tabletReference)
|
public VMultiRelativePointer(TabletReference tabletReference)
|
||||||
{
|
{
|
||||||
_instance = new VMultiInstance<RelativeInputReport>("VMultiRel", new RelativeInputReport());
|
|
||||||
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
||||||
if (!sharedStore.TryAdd(INSTANCE, _instance))
|
_instance = sharedStore.GetOrUpdate(REL_INSTANCE, createInstance, out var updated);
|
||||||
_instance = sharedStore.Get<VMultiInstance<RelativeInputReport>>(INSTANCE);
|
|
||||||
|
|
||||||
_rawPointer = _instance.Pointer;
|
_rawPointer = _instance.Pointer;
|
||||||
|
|
||||||
|
sharedStore.SetOrAdd(MODE, REL_INSTANCE);
|
||||||
|
|
||||||
|
static VMultiInstance<RelativeInputReport> createInstance()
|
||||||
|
{
|
||||||
|
return new VMultiInstance<RelativeInputReport>("VMultiRel", new RelativeInputReport());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPosition(Vector2 delta)
|
public void SetPosition(Vector2 delta)
|
||||||
{
|
{
|
||||||
if (delta == Vector2.Zero && _prev == Vector2.Zero)
|
if (delta == Vector2.Zero && _prev == Vector2.Zero)
|
||||||
return;
|
return;
|
||||||
if (_rawPointer is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
delta += _error;
|
delta += _error;
|
||||||
_error = new Vector2(delta.X % 1, delta.Y % 1);
|
_error = new Vector2(delta.X % 1, delta.Y % 1);
|
||||||
|
|
|
@ -33,7 +33,9 @@ namespace VoiDPlugins.OutputMode
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_instance = SharedStore.GetStore(tabletReference, STORE_KEY).Get<VMultiInstance>(INSTANCE);
|
var sharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
||||||
|
var mode = sharedStore.Get<int>(MODE);
|
||||||
|
_instance = sharedStore.Get<VMultiInstance>(mode);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,8 @@ namespace VoiDPlugins.OutputMode
|
||||||
public static class VMultiModeConstants
|
public static class VMultiModeConstants
|
||||||
{
|
{
|
||||||
public const string STORE_KEY = "VMultiMode";
|
public const string STORE_KEY = "VMultiMode";
|
||||||
public const int INSTANCE = 0;
|
public const int MODE = 0;
|
||||||
|
public const int ABS_INSTANCE = 1;
|
||||||
|
public const int REL_INSTANCE = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,13 +7,11 @@ namespace VoiDPlugins.OutputMode
|
||||||
{
|
{
|
||||||
public unsafe class WinInkAbsolutePointer : WinInkBasePointer, IAbsolutePointer
|
public unsafe class WinInkAbsolutePointer : WinInkBasePointer, IAbsolutePointer
|
||||||
{
|
{
|
||||||
private readonly Vector2 _conversionFactor;
|
|
||||||
private Vector2 _prev;
|
private Vector2 _prev;
|
||||||
|
|
||||||
public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen)
|
public WinInkAbsolutePointer(TabletReference tabletReference, IVirtualScreen screen)
|
||||||
: base("Windows Ink", tabletReference, screen)
|
: base("Windows Ink", tabletReference, screen)
|
||||||
{
|
{
|
||||||
_conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPosition(Vector2 pos)
|
public void SetPosition(Vector2 pos)
|
||||||
|
@ -23,7 +21,7 @@ namespace VoiDPlugins.OutputMode
|
||||||
|
|
||||||
SetInternalPosition(pos);
|
SetInternalPosition(pos);
|
||||||
Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
|
Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
|
||||||
pos *= _conversionFactor;
|
pos = Convert(pos);
|
||||||
RawPointer->X = (ushort)pos.X;
|
RawPointer->X = (ushort)pos.X;
|
||||||
RawPointer->Y = (ushort)pos.Y;
|
RawPointer->Y = (ushort)pos.Y;
|
||||||
Dirty = true;
|
Dirty = true;
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace VoiDPlugins.OutputMode
|
||||||
{
|
{
|
||||||
public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer
|
public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer
|
||||||
{
|
{
|
||||||
|
private readonly Vector2 _conversionFactor;
|
||||||
private readonly IVirtualScreen _screen;
|
private readonly IVirtualScreen _screen;
|
||||||
private ThinOSPointer? _osPointer;
|
private ThinOSPointer? _osPointer;
|
||||||
private Vector2 _internalPos;
|
private Vector2 _internalPos;
|
||||||
|
@ -30,20 +31,22 @@ namespace VoiDPlugins.OutputMode
|
||||||
public WinInkBasePointer(string name, TabletReference tabletReference, IVirtualScreen screen)
|
public WinInkBasePointer(string name, TabletReference tabletReference, IVirtualScreen screen)
|
||||||
{
|
{
|
||||||
_screen = screen;
|
_screen = screen;
|
||||||
Instance = new VMultiInstance<DigitizerInputReport>(name, new DigitizerInputReport());
|
_conversionFactor = new Vector2(32767, 32767) / new Vector2(screen.Width, screen.Height);
|
||||||
SharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
SharedStore = SharedStore.GetStore(tabletReference, STORE_KEY);
|
||||||
if (SharedStore.TryAdd(INSTANCE, Instance))
|
Instance = SharedStore.GetOrUpdate(INSTANCE, createInstance, out var updated);
|
||||||
{
|
|
||||||
SharedStore.TryAdd(POINTER, this);
|
|
||||||
SharedStore.TryAdd(ERASER_STATE, false);
|
|
||||||
SharedStore.TryAdd(MANUAL_ERASER, false);
|
|
||||||
SharedStore.TryAdd(TIP_PRESSED, false);
|
|
||||||
RawPointer = Instance.Pointer;
|
RawPointer = Instance.Pointer;
|
||||||
|
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
SharedStore.SetOrAdd(POINTER, this);
|
||||||
|
SharedStore.SetOrAdd(ERASER_STATE, false);
|
||||||
|
SharedStore.SetOrAdd(MANUAL_ERASER, false);
|
||||||
|
SharedStore.SetOrAdd(TIP_PRESSED, false);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
VMultiInstance<DigitizerInputReport> createInstance()
|
||||||
{
|
{
|
||||||
Instance = SharedStore.Get<VMultiInstance<DigitizerInputReport>>(INSTANCE);
|
return new VMultiInstance<DigitizerInputReport>(name, new DigitizerInputReport());
|
||||||
RawPointer = Instance.Pointer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +90,11 @@ namespace VoiDPlugins.OutputMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Vector2 Convert(Vector2 pos)
|
||||||
|
{
|
||||||
|
return pos * _conversionFactor;
|
||||||
|
}
|
||||||
|
|
||||||
protected void SetInternalPosition(Vector2 pos)
|
protected void SetInternalPosition(Vector2 pos)
|
||||||
{
|
{
|
||||||
_internalPos = pos;
|
_internalPos = pos;
|
||||||
|
|
|
@ -21,16 +21,18 @@ namespace VoiDPlugins.OutputMode
|
||||||
|
|
||||||
public void SetPosition(Vector2 delta)
|
public void SetPosition(Vector2 delta)
|
||||||
{
|
{
|
||||||
if (_prev == Vector2.Zero && delta == Vector2.Zero)
|
if (delta == Vector2.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
|
|
||||||
delta += _error;
|
delta += _error;
|
||||||
_error = new Vector2(delta.X % 1, delta.Y % 1);
|
_error = new Vector2(delta.X % 1, delta.Y % 1);
|
||||||
_currentPoint = Vector2.Clamp(_currentPoint + delta, Vector2.Zero, _maxPoint);
|
_currentPoint = Vector2.Clamp(_currentPoint + delta, Vector2.Zero, _maxPoint);
|
||||||
|
|
||||||
SetInternalPosition(_currentPoint);
|
SetInternalPosition(_currentPoint);
|
||||||
RawPointer->X = (ushort)_currentPoint.X;
|
Instance.EnableButtonBit((int)WindowsInkButtonFlags.InRange);
|
||||||
RawPointer->Y = (ushort)_currentPoint.Y;
|
var pos = Convert(_currentPoint);
|
||||||
|
RawPointer->X = (ushort)pos.X;
|
||||||
|
RawPointer->Y = (ushort)pos.Y;
|
||||||
Dirty = true;
|
Dirty = true;
|
||||||
_prev = delta;
|
_prev = delta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace VoiDPlugins.OutputMode
|
||||||
_instance.Write();
|
_instance.Write();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EraserStateTransition(SharedStore store, VMultiInstance instance, bool isEraser)
|
internal static void EraserStateTransition(SharedStore store, VMultiInstance instance, bool isEraser)
|
||||||
{
|
{
|
||||||
var eraserState = store.Get<bool>(ERASER_STATE);
|
var eraserState = store.Get<bool>(ERASER_STATE);
|
||||||
if (eraserState != isEraser)
|
if (eraserState != isEraser)
|
||||||
|
|
|
@ -1,23 +1,16 @@
|
||||||
using System.Collections;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using OpenTabletDriver.Plugin.Tablet;
|
using OpenTabletDriver.Plugin.Tablet;
|
||||||
|
|
||||||
namespace VoiDPlugins.Library.VoiD
|
namespace VoiDPlugins.Library.VoiD
|
||||||
{
|
{
|
||||||
public class SharedStore : IDictionary<int, object>
|
public class SharedStore
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<TabletReference, Dictionary<string, SharedStore>> _storeMap = new(new Comparer());
|
private static readonly Dictionary<TabletReference, Dictionary<string, SharedStore>> _storeMap = new(new Comparer());
|
||||||
|
|
||||||
private readonly Dictionary<int, object> _sharedStore = new();
|
private readonly Dictionary<int, object> _sharedStore = new();
|
||||||
|
|
||||||
public object this[int key] { get => ((IDictionary<int, object>)_sharedStore)[key]; set => ((IDictionary<int, object>)_sharedStore)[key] = value; }
|
|
||||||
public ICollection<int> Keys => ((IDictionary<int, object>)_sharedStore).Keys;
|
|
||||||
public ICollection<object> Values => ((IDictionary<int, object>)_sharedStore).Values;
|
|
||||||
public int Count => ((ICollection<KeyValuePair<int, object>>)_sharedStore).Count;
|
|
||||||
public bool IsReadOnly => ((ICollection<KeyValuePair<int, object>>)_sharedStore).IsReadOnly;
|
|
||||||
|
|
||||||
public static SharedStore GetStore(TabletReference reference, string storeKey)
|
public static SharedStore GetStore(TabletReference reference, string storeKey)
|
||||||
{
|
{
|
||||||
lock (_storeMap)
|
lock (_storeMap)
|
||||||
|
@ -39,69 +32,52 @@ namespace VoiDPlugins.Library.VoiD
|
||||||
return (T)_sharedStore[key];
|
return (T)_sharedStore[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T GetOrUpdate<T>(int key, Func<T> valueFactory, out bool updated)
|
||||||
|
{
|
||||||
|
if (_sharedStore.TryGetValue(key, out object? value) && SafeCast<T>(value) is T casted)
|
||||||
|
{
|
||||||
|
updated = false;
|
||||||
|
return casted;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValue = valueFactory();
|
||||||
|
_sharedStore[key] = newValue!;
|
||||||
|
updated = true;
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
public void Set<T>(int key, T value)
|
public void Set<T>(int key, T value)
|
||||||
{
|
{
|
||||||
_sharedStore[key] = value!;
|
_sharedStore[key] = value!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(int key, object value)
|
public void Add<T>(int key, T value)
|
||||||
{
|
{
|
||||||
((IDictionary<int, object>)_sharedStore).Add(key, value);
|
_sharedStore.Add(key, value!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryAdd(int key, object value)
|
public void SetOrAdd<T>(int key, T value)
|
||||||
{
|
{
|
||||||
return _sharedStore.TryAdd(key, value);
|
if (_sharedStore.ContainsKey(key))
|
||||||
|
{
|
||||||
|
_sharedStore[key] = value!;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sharedStore.Add(key, value!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(KeyValuePair<int, object> item)
|
private static T? SafeCast<T>(object value)
|
||||||
{
|
{
|
||||||
((ICollection<KeyValuePair<int, object>>)_sharedStore).Add(item);
|
try
|
||||||
|
{
|
||||||
|
return (T)value;
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
public void Clear()
|
|
||||||
{
|
{
|
||||||
((ICollection<KeyValuePair<int, object>>)_sharedStore).Clear();
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(KeyValuePair<int, object> item)
|
|
||||||
{
|
|
||||||
return ((ICollection<KeyValuePair<int, object>>)_sharedStore).Contains(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContainsKey(int key)
|
|
||||||
{
|
|
||||||
return ((IDictionary<int, object>)_sharedStore).ContainsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(KeyValuePair<int, object>[] array, int arrayIndex)
|
|
||||||
{
|
|
||||||
((ICollection<KeyValuePair<int, object>>)_sharedStore).CopyTo(array, arrayIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<int, object>> GetEnumerator()
|
|
||||||
{
|
|
||||||
return ((IEnumerable<KeyValuePair<int, object>>)_sharedStore).GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(int key)
|
|
||||||
{
|
|
||||||
return ((IDictionary<int, object>)_sharedStore).Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(KeyValuePair<int, object> item)
|
|
||||||
{
|
|
||||||
return ((ICollection<KeyValuePair<int, object>>)_sharedStore).Remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetValue(int key, [MaybeNullWhen(false)] out object value)
|
|
||||||
{
|
|
||||||
return ((IDictionary<int, object>)_sharedStore).TryGetValue(key, out value);
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return ((IEnumerable)_sharedStore).GetEnumerator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Comparer : IEqualityComparer<TabletReference>
|
private class Comparer : IEqualityComparer<TabletReference>
|
||||||
|
|
Loading…
Add table
Reference in a new issue