/// <summary> /// Fire RawStylusInputEvent for all the StylusPlugIns /// This method is called from the real-time context (pen thread) only /// </summary> /// <param name="args"></param> internal void FireRawStylusInput(RawStylusInput args) { try { if (IsActiveForInput) { // If we are currently active for input then we have a _penContexts that we must lock! lock (PenContextsSyncRoot) { for (int i = 0; i < this.Count; i++) { StylusPlugIn plugIn = base[i]; // set current plugin so any callback data gets an owner. args.CurrentNotifyPlugIn = plugIn; plugIn.RawStylusInput(args); } } } else { for (int i = 0; i < this.Count; i++) { StylusPlugIn plugIn = base[i]; // set current plugin so any callback data gets an owner. args.CurrentNotifyPlugIn = plugIn; plugIn.RawStylusInput(args); } } } finally { args.CurrentNotifyPlugIn = null; } }
/// <summary> /// Fire RawStylusInputEvent for all the StylusPlugIns /// This method is called from the real-time context (pen thread) only /// </summary> /// <param name="args"></param> internal void FireRawStylusInput(RawStylusInput args) { try { if (_stylusPlugInCollectionImpl.IsActiveForInput) { // If we are currently active for input then we have a _penContexts that we must lock! ExecuteWithPotentialLock(() => { for (int i = 0; i < this.Count; i++) { StylusPlugIn plugIn = base[i]; // set current plugin so any callback data gets an owner. args.CurrentNotifyPlugIn = plugIn; plugIn.RawStylusInput(args); } }); } else { for (int i = 0; i < this.Count; i++) { StylusPlugIn plugIn = base[i]; // set current plugin so any callback data gets an owner. args.CurrentNotifyPlugIn = plugIn; plugIn.RawStylusInput(args); } } } finally { args.CurrentNotifyPlugIn = null; } }
protected override void OnStylusMove(RawStylusInput rawStylusInput) { var movePoint = rawStylusInput.GetStylusPoints()[0]; var now = DateTime.Now; var stamp = (now - currentStroke.DownStylusPointStamp).Ticks; currentStroke.StampedStylusPoints.Add(new StampedStylusPoint { Stamp = stamp, StylusPoint = movePoint }); base.OnStylusMove(rawStylusInput); }
///////////////////////////////////////////////////////////////////// // (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 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; } } }
///////////////////////////////////////////////////////////////////// // (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> /// Fire the Enter notification. /// This method is called from pen threads and app thread. /// </summary> internal void FireEnterLeave(bool isEnter, RawStylusInput rawStylusInput, bool confirmed) { if (_stylusPlugInCollectionImpl.IsActiveForInput) { // If we are currently active for input then we have a _penContexts that we must lock! ExecuteWithPotentialLock(() => { for (int i = 0; i < this.Count; i++) { base[i].StylusEnterLeave(isEnter, rawStylusInput, confirmed); } }); } else { for (int i = 0; i < this.Count; i++) { base[i].StylusEnterLeave(isEnter, rawStylusInput, confirmed); } } }
/// <summary> /// Fire the Enter notification. /// This method is called from pen threads and app thread. /// </summary> internal void FireEnterLeave(bool isEnter, RawStylusInput rawStylusInput, bool confirmed) { if (IsActiveForInput) { // If we are currently active for input then we have a _penContexts that we must lock! lock (PenContextsSyncRoot) { for (int i = 0; i < this.Count; i++) { base[i].StylusEnterLeave(isEnter, rawStylusInput, confirmed); } } } else { for (int i = 0; i < this.Count; i++) { base[i].StylusEnterLeave(isEnter, rawStylusInput, confirmed); } } }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusUp(RawStylusInput rawStylusInput) { }
protected virtual new void OnStylusDown(RawStylusInput rawStylusInput) { }
private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusInputReport) { switch (rawStylusInputReport.Actions) { case RawStylusActions.Down: case RawStylusActions.Move: case RawStylusActions.Up: break; default: return; // do nothing if not Down, Move or Up. } RawStylusInput originalRSI = rawStylusInputReport.RawStylusInput; // See if we have a plugin for the target of this input. StylusPlugInCollection targetPIC = null; StylusPlugInCollection targetRtiPIC = (originalRSI != null) ? originalRSI.Target : null; bool updateEventPoints = false; // Make sure we use UIElement for target if non NULL and hit ContentElement. UIElement newTarget = InputElement.GetContainingUIElement(rawStylusInputReport.StylusDevice.DirectlyOver as DependencyObject) as UIElement; if (newTarget != null) { targetPIC = rawStylusInputReport.PenContext.Contexts.FindPlugInCollection(newTarget); } // Make sure any lock() calls do not reenter on us. using(Dispatcher.DisableProcessing()) { // See if we hit the wrong PlugInCollection on the pen thread and clean things up if we did. if (targetRtiPIC != null && targetRtiPIC != targetPIC && originalRSI != null) { // Fire custom data not confirmed events for both pre and post since bad target... foreach (RawStylusInputCustomData customData in originalRSI.CustomDataList) { customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, false); } updateEventPoints = originalRSI.StylusPointsModified; // Clear RawStylusInput data. rawStylusInputReport.RawStylusInput = null; } // See if we need to build up an RSI to send to the plugincollection (due to a mistarget). bool sendRawStylusInput = false; if (targetPIC != null && rawStylusInputReport.RawStylusInput == null) { // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine) // The transformTabletToView matrix and plugincollection rects though can change based // off of layout events which is why we need to lock this. GeneralTransformGroup transformTabletToView = new GeneralTransformGroup(); transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) transformTabletToView.Children.Add(targetPIC.ViewToElement); // Make it relative to the element. transformTabletToView.Freeze(); // Must be frozen for multi-threaded access. RawStylusInput rawStylusInput = new RawStylusInput(rawStylusInputReport, transformTabletToView, targetPIC); rawStylusInputReport.RawStylusInput = rawStylusInput; sendRawStylusInput = true; } // Now fire the confirmed enter/leave events as necessary. StylusPlugInCollection currentTarget = rawStylusInputReport.StylusDevice.CurrentVerifiedTarget; if (targetPIC != currentTarget) { if (currentTarget != null) { // Fire leave event. If we never had a plugin for this event then create a temp one. if (originalRSI == null) { GeneralTransformGroup transformTabletToView = new GeneralTransformGroup(); transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) transformTabletToView.Children.Add(currentTarget.ViewToElement); // Make it relative to the element. transformTabletToView.Freeze(); // Must be frozen for multi-threaded access. originalRSI = new RawStylusInput(rawStylusInputReport, transformTabletToView, currentTarget); } currentTarget.FireEnterLeave(false, originalRSI, true); } if (targetPIC != null) { // Fire Enter event targetPIC.FireEnterLeave(true, rawStylusInputReport.RawStylusInput, true); } // Update the verified target. rawStylusInputReport.StylusDevice.CurrentVerifiedTarget = targetPIC; } // Now fire RawStylusInput if needed to the right plugincollection. if (sendRawStylusInput) { // We are on the pen thread, just call directly. targetPIC.FireRawStylusInput(rawStylusInputReport.RawStylusInput); updateEventPoints = (updateEventPoints || rawStylusInputReport.RawStylusInput.StylusPointsModified); } // Now fire PrePreviewCustomData events. if (targetPIC != null) { // Send custom data pre event foreach (RawStylusInputCustomData customData in rawStylusInputReport.RawStylusInput.CustomDataList) { customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, true); } } // VerifyRawTarget might resend to correct plugins or may have hit the wrong plugincollection. The StylusPackets // may be overriden in those plugins so we need to call UpdateEventStylusPoints to update things. if (updateEventPoints) { rawStylusInputReport.StylusDevice.UpdateEventStylusPoints(rawStylusInputReport, true); } } }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusLeave(RawStylusInput rawStylusInput, bool confirmed) { }
internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport) { // Find PenContexts object for this inputReport. StylusPlugInCollection pic = null; // lock to make sure only one event is processed at a time and no changes to state can // be made until we finish routing this event. lock(__rtiLock) { switch (inputReport.Actions) { case RawStylusActions.Down: case RawStylusActions.Move: case RawStylusActions.Up: // Figure out current target plugincollection. pic = TargetPlugInCollection(inputReport); break; default: return; // Nothing to do unless one of the above events } StylusPlugInCollection currentPic = inputReport.StylusDevice.CurrentNonVerifiedTarget; // Fire Leave event if we need to. if (currentPic != null && currentPic != pic) { // Create new RawStylusInput to send GeneralTransformGroup transformTabletToView = new GeneralTransformGroup(); transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) transformTabletToView.Children.Add(currentPic.ViewToElement); // Make it relative to the element. transformTabletToView.Freeze(); // Must be frozen for multi-threaded access. RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic); currentPic.FireEnterLeave(false, tempRawStylusInput, false); inputReport.StylusDevice.CurrentNonVerifiedTarget = null; } if (pic != null) { // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine) // The transformTabletToView matrix and plugincollection rects though can change based // off of layout events which is why we need to lock this. GeneralTransformGroup transformTabletToView = new GeneralTransformGroup(); transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) transformTabletToView.Children.Add(pic.ViewToElement); // Make it relative to the element. transformTabletToView.Freeze(); // Must be frozen for multi-threaded access. RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic); inputReport.RawStylusInput = rawStylusInput; if (pic != currentPic) { inputReport.StylusDevice.CurrentNonVerifiedTarget = pic; pic.FireEnterLeave(true, rawStylusInput, false); } // We are on the pen thread, just call directly. pic.FireRawStylusInput(rawStylusInput); } } // lock(__rtiLock) }
protected override void OnStylusUp(RawStylusInput rawStylusInput) { }
protected override void OnStylusUp(RawStylusInput rawStylusInput) { base.OnStylusUp(rawStylusInput); HandlePoint(rawStylusInput); }
public void PlayStylusDown(RawStylusInput rawStylusInput) { base.OnStylusDown(rawStylusInput); }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] /// </summary> protected override void OnStylusDown(RawStylusInput rawStylusInput) { // Only allow inking if someone has queried our RootVisual. if (_mainContainerVisual != null) { StrokeInfo si; lock(__siLock) { si = FindStrokeInfo(rawStylusInput.Timestamp); // If we find we are already in the middle of stroke then bail out. // Can only ink with one stylus at a time. if (si != null) { return; } si = new StrokeInfo(DrawingAttributes, rawStylusInput.StylusDeviceId, rawStylusInput.Timestamp, GetCurrentHostVisual()); _strokeInfoList.Add(si); } rawStylusInput.NotifyWhenProcessed(si); RenderPackets(rawStylusInput.GetStylusPoints(), si); } }
private void HandleStylusEnterLeave(RawStylusInput rawStylusInput, bool isEnter, bool isConfirmed) { // See if we need to abort a stroke due to entering or leaving within a stroke. if (isConfirmed) { StrokeInfo si = FindStrokeInfo(rawStylusInput.Timestamp); if (si != null) { if (rawStylusInput.StylusDeviceId == si.StylusId) { if ((isEnter && (rawStylusInput.Timestamp > si.StartTime)) || (!isEnter && !si.SeenUp)) { // abort this stroke. TransitionStrokeVisuals(si, true); } } } } }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - On pen threads or app thread /// </summary> protected override void OnStylusLeave(RawStylusInput rawStylusInput, bool confirmed) { HandleStylusEnterLeave(rawStylusInput, false, confirmed); }
protected override void OnStylusDown(RawStylusInput rawStylusInput) { base.OnStylusDown(rawStylusInput); }
protected virtual new void OnStylusMove(RawStylusInput rawStylusInput) { }
void HandlePoint(RawStylusInput rawStylusInput) { //Console.WriteLine("num points {0}", rawStylusInput.GetStylusPoints().Count()); //foreach (var p in rawStylusInput.GetStylusPoints()) // Console.WriteLine("{0}-{1}", p.X, p.Y); }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] /// </summary> protected override void OnStylusMove(RawStylusInput rawStylusInput) { // Only allow inking if someone has queried our RootVisual. if (_mainContainerVisual != null) { StrokeInfo si = FindStrokeInfo(rawStylusInput.Timestamp); if (si != null && (si.StylusId == rawStylusInput.StylusDeviceId)) { // We only render packets that are in the proper order due to // how our incremental rendering uses the last point to continue // the path geometry from. // NOTE: We also update the LastTime value here too if (si.IsTimestampAfter(rawStylusInput.Timestamp)) { si.LastTime = rawStylusInput.Timestamp; RenderPackets(rawStylusInput.GetStylusPoints(), si); } } } }
protected override void OnStylusLeave(RawStylusInput rawStylusInput, bool confirmed) { }
public void PlayStylusMove(RawStylusInput rawStylusInput) { base.OnStylusMove(rawStylusInput); }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] /// </summary> protected override void OnStylusUp(RawStylusInput rawStylusInput) { // Only allow inking if someone has queried our RootVisual. if (_mainContainerVisual != null) { StrokeInfo si = FindStrokeInfo(rawStylusInput.Timestamp); if (si != null && ((si.StylusId == rawStylusInput.StylusDeviceId) || (rawStylusInput.StylusDeviceId == 0 && (si.IsReset || (si.IsTimestampAfter(rawStylusInput.Timestamp) && IsStylusUp(si.StylusId)))))) { si.SeenUp = true; si.LastTime = rawStylusInput.Timestamp; rawStylusInput.NotifyWhenProcessed(si); } } }
public void PlayStylusUp(RawStylusInput rawStylusInput) { base.OnStylusUp(rawStylusInput); }
internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection) { StylusPlugInCollection newPlugInCollection = null; // lock to make sure only one event is processed at a time and no changes to state can // be made until we finish routing this event. lock(__rtiLock) { //Debug.Assert(inputReport.Actions == RawStylusActions.Down || // inputReport.Actions == RawStylusActions.Up || // inputReport.Actions == RawStylusActions.Move); // Find new target plugin collection if (directlyOver != null) { UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement; if (uiElement != null) { newPlugInCollection = FindPlugInCollection(uiElement); } } // Fire Leave event to old pluginCollection if we need to. if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection) { // NOTE: input report points for mouse are in avalon measured units and not device! RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection); currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true); } if (newPlugInCollection != null) { // NOTE: input report points for mouse are in avalon measured units and not device! RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection); inputReport.RawStylusInput = rawStylusInput; if (newPlugInCollection != currentPlugInCollection) { newPlugInCollection.FireEnterLeave(true, rawStylusInput, true); } // We are on the pen thread, just call directly. newPlugInCollection.FireRawStylusInput(rawStylusInput); // Fire custom data events (always confirmed for mouse) foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList) { customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true); } } } return newPlugInCollection; }
///////////////////////////////////////////////////////////////////// /// <summary> /// [TBS] - on RTI Dispatcher /// </summary> protected virtual void OnStylusEnter(RawStylusInput rawStylusInput, bool confirmed) { }
protected override void OnStylusDown(RawStylusInput rawStylusInput) { currentStroke = new StampedStroke(); currentStroke.DownStylusPointStamp = DateTime.Now; base.OnStylusDown(rawStylusInput); }
protected override void OnStylusMove(RawStylusInput rawStylusInput) { base.OnStylusMove(rawStylusInput); }