| File: System\Windows\Input\Stylus\Common\StylusPlugin.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationCore\PresentationCore.csproj (PresentationCore) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // #define TRACE namespace System.Windows.Input.StylusPlugIns { ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] /// </summary> public abstract class StylusPlugIn { ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on Dispatcher /// </summary> protected StylusPlugIn() { } ///////////////////////////////////////////////////////////////////// // (in Dispatcher) internal void Added(StylusPlugInCollection plugInCollection) { _pic = plugInCollection; OnAdded(); InvalidateIsActiveForInput(); // Make sure we fire OnIsActivateForInputChanged. } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on Dispatcher /// </summary> protected virtual void OnAdded() { } ///////////////////////////////////////////////////////////////////// // (in Dispatcher) internal void Removed() { // Make sure we fire OnIsActivateForInputChanged if we need to. if (_activeForInput) { InvalidateIsActiveForInput(); } OnRemoved(); _pic = null; } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on Dispatcher /// </summary> protected virtual void OnRemoved() { } ///////////////////////////////////////////////////////////////////// // (in RTI Dispatcher) internal void StylusEnterLeave(bool isEnter, RawStylusInput rawStylusInput, bool confirmed) { // Only fire if plugin is enabled and hooked up to plugincollection. if (__enabled && _pic != null) { if (isEnter) OnStylusEnter(rawStylusInput, confirmed); else OnStylusLeave(rawStylusInput, confirmed); } } ///////////////////////////////////////////////////////////////////// // (in RTI Dispatcher) internal void RawStylusInput(RawStylusInput rawStylusInput) { // Only fire if plugin is enabled and hooked up to plugincollection. if (__enabled && _pic != null) { switch (rawStylusInput.Report.Actions) { case RawStylusActions.Down: OnStylusDown(rawStylusInput); break; case RawStylusActions.Move: OnStylusMove(rawStylusInput); break; case RawStylusActions.Up: OnStylusUp(rawStylusInput); break; } } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusEnter(RawStylusInput rawStylusInput, bool confirmed) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusLeave(RawStylusInput rawStylusInput, bool confirmed) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusDown(RawStylusInput rawStylusInput) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusMove(RawStylusInput rawStylusInput) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusUp(RawStylusInput rawStylusInput) { } ///////////////////////////////////////////////////////////////////// // (on app Dispatcher) internal void FireCustomData(object callbackData, RawStylusActions action, bool targetVerified) { // Only fire if plugin is enabled and hooked up to plugincollection. if (__enabled && _pic != null) { switch (action) { case RawStylusActions.Down: OnStylusDownProcessed(callbackData, targetVerified); break; case RawStylusActions.Move: OnStylusMoveProcessed(callbackData, targetVerified); break; case RawStylusActions.Up: OnStylusUpProcessed(callbackData, targetVerified); break; } } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on app Dispatcher /// </summary> protected virtual void OnStylusDownProcessed(object callbackData, bool targetVerified) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on app Dispatcher /// </summary> protected virtual void OnStylusMoveProcessed(object callbackData, bool targetVerified) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on app Dispatcher /// </summary> protected virtual void OnStylusUpProcessed(object callbackData, bool targetVerified) { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - both Dispatchers /// </summary> public UIElement Element { get { return _pic?.Element; } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - both Dispatchers /// </summary> public Rect ElementBounds { get { return (_pic != null) ? _pic.Rect : new Rect(); } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - get - both Dispatchers, set Dispatcher /// </summary> public bool Enabled { get // both Dispatchers { return __enabled; } set // on Dispatcher { // Verify we are on the proper thread. _pic?.Element.VerifyAccess(); if (value != __enabled) { // If we are currently active for input we need to lock before input before // changing so we don't get input coming in before event is fired. if (_pic != null && _pic.IsActiveForInput) { // Make sure lock() doesn't cause reentrancy. using (_pic.Element.Dispatcher.DisableProcessing()) { _pic.ExecuteWithPotentialLock(() => { // Make sure we fire the OnEnabledChanged event in the proper order // depending on whether we are going active or inactive so you don't // get input events after going inactive or before going active. __enabled = value; if (!value) { // Make sure we fire OnIsActivateForInputChanged if we need to. InvalidateIsActiveForInput(); OnEnabledChanged(); } else { OnEnabledChanged(); InvalidateIsActiveForInput(); } }); } } else { __enabled = value; if (!value) { // Make sure we fire OnIsActivateForInputChanged if we need to. InvalidateIsActiveForInput(); OnEnabledChanged(); } else { OnEnabledChanged(); InvalidateIsActiveForInput(); } } } } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on app Dispatcher /// </summary> protected virtual void OnEnabledChanged() { } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - app Dispatcher /// </summary> internal void InvalidateIsActiveForInput() { bool newIsActive = (_pic != null) ? (Enabled && _pic.Contains(this) && _pic.IsActiveForInput) : false; if (newIsActive != _activeForInput) { _activeForInput = newIsActive; OnIsActiveForInputChanged(); } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - get - both Dispatchers /// </summary> public bool IsActiveForInput { get // both Dispatchers { return _activeForInput; } } ///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on Dispatcher /// </summary> protected virtual void OnIsActiveForInputChanged() { } // Enabled state is local to this plugin so we just use volatile versus creating a lock // around it since we just read it from multiple thread and write from one. private volatile bool __enabled = true; private bool _activeForInput = false; private StylusPlugInCollection _pic = null; } }