/// <summary> /// Clone this model. /// </summary> /// <returns>The cloned model.</returns> public object Clone() { SimpleWebInk ink = new SimpleWebInk(); if (this.Pts != null) { ink.Pts = (System.Drawing.Point[])this.Pts.Clone(); } ink.R = this.R; ink.G = this.G; ink.B = this.B; ink.Opacity = this.Opacity; ink.Width = this.Width; return ink; }
/// <summary> /// Clone this model. /// </summary> /// <returns>The cloned model.</returns> public object Clone() { SimpleWebInk ink = new SimpleWebInk(); if (this.Pts != null) { ink.Pts = (System.Drawing.Point[]) this.Pts.Clone(); } ink.R = this.R; ink.G = this.G; ink.B = this.B; ink.Opacity = this.Opacity; ink.Width = this.Width; return(ink); }
/// <summary> /// Build the values for a single slide stroke. /// </summary> /// <param name="first">The first ink.</param> /// <param name="second">The second ink.</param> /// <returns>The data structure for the stroke difference.</returns> protected List <KeyValuePair <string, object> > BuildStrokeData(SimpleWebInk first, SimpleWebInk second) { List <KeyValuePair <string, object> > stroke = new List <KeyValuePair <string, object> >(); // Optionally, add the opacity. if (first == null || first.Opacity != second.Opacity) { stroke.Add(new KeyValuePair <string, object>(StrokeOpacity, second.Opacity)); } // Optionally, add the width. if (first == null || first.Width != second.Width) { stroke.Add(new KeyValuePair <string, object>(StrokeWidth, second.Width)); } // Optionally, add the color. if (first == null || first.R != second.R || first.G != second.G || first.B != second.B) { List <KeyValuePair <string, object> > colorData = new List <KeyValuePair <string, object> >(); colorData.Add(new KeyValuePair <string, object>(ColorR, second.R)); colorData.Add(new KeyValuePair <string, object>(ColorG, second.G)); colorData.Add(new KeyValuePair <string, object>(ColorB, second.B)); stroke.Add(new KeyValuePair <string, object>(StrokeColor, colorData)); } // Optionally, add the stroke points. List <System.Drawing.Point> pts = BuildInkData((first != null) ? first.Pts : null, second.Pts); if (pts != null) { stroke.Add(new KeyValuePair <string, object>(StrokePts, pts)); } // Return the result only if we added/updated data. if (stroke.Count > 0) { return(stroke); } else { return(null); } }
/// <summary> /// Build the values for the slide strokes. /// </summary> /// <param name="first">The first slide.</param> /// <param name="second">The second slide.</param> /// <returns>The data structure for the strokes array.</returns> protected List <object> BuildStrokesData(SimpleWebSlide first, SimpleWebSlide second) { bool nonNull = false; List <object> strokes = new List <object>(); // We need an entry for every stroke in the second model. for (int i = 0; i < second.Inks.Count; i++) { // Optionally, get the first stroke if this stroke existed in the first model. SimpleWebInk firstInk = null; if (first != null && i < first.Inks.Count) { firstInk = (SimpleWebInk)first.Inks[i]; } // Get the difference between the two strokes, if the strokes are the same add null. List <KeyValuePair <string, object> > strokeData = BuildStrokeData(firstInk, (SimpleWebInk)second.Inks[i]); if (strokeData != null) { strokes.Add(strokeData); nonNull = true; } else { strokes.Add(null); } } // Return the result only if some stroke was updated. if (nonNull == true && strokes.Count > 0) { return(strokes); } else { return(null); } }
/// <summary> /// Handle data posted to up by th web client. /// </summary> /// <param name="parameters">The query string parameters.</param> /// <param name="postData">The post data string.</param> /// <returns>The response text.</returns> private string PostHandler(NameValueCollection parameters, string postData) { // Get the parts of the post data. string[] items = postData.Split(new char[] { '|' }); if (items[0] == STUDENT_SUBMISSION_REQUEST) { // Handle student submission. // Deserialize the Array of SimpleStrokeModel from the post data. int clientId = Convert.ToInt32(items[1]); int deck = Convert.ToInt32(items[2]); int slide = Convert.ToInt32(items[3]); object strokes = JSON.Decode(items[4]); if (strokes is List<object>) { ArrayList deserializedStrokes = new ArrayList(); List<object> strokesArray = (List<object>)strokes; foreach (object stroke in strokesArray) { if (stroke is List<KeyValuePair<string, object>>) { SimpleWebInk deserializedStroke = new SimpleWebInk(); List<KeyValuePair<string, object>> strokeObject = (List<KeyValuePair<string, object>>)stroke; foreach (KeyValuePair<string, object> field in strokeObject) { switch (field.Key) { case "c": // Color if (field.Value is List<KeyValuePair<string, object>>) { List<KeyValuePair<string, object>> color = (List<KeyValuePair<string, object>>)field.Value; foreach (KeyValuePair<string, object> channel in color) { if (channel.Key == "r") { deserializedStroke.R = (byte)Math.Round((double)channel.Value); } else if (channel.Key == "g") { deserializedStroke.G = (byte)Math.Round((double)channel.Value); } else if (channel.Key == "b") { deserializedStroke.B = (byte)Math.Round((double)channel.Value); } } } break; case "w": // Width if (field.Value is double) { deserializedStroke.Width = (float)((double)field.Value); } break; case "o": // Opacity if (field.Value is double) { deserializedStroke.Opacity = (byte)Math.Round((double)field.Value); } break; case "k": // Points if (field.Value is List<object>) { List<object> points = (List<object>)field.Value; int numPoints = points.Count / 2; System.Drawing.Point[] pts = new System.Drawing.Point[numPoints]; for (int i = 0; i < numPoints; i++) { pts[i].X = (int)((double)points[(i*2)] * 26.37f); pts[i].Y = (int)((double)points[(i*2)+1] * 26.37f); } deserializedStroke.Pts = pts; } break; } } deserializedStrokes.Add(deserializedStroke); } } // Notify listeners that a student submission was received. WebService.Instance.SubmissionReceived(WebServer.Instance, deck, slide, deserializedStrokes); } // Log that we responded to a pong. this.LogSubmissionReceived(clientId, deck, slide); } else if (items[0] == QUICK_POLL_REQUEST) { // Handle quick poll. // Notify listeners that a quick poll update was received. WebService.Instance.QuickPollReceived(WebServer.Instance, new Guid(items[1]), items[2]); } else if (items[0] == PING_REQUEST) { // Handle ping request. String clientId = items[1]; String clientTimestamp = items[2]; String serverTimestamp = WebService.ToUnixTime(System.DateTime.Now).ToString(); // We should respond with the current timestamp. String pong = "{\"u\":" + clientId + ",\"c\":" + clientTimestamp + ",\"s\":" + serverTimestamp + "}"; // Log that we responded to a pong. this.LogPong(Convert.ToInt32(clientId), pong); return pong; } else if (items[0] == LOG_DUMP_REQUEST) { // Handle a client log dump. String clientId = items[1]; String logDump = items[2]; // Print the dumped log to a file. StreamWriter logFile = new StreamWriter( System.IO.Path.Combine(System.IO.Path.GetTempPath(), "CP_ClientPerformanceLog_" + clientId.ToString() + ".txt")); logFile.Write(logDump); logFile.Close(); } // By default, return an empty json object. return "{}"; }
/// <summary> /// Helper class that is run on a different thread that converts the ink coordinates into pixel coordinates /// </summary> /// <param name="extracted">The strokes to convert and add to the model</param> private void HandleInkAddedHelper(Ink extracted) { // Adjust for differences in DPI if (ViewerStateModel.NonStandardDpi) { extracted.Strokes.Transform(ViewerStateModel.DpiNormalizationSendMatrix, true); } // Get the model object to add it to lock (WebService.Instance.GlobalModel) { SimpleWebDeck deck = (SimpleWebDeck)WebService.Instance.GlobalModel.Decks[WebService.Instance.GlobalModel.CurrentDeck]; SimpleWebSlide slide = (SimpleWebSlide)deck.Slides[WebService.Instance.GlobalModel.CurrentSlide - 1]; slide.Inks = new ArrayList(); // Extract each stroke foreach (Stroke s in extracted.Strokes) { // Get the points System.Drawing.Point[] pts = s.GetPoints(); // Convert and remove duplicates bool bFirst = true; ArrayList pts_new = new ArrayList(); System.Drawing.Point last = System.Drawing.Point.Empty; foreach (System.Drawing.Point p in pts) { System.Drawing.Point pNew = new System.Drawing.Point((int)Math.Round(p.X / 26.37f), (int)Math.Round(p.Y / 26.37f)); if (!bFirst && last == pNew) continue; bFirst = false; last = pNew; pts_new.Add(pNew); } // Add the points to the model SimpleWebInk stroke = new SimpleWebInk(); stroke.Pts = (System.Drawing.Point[])pts_new.ToArray(typeof(System.Drawing.Point)); stroke.R = s.DrawingAttributes.Color.R; stroke.G = s.DrawingAttributes.Color.G; stroke.B = s.DrawingAttributes.Color.B; stroke.Opacity = (s.DrawingAttributes.RasterOperation == RasterOperation.MaskPen) ? (byte)127 : (byte)255; stroke.Width = s.DrawingAttributes.Width / 26.37f; slide.Inks.Add(stroke); } } WebService.Instance.UpdateModel(); }
/// <summary> /// Build the values for a single slide stroke. /// </summary> /// <param name="first">The first ink.</param> /// <param name="second">The second ink.</param> /// <returns>The data structure for the stroke difference.</returns> protected List<KeyValuePair<string, object>> BuildStrokeData(SimpleWebInk first, SimpleWebInk second) { List<KeyValuePair<string, object>> stroke = new List<KeyValuePair<string, object>>(); // Optionally, add the opacity. if (first == null || first.Opacity != second.Opacity) { stroke.Add(new KeyValuePair<string, object>(StrokeOpacity, second.Opacity)); } // Optionally, add the width. if (first == null || first.Width != second.Width) { stroke.Add(new KeyValuePair<string, object>(StrokeWidth, second.Width)); } // Optionally, add the color. if (first == null || first.R != second.R || first.G != second.G || first.B != second.B) { List<KeyValuePair<string, object>> colorData = new List<KeyValuePair<string, object>>(); colorData.Add(new KeyValuePair<string, object>(ColorR, second.R)); colorData.Add(new KeyValuePair<string, object>(ColorG, second.G)); colorData.Add(new KeyValuePair<string, object>(ColorB, second.B)); stroke.Add(new KeyValuePair<string, object>(StrokeColor, colorData)); } // Optionally, add the stroke points. List<System.Drawing.Point> pts = BuildInkData((first != null) ? first.Pts : null, second.Pts); if (pts != null) { stroke.Add(new KeyValuePair<string, object>(StrokePts, pts)); } // Return the result only if we added/updated data. if (stroke.Count > 0) return stroke; else return null; }