コード例 #1
0
        /// <summary>
        /// return a list of rtDrawStroke messages if ink has been cached for this slide, else null.
        /// The expectation is that the toc entry for slideId does exist before this is called.
        /// </summary>
        /// <param name="slideId"></param>
        private List <object> getCachedStrokes(Guid slideId)
        {
            List <object> outputMessages = null;

            TableOfContents.TocEntry tocEntry = toc.LookupBySlideId(slideId);
            if (tocEntry == null)
            {
                Debug.WriteLine("Warning: getCachedStrokes failed to find TOC entry.");
                return(null);
            }

            if (this.pendingInk.ContainsKey(slideId))
            {
                foreach (Ink ink in pendingInk[slideId])
                {
                    if (ink.Strokes.Count <= 0)
                    {
                        continue;
                    }

                    Guid strokeId = Guid.NewGuid();
                    //Pull out the identifier which is used if we need to delete the stroke later:
                    if (ink.Strokes[0].ExtendedProperties.DoesPropertyExist(StrokeIdExtendedProperty))
                    {
                        strokeId = new Guid((string)ink.Strokes[0].ExtendedProperties[StrokeIdExtendedProperty].Data);
                    }
                    else
                    {
                        Debug.WriteLine("Warning: Failed to find stroke Id.");
                    }
                    //WebViewer looks for the CP2 extended property, so add it too.
                    ink.Strokes[0].ExtendedProperties.Add(CP2StrokeIdExtendedProperty, (object)strokeId.ToString());
                    //WebViewer wants ink to be scaled to 500x500
                    ink.Strokes.Scale(500f / getCurrentSlideWidth(), 500f / getCurrentSlideHeight());
                    RTDrawStroke rtds = new RTDrawStroke(ink, strokeId, true, tocEntry.DeckId, tocEntry.SlideIndex);

                    //Add the stroke to our list to optimize deletes
                    if (!strokeCountsBySlideId.ContainsKey(slideId))
                    {
                        strokeCountsBySlideId.Add(slideId, 1);
                    }
                    else
                    {
                        strokeCountsBySlideId[slideId]++;
                    }

                    if (outputMessages == null)
                    {
                        outputMessages = new List <object>();
                    }
                    outputMessages.Add(rtds);
                    Debug.WriteLine("***** getCachedStrokes:Adding Stroke ID=" + strokeId.ToString());
                }

                pendingInk.Remove(slideId);
            }
            return(outputMessages);
        }
コード例 #2
0
        /// <summary>
        /// Translate real-time ink packets to a stroke and return RTStrokeAdded.
        /// </summary>
        /// <param name="rtispm"></param>
        /// <returns></returns>
        internal object AddRealTimeInkSheetPackets(UW.ClassroomPresenter.Network.Messages.Presentation.RealTimeInkSheetPacketsMessage rtispm)
        {
            //Resolve the sheetId to a slideId, and use it to look up a TOC entry.
            if (!sheetToSlideLookup.ContainsKey(rtispm.TargetId))
            {
                if (this.currentSlideId.Equals(Guid.Empty))
                {
                    warning += "Warning: found real-time ink on an unknown sheet.  Ignoring the ink.  ";
                    return(null);
                }
                //Can we assume current slide??  Probably..
                sheetToSlideLookup.Add(rtispm.TargetId, currentSlideId);
            }

            TableOfContents.TocEntry tocEntry = toc.LookupBySlideId((Guid)sheetToSlideLookup[rtispm.TargetId]);
            if (tocEntry == null)
            {
                warning += "Warning: Failed to find a TOC entry for a slide when applying real-time ink.  Ignoring the ink.  ";
                return(null);
            }

            //Tablet Properties should have been received in a StylusDown message.
            if (previousTabletProperties == null)
            {
                warning += "Warning: Received real-time ink without tablet properties.  Ignoring the ink.  ";
                return(null);
            }

            //Debug.WriteLine("***** Realtime Ink packets StrokeID=" + rtispm.StrokeId.ToString() + "; stylusId=" + rtispm.StylusId.ToString());

            // Verify that the stroke we're about to render matches the StrokeId
            // from the most recent StylusDown event.  (If not, then something
            // probably got lost over the network.)
            if (this.previousRealTimeStroke != rtispm.StrokeId)
            {
                previousRealTimeStroke  = rtispm.StrokeId;
                previousRealTimePackets = new int[] { };
            }

            // Get the DrawingAttributes which were in effect on StylusDown.  We should have received this in a
            // RealTimeInkSheetInformationMessage previously.
            if (!this.sheetToDrawingAttributesLookup.ContainsKey(rtispm.TargetId))
            {
                //Note: this seems to happen all the time, but I don't notice any ill effects.  Ignore the ink but leave out the warning.
                //this.warning += "Warning: Real-time ink was found that lacks DrawingAttributes.  The ink will be ignored.  ";
                return(null);
            }
            DrawingAttributes atts = (DrawingAttributes)this.sheetToDrawingAttributesLookup[rtispm.TargetId];

            // Ink packets for this stroke so far.  Initial packets should have been received in the Stylus Down message.
            if (this.previousRealTimePackets == null)
            {
                this.warning += "Warning: Failed to find previous real-time ink packets. The ink will be ignored.  ";
                return(null);
            }

            // Assemble the completed information we'll need to create the mini-stroke.
            int[] combinedPackets = new int[this.previousRealTimePackets.Length + rtispm.Packets.Length];
            this.previousRealTimePackets.CopyTo(combinedPackets, 0);
            rtispm.Packets.CopyTo(combinedPackets, this.previousRealTimePackets.Length);

            // Store the new data.
            this.previousRealTimePackets = combinedPackets;

            // Now that we have the data, we're ready to create the temporary stroke.
            Ink    ink    = new Ink();
            Stroke stroke = ink.CreateStroke(combinedPackets, previousTabletProperties);

            stroke.DrawingAttributes = atts;

            //Look up the data for this stroke, or assign a new Guid if needed.
            RTStrokeData rtsData;

            if (!realTimeStrokesPending.TryGetValue(rtispm.StrokeId, out rtsData))
            {
                rtsData = new RTStrokeData(Guid.NewGuid(), tocEntry.DeckId, tocEntry.SlideIndex);
                realTimeStrokesPending.Add(rtispm.StrokeId, rtsData);
            }
            Guid strokeId = rtsData.StrokeId;

            //WebViewer requires the CP2 extended property to allow deletion of the stroke
            ink.Strokes[0].ExtendedProperties.Add(CP2StrokeIdExtendedProperty, (object)strokeId.ToString());
            //WebViewer wants ink to be scaled to 500x500
            ink.Strokes.Scale(500f / getCurrentSlideWidth(), 500f / getCurrentSlideHeight());


            Debug.WriteLine("***** Adding Real-time Stroke ID=" + strokeId.ToString());
            RTDrawStroke rtds = new RTDrawStroke(ink, strokeId, false, tocEntry.DeckId, tocEntry.SlideIndex);

            return(rtds);
        }
