/// <summary> /// On stylus-up we send a message to delete real-time ink. Note we wouldn't need to do this if we could map real-time ink /// to completed strokes. /// </summary> /// <param name="rtissu"></param> /// <returns></returns> internal object AddRealTimeInkSheetStylusUp(UW.ClassroomPresenter.Network.Messages.Presentation.RealTimeInkSheetStylusUpMessage rtissu) { //Debug.WriteLine("***** Realtime Ink stylus Up StrokeID=" + rtissu.StrokeId.ToString() + "; stylusId=" + rtissu.StylusId.ToString()); //Resolve sheetId to slideID, then use slideId to get the TOC entry. if (!this.sheetToSlideLookup.ContainsKey(rtissu.TargetId)) { if (currentSlideId.Equals(Guid.Empty)) { warning += "Warning: Failed to find slide for a sheet which was the target of a stylus-up message. May result in stray ink. "; return(null); } //Can we assume current slide?? Probably.. sheetToSlideLookup.Add(rtissu.TargetId, currentSlideId); } Guid slideId = (Guid)this.sheetToSlideLookup[rtissu.TargetId]; TableOfContents.TocEntry tocEntry = toc.LookupBySlideId(slideId); if (tocEntry == null) { warning += "Warning: Failed to find table of contents entry for sheet which was the target of a stylus-up message. May result in stray ink. "; return(null); } RTStrokeData rtsData; if (!this.realTimeStrokesPending.TryGetValue(rtissu.StrokeId, out rtsData)) { //warning += "Warning: Failed to find stroke ID for a real-time ink stylus-up message. May result in stray ink. "; //Note that this seems to happen fairly frequently when using text annotations. I suspect CP3 is sending stylus up //when the annotations are moved, etc. This case has no consequences for stray ink, so we'll just remove the warning for now. Debug.WriteLine("Warning: Failed to find stroke ID for a real-time ink stylus-up message. Could result in stray ink. The warning could be bogus if text annotations were used."); return(null); } Debug.WriteLine("***** Removing Real-time stroke in response to stylus-up. Stroke ID=" + rtsData.StrokeId.ToString()); RTDeleteStroke rtds = rtsData.GetRTDeleteStroke(); this.realTimeStrokesPending.Remove(rtissu.StrokeId); return(rtds); }
/// <summary> /// If strokes with this Guid are found in the queue, remove them, then enqueue the delete. /// </summary> /// <param name="rtds"></param> private void FilterRTDeleteStroke(RTDeleteStroke rtds) { Guid guid = rtds.Guid; lock (subQueue) { //if stroke with this guid is found in low priority queue, remove it. //We assume there will never be more than one due to the way we enqueue strokes. for (int i = 0; i < subQueue.Count; i++) { if ((((WorkItem)subQueue[i]).OpCode == PacketType.Scribble) && (((WorkItem)subQueue[i]).Guid == guid)) { subQueue.RemoveAt(i); break; } } } BufferChunk bc = new BufferChunk(Helpers.ObjectToByteArray(rtds)); enqueueMain(new WorkItem(bc, PacketType.ScribbleDelete, rtds.SlideIndex, rtds.DeckGuid)); }
/// <summary> /// Return one or more RTDeleteStroke messages. /// </summary> /// <param name="issdm"></param> /// <returns></returns> internal List <object> AddInkSheetStrokesDeleting(UW.ClassroomPresenter.Network.Messages.Presentation.InkSheetStrokesDeletingMessage issdm) { //Resolve the SheetId to a slideId if (!sheetToSlideLookup.ContainsKey(issdm.TargetId)) { if (currentSlideId.Equals(Guid.Empty)) { warning += "Warning: Failed to lookup slide from sheet during ink erase operation."; return(null); } //Can we assume current slide?? Probably.. sheetToSlideLookup.Add(issdm.TargetId, currentSlideId); } //Use the slideId to get DeckID and Slide index from toc. Guid slideId = (Guid)sheetToSlideLookup[issdm.TargetId]; TableOfContents.TocEntry tocEntry = toc.LookupBySlideId(slideId); if (tocEntry == null) { warning += "Warning: InkSheetStrokesDeleted does not have a Toc entry. Ignoring erase. "; return(null); } if (issdm.StrokeIds.Length == 0) { return(null); } List <object> outputMessages = new List <object>(); //If more than one stroke, and count matches the total we have recorded for this slide, send one // message to erase all strokes. if (issdm.StrokeIds.Length > 1) { if (strokeCountsBySlideId.ContainsKey(slideId)) { if (strokeCountsBySlideId[slideId] == issdm.StrokeIds.Length) { strokeCountsBySlideId[slideId] = 0; RTEraseLayer rtel = new RTEraseLayer(tocEntry.DeckId, tocEntry.SlideIndex); Trace.WriteLine("*****Returning RTEraseLayer deck=" + tocEntry.DeckId.ToString() + ";slide=" + tocEntry.SlideIndex.ToString()); outputMessages.Add(rtel); //note: this message also takes care of any stray RT strokes, so clear this list: this.realTimeStrokesPending.Clear(); return(outputMessages); } } } //If there are any stray real-time strokes, delete them here. foreach (RTStrokeData rtsd in this.realTimeStrokesPending.Values) { outputMessages.Add(rtsd.GetRTDeleteStroke()); Debug.WriteLine("***** Deleting stray real-time stroke id=" + rtsd.StrokeId.ToString()); } this.realTimeStrokesPending.Clear(); //Delete individual strokes as indicated foreach (string s in issdm.StrokeIds) { Guid g = new Guid(s); RTDeleteStroke rtds = new RTDeleteStroke(g, tocEntry.DeckId, tocEntry.SlideIndex); outputMessages.Add(rtds); int strokesRemaining = -1; if ((strokeCountsBySlideId.ContainsKey(slideId)) && (strokeCountsBySlideId[slideId] > 0)) { strokeCountsBySlideId[slideId]--; strokesRemaining = strokeCountsBySlideId[slideId]; } Debug.WriteLine("***** Deleting static stroke id=" + g.ToString() + ";strokes remaining=" + strokesRemaining.ToString()); } return(outputMessages); }