コード例 #3
0
        /// <summary>
        /// This is the message received when there is a completed stroke. Translate to RTDrawStroke.
        /// </summary>
        /// <param name="issam"></param>
        /// <returns></returns>
        internal RTDrawStroke AddInkSheetStrokesAdded(CP3Msgs.InkSheetStrokesAddedMessage issam)
        {
            //Notice that we tend to get a fair number of these messages that have nothing in the SavedInks property.. presenter bug?
            byte[][] saved = issam.SavedInks;
            if (saved.Length == 0)
            {
                return(null);
            }
            if (saved[0].Length == 0)
            {
                return(null);
            }
            if (saved.Length > 1)
            {
                //This does not seem to occur in practice.  If it ever does, we need to generate multiple RTDrawStroke messages:
                warning += "Warning: Valid ink may be ignored because we only support one byte[] per ink message.  ";
            }
            Ink ink = new Ink();

            ink.Load(saved[0]);
            if (ink.Strokes.Count <= 0)
            {
                return(null);
            }

            //This message has a targetID identifying a Sheet which we use to look up a toc entry.
            Debug.WriteLine("***** InkSheetStrokesAdded targetid=" + issam.TargetId.ToString());

            if (!sheetToSlideLookup.ContainsKey(issam.TargetId))
            {
                if (issam.SlideId.Equals(Guid.Empty))
                {
                    //Don't think this should ever happen.
                    warning += "Warning: InkSheetStrokesAdded does not match a known sheet.  Ignoring ink.  ";
                    return(null);
                }
                sheetToSlideLookup.Add(issam.TargetId, issam.SlideId);
            }

            Guid slideId = (Guid)sheetToSlideLookup[issam.TargetId];

            //Get DeckID and Slide index from toc.  Return RTDrawStroke.
            TableOfContents.TocEntry tocEntry = toc.LookupBySlideId(slideId);
            if (tocEntry == null)
            {
                //In some cases ink arrives before the TOC entry.
                //    Save the ink to send later when the TOC entry is available.
                if (!pendingInk.ContainsKey(slideId))
                {
                    pendingInk.Add(slideId, new List <Ink>());
                }
                pendingInk[slideId].Add(ink);
                Debug.WriteLine("InkSheetStrokesAdded does not have a Toc entry.  Caching for later.");
                return(null);
            }

            Guid strokeId = Guid.NewGuid();

            //Pull out the identifier which is used if we need to delete the stroke later:
            if (ink.Strokes[0].ExtendedProperties.DoesPropertyExist(StrokeIdExtendedProperty))
            {
                strokeId = new Guid((string)ink.Strokes[0].ExtendedProperties[StrokeIdExtendedProperty].Data);
            }
            else
            {
                warning += "Warning: Failed to find stroke Id.  ";
            }
            //WebViewer looks for the CP2 extended property, so add it too.
            ink.Strokes[0].ExtendedProperties.Add(CP2StrokeIdExtendedProperty, (object)strokeId.ToString());
            //WebViewer wants ink to be scaled to 500x500
            ink.Strokes.Scale(500f / getCurrentSlideWidth(), 500f / getCurrentSlideHeight());
            //Debug.WriteLine("***** Adding Stroke ID=" + strokeId.ToString());
            RTDrawStroke rtds = new RTDrawStroke(ink, strokeId, true, tocEntry.DeckId, tocEntry.SlideIndex);

            //Add the stroke to our list to optimize deletes
            if (!strokeCountsBySlideId.ContainsKey(slideId))
            {
                strokeCountsBySlideId.Add(slideId, 1);
            }
            else
            {
                strokeCountsBySlideId[slideId]++;
            }

            return(rtds);
        }