/// <summary> /// Initializes a new instance of the VGEllipse class. /// Clone Constructor. Creates new ellipse element that is /// identical to the given VGEllipse. /// </summary> /// <param name="ellipse"><see cref="VGEllipse"/> to clone</param> private VGEllipse(VGEllipse ellipse) : base( ellipse.ShapeDrawAction, ellipse.Pen, ellipse.Brush, ellipse.Font, ellipse.FontColor, ellipse.Bounds, ellipse.StyleGroup, ellipse.Name, ellipse.ElementGroup, ellipse.Sound) { this.inverted = ellipse.Inverted; }
/// <summary> /// Loads the shapes that are listed in the given database table /// and creates corresponding graphic elements. /// </summary> /// <param name="areaOfInterestTableRows"> /// Areas of interest table as /// a <see cref="DataGridViewRowCollection"/> /// </param> public void LoadShapesFromDataGridView(DataGridViewRowCollection areaOfInterestTableRows) { try { // Create aoi elements from data view this.AoiCollection = new VGElementCollection(); foreach (DataGridViewRow row in areaOfInterestTableRows) { if (!row.IsNewRow) { // retrieve shape parameters from cell values. var shapeName = row.Cells["colShapeName"].Value.ToString(); var strPtList = row.Cells["colShapePts"].Value.ToString(); Pen usedPen; Font usedFont; Color usedFontColor; VGAlignment usedAlignment; VGStyleGroup usedStyleGroup; var pointList = ObjectStringConverter.StringToPointFList(strPtList); var usedElementGroup = row.Cells["colShapeGroup"].Value.ToString(); switch (usedElementGroup) { case "Target": usedPen = this.TargetPen; usedFont = this.TargetFont; usedFontColor = this.TargetFontColor; usedStyleGroup = VGStyleGroup.AOI_TARGET; usedAlignment = this.TargetTextAlignment; break; case "SearchRect": usedPen = this.SearchRectPen; usedFont = this.SearchRectFont; usedFontColor = this.SearchRectFontColor; usedStyleGroup = VGStyleGroup.AOI_SEARCHRECT; usedAlignment = this.SearchRectTextAlignment; break; default: usedPen = this.DefaultPen; usedFont = this.DefaultFonts; usedFontColor = this.DefaultFontColor; usedStyleGroup = VGStyleGroup.AOI_NORMAL; usedAlignment = this.DefaultTextAlignment; break; } // Create the shape depending on ShapeType var boundingRect = new RectangleF(); switch (row.Cells["colShapeType"].Value.ToString()) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke var newRect = new VGRectangle( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); newRect.TextAlignment = usedAlignment; this.AoiCollection.Add(newRect); break; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke var newEllipse = new VGEllipse( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); newEllipse.TextAlignment = usedAlignment; this.AoiCollection.Add(newEllipse); break; case "Polyline": // Create Polyline with defined stroke var newPolyline = new VGPolyline( this.hideAOIDescription ? ShapeDrawAction.Edge : ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, usedStyleGroup, shapeName, usedElementGroup); newPolyline.TextAlignment = usedAlignment; foreach (var point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); this.AoiCollection.Add(newPolyline); break; } } } // Reset Elements (deselect and clear all) this.ResetPicture(); this.Elements.AddRange(this.AoiCollection); // If there were a selected element before updating, try // to select it again. if (this.SelectedElement != null) { foreach (VGElement element in this.Elements) { if (VGPolyline.Distance(element.Location, this.SelectedElement.Location) < 1) { this.SelectedElement = element; element.IsInEditMode = true; } } } this.DrawForeground(true); } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }
/// <summary> /// This method draws the statistic bubbles and transisiton arrows /// of given <see cref="SampleType"/> in given <see cref="VisualizationModes"/>. /// </summary> /// <param name="mode"> /// The <see cref="VisualizationModes"/> to be used. /// </param> /// <param name="sampleType"> /// The <see cref="SampleType"/> of the data. /// </param> public void DrawAOIStatistics(VisualizationModes mode, SampleType sampleType) { // Skip if no data available if (this.aoiStatistics == null) { return; } // Get all statistical elements var statisticalElements = this.Elements.FindAllGroupMembers(VGStyleGroup.AOI_STATISTICS_ARROW); statisticalElements.AddRange(this.Elements.FindAllGroupMembers(VGStyleGroup.AOI_STATISTICS_BUBBLE)); this.Elements.RemoveAll(statisticalElements); var distances = new List<int>(); var aoisWithoutSearchRects = new VGElementCollection(); foreach (VGElement aoi in this.AoiCollection) { if (aoi.StyleGroup != VGStyleGroup.AOI_SEARCHRECT) { aoisWithoutSearchRects.Add(aoi); } } foreach (VGElement aoi in aoisWithoutSearchRects) { if (!this.aoiStatistics.ContainsKey(aoi.Name)) { continue; } var aoiStatistic = this.aoiStatistics[aoi.Name]; if ((mode & VisualizationModes.FixationTime) == VisualizationModes.FixationTime) { if (aoiStatistic.SumOfTimeOfAllFixations > 0) { var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.SumOfTimeOfAllFixations, mode); var ellipse = new VGEllipse( this.BubbleDrawAction, this.BubblePen, this.BubbleBrush, this.BubbleFont, this.BubbleFontColor, bounds, VGStyleGroup.AOI_STATISTICS_BUBBLE, aoiStatistic.SumOfTimeOfAllFixations + " ms", string.Empty); ellipse.TextAlignment = this.BubbleTextAlignment; distances.Add((int)(bounds.Width / 2)); this.Elements.Add(ellipse); } } if ((mode & VisualizationModes.NumberOfFixations) == VisualizationModes.NumberOfFixations) { if (aoiStatistic.FixationCount > 0) { var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.FixationCount, mode); var ellipse = new VGEllipse( this.BubbleDrawAction, this.BubblePen, this.BubbleBrush, this.BubbleFont, this.BubbleFontColor, bounds, VGStyleGroup.AOI_STATISTICS_BUBBLE, aoiStatistic.FixationCount.ToString(CultureInfo.InvariantCulture), string.Empty); ellipse.TextAlignment = this.BubbleTextAlignment; distances.Add((int)(bounds.Width / 2)); this.Elements.Add(ellipse); } } if ((mode & VisualizationModes.AverageFixationDuration) == VisualizationModes.AverageFixationDuration) { if (aoiStatistic.FixationDurationMean > 0) { var bounds = this.GetCircleBounds(aoi.Center, aoiStatistic.FixationDurationMean, mode); var ellipse = new VGEllipse( this.BubbleDrawAction, this.BubblePen, this.BubbleBrush, this.BubbleFont, this.BubbleFontColor, bounds, VGStyleGroup.AOI_STATISTICS_BUBBLE, aoiStatistic.FixationDurationMean.ToString("N0") + " ms", string.Empty); ellipse.TextAlignment = this.BubbleTextAlignment; distances.Add((int)(bounds.Width / 2)); this.Elements.Add(ellipse); } } } // Check for absolute or relative transition values var absolute = (mode & VisualizationModes.AbsoluteTransitions) == VisualizationModes.AbsoluteTransitions; if ((mode & VisualizationModes.RelativeTransitions) == VisualizationModes.RelativeTransitions || (mode & VisualizationModes.AbsoluteTransitions) == VisualizationModes.AbsoluteTransitions) { DataView trialsFixations = null; // Get filtered fixations data view switch (sampleType) { case SampleType.Gaze: trialsFixations = this.GazeFixationsView; break; case SampleType.Mouse: trialsFixations = this.MouseFixationsView; break; } var transitions = Statistics.Statistic.CreateTransitionMatrixForSingleAOIs( trialsFixations, aoisWithoutSearchRects); float transitionSum = 0; // Calculate transition total sum only if relative values are requested. if (!absolute) { for (var i = 0; i <= transitions.GetUpperBound(0); i++) { // Skip nowhere transitions if (i == 0) { continue; } for (var j = 0; j <= transitions.GetUpperBound(1); j++) { // Only take values outside the diagonal if (i == j || j == 0) { continue; } transitionSum += (int)transitions.GetValue(i, j); } } } // Write transitionMatrix to dgv for (var i = transitions.GetLowerBound(0); i <= transitions.GetUpperBound(0); i++) { // Skip nowhere transitions if (i == 0) { continue; } for (var j = transitions.GetLowerBound(1); j <= transitions.GetUpperBound(1); j++) { // Only take values above the diagonal if (i >= j) { continue; } float transAtoB; float transBtoA; if (absolute) { transAtoB = (int)transitions.GetValue(i, j); transBtoA = (int)transitions.GetValue(j, i); } else { transAtoB = (float)Math.Round((int)transitions.GetValue(i, j) / transitionSum * 100, 1); transBtoA = (float)Math.Round((int)transitions.GetValue(j, i) / transitionSum * 100, 1); } if (transAtoB > 0 || transBtoA > 0) { var showNumbers = false; if ((this.ArrowDrawAction & ShapeDrawAction.Name) == ShapeDrawAction.Name) { this.ArrowDrawAction |= ~ShapeDrawAction.Name; showNumbers = true; } var arrow = new VGArrow(this.ArrowDrawAction, this.ArrowPen); arrow.Brush = this.ArrowBrush; if (!showNumbers) { arrow.HideWeights = true; } var location1 = aoisWithoutSearchRects[i - 1].Center; var location2 = aoisWithoutSearchRects[j - 1].Center; var distanceFirst = distances.Count >= i ? distances[i - 1] : 15; var distanceSecond = distances.Count >= j ? distances[j - 1] : 15; if (location1.X <= location2.X) { arrow.FirstPoint = location1; arrow.SecondPoint = location2; arrow.FirstPointDistance = distanceFirst; arrow.SecondPointDistance = distanceSecond; arrow.FirstPointWeight = transBtoA; arrow.SecondPointWeight = transAtoB; } else { arrow.FirstPoint = location2; arrow.SecondPoint = location1; arrow.FirstPointDistance = distanceSecond; arrow.SecondPointDistance = distanceFirst; arrow.FirstPointWeight = transAtoB; arrow.SecondPointWeight = transBtoA; } arrow.FormatString = "N0"; if (!absolute) { if (arrow.FirstPointWeight < 1 && arrow.SecondPointWeight < 1) { arrow.FormatString = "N1"; } arrow.AddOnString = "%"; } arrow.WeightFont = this.ArrowFont; arrow.WeightFontColor = this.ArrowFontColor; arrow.ScaleFactor = this.ArrowFactor; arrow.StyleGroup = VGStyleGroup.AOI_STATISTICS_ARROW; arrow.TextAlignment = this.ArrowTextAlignment; this.Elements.Add(arrow); } } } } this.DrawForeground(true); }
/// <summary> /// Draws fixations and fixation connections. /// Updates fixation objects and calculates fixation parameters. /// </summary> /// <param name="pointTime"> /// The time estimation of the new point. /// </param> /// <param name="newPt"> /// A <see cref="PointF"/> with the new sampling data. /// </param> /// <param name="toDraw"> /// The <see cref="SampleType"/> to draw. /// </param> /// <param name="lastPointInSampleRange"> /// A <see cref="Boolean"/> /// indicating whether this sample is the last one in the range of /// the current update, so this is to update the current fixations diameter. /// </param> private void DrawFixations( long pointTime, PointF newPt, SampleType toDraw, bool lastPointInSampleRange) { bool point_found_delayed; float x_delayed; float y_delayed; float deviation_delayed; float x_fix_delayed; float y_fix_delayed; int saccade_duration_delayed; long fix_start_time; int fix_duration_delayed_samples; long fix_duration_delayed_milliseconds; VGPolyline usedPolyline; VGLine usedLine; VGEllipse usedEllipse; Pen usedFixationPen; PointF usedFixCenterPt; var usedBoundingRect = new RectangleF(); VGStyleGroup usedGroup; EyeMotionState currentState; float divisor; switch (toDraw) { case SampleType.Gaze: default: currentState = this.objFixGazeDetection.DetectFixation( newPt.IsEmpty ? false : true, pointTime, newPt.X, newPt.Y, this.gazeMaxDistance, this.gazeMinSamples, out point_found_delayed, out x_delayed, out y_delayed, out deviation_delayed, out x_fix_delayed, out y_fix_delayed, out saccade_duration_delayed, out fix_start_time, out fix_duration_delayed_milliseconds, out fix_duration_delayed_samples); usedPolyline = this.gazeFixConPolyline; usedLine = this.gazeFixConLine; usedEllipse = this.gazeFixEllipse; usedFixationPen = this.penGazeFixation; usedFixCenterPt = this.currentLoopState.GazeLastFixCenter; usedGroup = VGStyleGroup.RPL_PEN_GAZE_FIX; divisor = this.gazeFixDiameterDiv; break; case SampleType.Mouse: currentState = this.objFixMouseDetection.DetectFixation( newPt.IsEmpty ? false : true, pointTime, newPt.X, newPt.Y, this.mouseMaxDistance, this.mouseMinSamples, out point_found_delayed, out x_delayed, out y_delayed, out deviation_delayed, out x_fix_delayed, out y_fix_delayed, out saccade_duration_delayed, out fix_start_time, out fix_duration_delayed_milliseconds, out fix_duration_delayed_samples); usedPolyline = this.mouseFixConPolyline; usedLine = this.mouseFixConLine; usedEllipse = this.mouseFixEllipse; usedFixationPen = this.penMouseFixation; usedFixCenterPt = this.currentLoopState.MouseLastFixCenter; usedGroup = VGStyleGroup.RPL_PEN_MOUSE_FIX; divisor = this.mouseFixDiameterDiv; break; } // Calculate Bounding Rectangle var fixationDiameter = Convert.ToSingle(fix_duration_delayed_samples) / divisor; usedBoundingRect.X = x_fix_delayed - fixationDiameter; usedBoundingRect.Y = y_fix_delayed - fixationDiameter; usedBoundingRect.Width = fixationDiameter * 2; usedBoundingRect.Height = fixationDiameter * 2; var fixationCenter = new PointF(x_fix_delayed, y_fix_delayed); switch (currentState) { case EyeMotionState.MOVING: if (!Queries.OutOfScreen(newPt, this.StimulusSize)) { if (lastPointInSampleRange) { this.UpdateLastPtInLine(usedLine, newPt, pointTime); } } else { this.currentLoopState.IsOutOfMonitor = true; } this.onsetTime = pointTime; break; case EyeMotionState.FIXATING: if (lastPointInSampleRange) { usedEllipse.Bounds = usedBoundingRect; this.UpdateLastPtInLine(usedLine, fixationCenter, pointTime); } break; case EyeMotionState.FIXATION_COMPLETED: if (!Queries.OutOfScreen(fixationCenter, this.StimulusSize)) { if (this.currentLoopState.IsOutOfMonitor) { this.currentLoopState.IsOutOfMonitor = false; var dottedLine = new VGLine(ShapeDrawAction.Edge, this.penGazeNoData, VGStyleGroup.RPL_PEN_GAZE_NODATA, string.Empty, string.Empty); dottedLine.FirstPoint = usedFixCenterPt; dottedLine.SecondPoint = fixationCenter; dottedLine.OnsetTime = pointTime; dottedLine.EndTime = pointTime; switch (toDraw) { case SampleType.Gaze: if (((this.gazeDrawingMode & ReplayDrawingModes.FixationConnections) == ReplayDrawingModes.FixationConnections) && (!this.isGazeDiscreteLength)) { this.Elements.Add(dottedLine); } break; case SampleType.Mouse: if (((this.mouseDrawingMode & ReplayDrawingModes.FixationConnections) == ReplayDrawingModes.FixationConnections) && (!this.isMouseDiscreteLength)) { this.Elements.Add(dottedLine); } break; } } var ellipse2 = new VGEllipse( ShapeDrawAction.Edge, usedFixationPen, usedBoundingRect, usedGroup, string.Empty, string.Empty); ellipse2.OnsetTime = this.onsetTime; ellipse2.EndTime = pointTime; switch (toDraw) { default: case SampleType.Gaze: this.UpdateFirstPtInLine(usedLine, fixationCenter, pointTime); this.AddPtToPolyline(usedPolyline, fixationCenter, this.isGazeDiscreteLength, pointTime); this.currentLoopState.GazeLastFixCenter = fixationCenter; this.gazeFixations.Add(ellipse2); // Switch to fixed length if choosen if (this.isGazeDiscreteLength && (this.gazeFixations.Count >= this.numFixToShow)) { this.Elements.Remove(this.gazeFixations[0]); this.gazeFixations.RemoveAt(0); while (usedPolyline.GetPointCount() >= this.numFixToShow) { usedPolyline.RemoveFirstPt(); } } if ((this.gazeDrawingMode & ReplayDrawingModes.Fixations) == ReplayDrawingModes.Fixations) { Elements.Add(ellipse2); } break; case SampleType.Mouse: this.UpdateFirstPtInLine(usedLine, fixationCenter, pointTime); this.AddPtToPolyline(usedPolyline, fixationCenter, this.isMouseDiscreteLength, pointTime); this.currentLoopState.MouseLastFixCenter = fixationCenter; this.mouseFixations.Add(ellipse2); // Switch to fixed length if choosen if (this.isMouseDiscreteLength && (this.mouseFixations.Count >= this.numFixToShow)) { this.Elements.Remove(this.mouseFixations[0]); this.mouseFixations.RemoveAt(0); while (usedPolyline.GetPointCount() >= this.numFixToShow) { usedPolyline.RemoveFirstPt(); } } if ((this.mouseDrawingMode & ReplayDrawingModes.Fixations) == ReplayDrawingModes.Fixations) { this.Elements.Add(ellipse2); } break; } } else { this.currentLoopState.IsOutOfMonitor = true; } break; case EyeMotionState.ERROR: break; default: break; } }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// This method creates the shape that is defined in this dialog to be added to a slide. /// </summary> /// <returns>The ready to use <see cref="VGElement"/>.</returns> private VGElement GenerateNewShape() { VGElement element = null; if (this.rdbRectangle.Checked) { element = new VGRectangle( this.pbcStyle.DrawAction, this.pbcStyle.NewPen, this.pbcStyle.NewBrush, this.pbcStyle.NewFont, this.pbcStyle.NewFontColor, new RectangleF(0, 0, 100, 100), VGStyleGroup.None, this.pbcStyle.NewName, string.Empty); } else if (this.rdbEllipse.Checked) { element = new VGEllipse( this.pbcStyle.DrawAction, this.pbcStyle.NewPen, this.pbcStyle.NewBrush, this.pbcStyle.NewFont, this.pbcStyle.NewFontColor, new RectangleF(0, 0, 100, 100), VGStyleGroup.None, this.pbcStyle.NewName, string.Empty); } else if (this.rdbPolyline.Checked) { element = new VGPolyline( this.pbcStyle.DrawAction, this.pbcStyle.NewPen, this.pbcStyle.NewBrush, this.pbcStyle.NewFont, this.pbcStyle.NewFontColor, VGStyleGroup.None, this.pbcStyle.NewName, string.Empty); } else if (this.rdbSharp.Checked) { element = new VGSharp( this.pbcStyle.DrawAction, this.pbcStyle.NewPen, this.pbcStyle.NewFont, this.pbcStyle.NewFontColor, new RectangleF(0, 0, 100, 100), VGStyleGroup.None, this.pbcStyle.NewName, string.Empty); } else if (this.rdbLine.Checked) { element = new VGLine( this.pbcStyle.DrawAction, this.pbcStyle.NewPen, this.pbcStyle.NewFont, this.pbcStyle.NewFontColor, VGStyleGroup.None, this.pbcStyle.NewName, string.Empty); } element.Sound = this.audioControl.Sound; return element; }
/// <summary> /// Initializes standard values of drawing elements /// </summary> private void InitializeElements() { try { this.penGazeCursor = new Pen(Properties.Settings.Default.GazeCursorColor, Properties.Settings.Default.GazeCursorWidth); this.penGazeCursor.DashStyle = Properties.Settings.Default.GazeCursorStyle; this.penGazePath = new Pen(Properties.Settings.Default.GazePathColor, Properties.Settings.Default.GazePathWidth); this.penGazePath.DashStyle = Properties.Settings.Default.GazePathStyle; this.penGazePath.LineJoin = LineJoin.Round; this.penGazeFixation = new Pen(Properties.Settings.Default.GazeFixationsPenColor, Properties.Settings.Default.GazeFixationsPenWidth); this.penGazeFixation.DashStyle = Properties.Settings.Default.GazeFixationsPenStyle; this.penGazeFixationConnection = new Pen(Properties.Settings.Default.GazeFixationConnectionsPenColor, Properties.Settings.Default.GazeFixationConnectionsPenWidth); this.penGazeFixation.DashStyle = Properties.Settings.Default.GazeFixationConnectionsPenStyle; this.penGazeNoData = new Pen(Properties.Settings.Default.GazeNoDataColor, Properties.Settings.Default.GazeNoDataWidth); this.penGazeNoData.DashStyle = Properties.Settings.Default.GazeNoDataStyle; this.penMouseCursor = new Pen(Properties.Settings.Default.MouseCursorColor, Properties.Settings.Default.MouseCursorWidth); this.penMouseCursor.DashStyle = Properties.Settings.Default.MouseCursorStyle; this.penMousePath = new Pen(Properties.Settings.Default.MousePathColor, Properties.Settings.Default.MousePathWidth); this.penMousePath.DashStyle = Properties.Settings.Default.MousePathStyle; this.penMousePath.LineJoin = LineJoin.Round; this.penMouseFixation = new Pen(Properties.Settings.Default.MouseFixationsPenColor, Properties.Settings.Default.MouseFixationsPenWidth); this.penMouseFixation.DashStyle = Properties.Settings.Default.MouseFixationsPenStyle; this.penMouseFixationConnection = new Pen(Properties.Settings.Default.MouseFixationConnectionsPenColor, Properties.Settings.Default.MouseFixationConnectionsPenWidth); this.penMouseFixationConnection.DashStyle = Properties.Settings.Default.MouseFixationConnectionsPenStyle; this.gazePicEllipse = new VGEllipse(ShapeDrawAction.Fill, this.GrayBrush); this.gazePicEllipse.Inverted = true; this.gazePicEllipse.ElementGroup = "Default"; this.mousePicEllipse = new VGEllipse(ShapeDrawAction.Fill, this.GrayBrush); this.mousePicEllipse.Inverted = true; this.mousePicEllipse.ElementGroup = "Default"; this.gazeRawPolyline = new VGPolyline(ShapeDrawAction.Edge, this.penGazePath, VGStyleGroup.RPL_PEN_GAZE_PATH, string.Empty, string.Empty); this.gazeRawPolyline.ElementGroup = "Default"; this.mouseRawPolyline = new VGPolyline(ShapeDrawAction.Edge, this.penMousePath, VGStyleGroup.RPL_PEN_MOUSE_PATH, string.Empty, string.Empty); this.mouseRawPolyline.ElementGroup = "Default"; this.gazeFixEllipse = new VGEllipse(ShapeDrawAction.Edge, this.penGazeFixation, VGStyleGroup.RPL_PEN_GAZE_FIX, string.Empty, string.Empty); this.gazeFixEllipse.ElementGroup = "Default"; this.mouseFixEllipse = new VGEllipse(ShapeDrawAction.Edge, this.penMouseFixation, VGStyleGroup.RPL_PEN_MOUSE_FIX, string.Empty, string.Empty); this.mouseFixEllipse.ElementGroup = "Default"; this.gazeFixConPolyline = new VGPolyline(ShapeDrawAction.Edge, this.penGazeFixationConnection, VGStyleGroup.RPL_PEN_GAZE_FIXCON, string.Empty, string.Empty); this.gazeFixConPolyline.ElementGroup = "Default"; this.mouseFixConPolyline = new VGPolyline(ShapeDrawAction.Edge, this.penMouseFixationConnection, VGStyleGroup.RPL_PEN_MOUSE_FIXCON, string.Empty, string.Empty); this.mouseFixConPolyline.ElementGroup = "Default"; this.gazeFixConLine = new VGLine(ShapeDrawAction.Edge, this.penGazeFixationConnection, VGStyleGroup.RPL_PEN_GAZE_FIXCON, string.Empty, string.Empty); this.gazeFixConLine.ElementGroup = "Default"; this.mouseFixConLine = new VGLine(ShapeDrawAction.Edge, this.penMouseFixationConnection, VGStyleGroup.RPL_PEN_MOUSE_FIXCON, string.Empty, string.Empty); this.mouseFixConLine.ElementGroup = "Default"; var gazeCursorSize = (float)Properties.Settings.Default.GazeCursorSize; var gazeCursorType = (VGCursor.DrawingCursors)Enum.Parse( typeof(VGCursor.DrawingCursors), Properties.Settings.Default.GazeCursorType); this.gazeCursor = new VGCursor(this.penGazeCursor, gazeCursorType, gazeCursorSize, VGStyleGroup.RPL_PEN_GAZE_CURSOR); this.gazeCursor.ElementGroup = "Default"; var mouseCursorSize = (float)Properties.Settings.Default.MouseCursorSize; var mouseCursorType = (VGCursor.DrawingCursors)Enum.Parse( typeof(VGCursor.DrawingCursors), Properties.Settings.Default.MouseCursorType); this.mouseCursor = new VGCursor(this.penMouseCursor, mouseCursorType, mouseCursorSize, VGStyleGroup.RPL_PEN_MOUSE_CURSOR); this.mouseCursor.ElementGroup = "Default"; if (Document.ActiveDocument != null) { this.visiblePartOfScreen = new VGRectangle( ShapeDrawAction.Edge, Pens.Red, Document.ActiveDocument.PresentationSizeRectangle); this.visiblePartOfScreen.Visible = false; } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }
/// <summary> /// This method returns an default colored <see cref="VGElement"/> /// that represents the object in the database described by the three parameters /// </summary> /// <param name="shapeType">A <see cref="String"/> with the shape type Rectangle, Ellipse or Polyline</param> /// <param name="shapeName">A <see cref="String"/> with the shape name</param> /// <param name="shapeGroup">A <see cref="String"/> with the shapes group</param> /// <param name="strPtList">A <see cref="String"/> with the list of points to be converted /// with <see cref="ObjectStringConverter.StringToPointFList(String)"/></param> /// <returns>A <see cref="VGElement"/> that represents the object in the database described by the three parameters.</returns> public static VGElement GetVGElementFromDatabase( string shapeType, string shapeName, string shapeGroup, string strPtList) { // Create the shape depending on ShapeType RectangleF boundingRect = new RectangleF(); List<PointF> pointList = ObjectStringConverter.StringToPointFList(strPtList); switch (shapeType) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGRectangle newRect = new VGRectangle( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, boundingRect, VGStyleGroup.None, shapeName, shapeGroup); newRect.TextAlignment = VGAlignment.Center; return newRect; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGEllipse newEllipse = new VGEllipse( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, boundingRect, VGStyleGroup.None, shapeName, shapeGroup); newEllipse.TextAlignment = VGAlignment.Center; return newEllipse; case "Polyline": // Create Polyline with defined stroke VGPolyline newPolyline = new VGPolyline( ShapeDrawAction.NameAndEdge, Pens.Red, SystemFonts.MenuFont, Color.Black, VGStyleGroup.None, shapeName, shapeGroup); newPolyline.TextAlignment = VGAlignment.Center; foreach (PointF point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); boundingRect = newPolyline.Bounds; return newPolyline; } return null; }
/// <summary> /// This method converts the AOI table with areas of interest from the database /// into a list of <see cref="VGElement"/>s. /// </summary> /// <param name="aoiTable">The <see cref="DataTable"/> with the AOIs.</param> /// <returns>A <see cref="List{VGElement}"/> with the shapes.</returns> protected virtual VGElementCollection GetAOIElements(DataTable aoiTable) { Pen defaultPen = new Pen(Properties.Settings.Default.AOIStandardColor, Properties.Settings.Default.AOIStandardWidth); Pen targetPen = new Pen(Properties.Settings.Default.AOITargetColor, Properties.Settings.Default.AOITargetWidth); Pen searchRectPen = new Pen(Properties.Settings.Default.AOISearchRectColor, Properties.Settings.Default.AOISearchRectWidth); Font defaultFont = (Font)Properties.Settings.Default.AOIStandardFont.Clone(); Font targetFont = (Font)Properties.Settings.Default.AOITargetFont.Clone(); Font searchRectFont = (Font)Properties.Settings.Default.AOISearchRectFont.Clone(); Color defaultFontColor = Properties.Settings.Default.AOIStandardFontColor; Color targetFontColor = Properties.Settings.Default.AOITargetFontColor; Color searchRectFontColor = Properties.Settings.Default.AOISearchRectFontColor; VGElementCollection aoiList = new VGElementCollection(); int counter = 0; try { foreach (DataRow row in aoiTable.Rows) { string strPtList = row["ShapePts"].ToString(); string shapeName = row["ShapeName"].ToString(); Pen usedPen = defaultPen; Font usedFont = defaultFont; Color usedFontColor = defaultFontColor; VGStyleGroup usedStyleGroup = VGStyleGroup.AOI_NORMAL; List<PointF> pointList = ObjectStringConverter.StringToPointFList(strPtList); string usedElementGroup = row["ShapeGroup"].ToString(); switch (usedElementGroup) { case "Target": usedPen = targetPen; usedFont = targetFont; usedFontColor = targetFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; case "SearchRect": usedPen = searchRectPen; usedFont = searchRectFont; usedFontColor = searchRectFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; default: usedPen = defaultPen; usedFont = defaultFont; usedFontColor = defaultFontColor; usedStyleGroup = VGStyleGroup.SCA_GRID_AOI; break; } // Create the shape depending on ShapeType RectangleF boundingRect = new RectangleF(); switch (row["ShapeType"].ToString()) { case "Rectangle": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGRectangle newRect = new VGRectangle( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); aoiList.Add(newRect); break; case "Ellipse": boundingRect.Location = pointList[0]; boundingRect.Width = pointList[2].X - pointList[0].X; boundingRect.Height = pointList[2].Y - pointList[0].Y; // Create Rect with defined stroke VGEllipse newEllipse = new VGEllipse( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, boundingRect, usedStyleGroup, shapeName, usedElementGroup); aoiList.Add(newEllipse); break; case "Polyline": // Create Polyline with defined stroke VGPolyline newPolyline = new VGPolyline( ShapeDrawAction.NameAndEdge, usedPen, usedFont, usedFontColor, usedStyleGroup, shapeName, usedElementGroup); foreach (PointF point in pointList) { newPolyline.AddPt(point); } newPolyline.ClosePolyline(); aoiList.Add(newPolyline); boundingRect = newPolyline.Bounds; break; } counter++; } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } return aoiList; }
/// <summary> /// Draw fixation circles over original image with line connections in between. /// </summary> /// <param name="sampleType">The <see cref="SampleType"/> to draw. Can be gaze or mouse.</param> private void DrawSamples(SampleType sampleType) { try { DataView usedFixationTable = null; VGStyleGroup usedGroup = VGStyleGroup.None; Pen usedPen = null; Font usedFont = null; Color usedFontColor = Color.Empty; VGLine usedConnectionLine = new VGLine(ShapeDrawAction.Edge, Pens.Red); FixationDrawingMode usedFixationDrawingMode = FixationDrawingMode.None; // Initialize variables bool drawLine = false; bool drawNumber = false; int eyeMonX = this.StimulusSize.Width; int eyeMonY = this.StimulusSize.Height; // Set used variables switch (sampleType) { case SampleType.Gaze: usedFixationTable = this.gazeFixationsView; usedGroup = VGStyleGroup.FIX_GAZE_ELEMENT; usedPen = this.gazeFixationsPen; usedFont = this.gazeFixationsFont; usedFontColor = this.gazeFixationsFontColor; usedConnectionLine.Pen = this.gazeFixationConnectionsPen; usedFixationDrawingMode = this.gazeDrawingMode; if (this.gazeConnections) { drawLine = true; } if (this.gazeNumbers) { drawNumber = true; } break; case SampleType.Mouse: usedFixationTable = this.mouseFixationsView; usedGroup = VGStyleGroup.FIX_MOUSE_ELEMENT; usedPen = this.mouseFixationsPen; usedFont = this.mouseFixationsFont; usedFontColor = this.mouseFixationsFontColor; usedConnectionLine.Pen = this.mouseFixationConnectionsPen; usedFixationDrawingMode = this.mouseDrawingMode; if (this.mouseConnections) { drawLine = true; } if (this.mouseNumbers) { drawNumber = true; } break; } // TextureBrush bkgBrush = null; // if (usedFixationDrawingMode == FixationDrawingMode.Circles) // { // Bitmap bkg = new Bitmap(eyeMonX, eyeMonY); // Bitmap transparentBkg = new Bitmap(eyeMonX, eyeMonY); // using (Graphics graphics = Graphics.FromImage(bkg)) // { // ColorMatrix colorMatrix = new ColorMatrix(); // colorMatrix.Matrix33 = 0.7f; // ImageAttributes attributes = new ImageAttributes(); // attributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); // if (this.BGSlide != null) // { // Slide.DrawSlideAsync(this.BGSlide, graphics); // } // using (Graphics transGraphics = Graphics.FromImage(transparentBkg)) // { // transGraphics.DrawImage(bkg, new Rectangle(0, 0, bkg.Width, bkg.Height), 0, 0, bkg.Width, bkg.Height, GraphicsUnit.Pixel, attributes); // bkgBrush = new TextureBrush(transparentBkg); // } // } // bkg.Dispose(); // transparentBkg.Dispose(); // } // Loop Fixations and draw each one for (int i = 0; i < usedFixationTable.Count; i++) { DataRow row = usedFixationTable[i].Row; // Skip samples that are out of timing section bounds long fixationStartTime = row.IsNull("StartTime") ? 0 : Convert.ToInt64(row["StartTime"]); if (fixationStartTime < this.SectionStartTime) { continue; } if (fixationStartTime > this.SectionEndTime) { break; } float x = !row.IsNull("PosX") ? Convert.ToSingle(row["PosX"]) : 0; float y = !row.IsNull("PosY") ? Convert.ToSingle(row["PosY"]) : 0; PointF newFixationLocation = new PointF(x, y); float factor = (int)row["Length"]; if (drawLine && this.foregoingFixationLocation != PointF.Empty) { // Add Point to connectionline usedConnectionLine.FirstPoint = this.foregoingFixationLocation; usedConnectionLine.SecondPoint = newFixationLocation; this.Elements.Add((VGElement)usedConnectionLine.Clone()); } this.foregoingFixationLocation = newFixationLocation; // Create fixation description if applicable string name = string.Empty; if (drawNumber) { name = row["CountInTrial"].ToString(); } switch (usedFixationDrawingMode) { case FixationDrawingMode.None: if (drawNumber) { // Create Ellipse with DOTSIZEd bounding rect int placeHolderSize = (int)(usedFont.Size * DOTSIZE); RectangleF numberBoundingRect = new RectangleF( x - placeHolderSize / 2, y - placeHolderSize / 2, placeHolderSize, placeHolderSize); // Draw Ellipse VGEllipse newNameEllipse = new VGEllipse( ShapeDrawAction.Name, (Pen)usedPen.Clone(), new SolidBrush(usedPen.Color), (Font)usedFont.Clone(), usedFontColor, numberBoundingRect, usedGroup, name, string.Empty); this.Elements.Add(newNameEllipse); } break; case FixationDrawingMode.Dots: // Create Ellipse with DOTSIZEd bounding rect RectangleF dotBoundingRect = new RectangleF( x - DOTSIZE / 2, y - DOTSIZE / 2, DOTSIZE, DOTSIZE); Font ont = (Font)usedFont.Clone(); // Draw Ellipse VGEllipse newEllipse = new VGEllipse( ShapeDrawAction.NameAndFill, (Pen)usedPen.Clone(), new SolidBrush(usedPen.Color), (Font)usedFont.Clone(), usedFontColor, dotBoundingRect, usedGroup, name, string.Empty); this.Elements.Add(newEllipse); break; case FixationDrawingMode.Circles: RectangleF fixBoundingRect = this.GetBoundingRectFromRow(sampleType, row); newEllipse = new VGEllipse( ShapeDrawAction.NameAndEdge, (Pen)usedPen.Clone(), null, // (TextureBrush)bkgBrush.Clone(), (Font)usedFont.Clone(), usedFontColor, fixBoundingRect, usedGroup, name, string.Empty); this.Elements.Add(newEllipse); break; case FixationDrawingMode.Spotlight: if (drawNumber) { dotBoundingRect = new RectangleF(x - DOTSIZE / 2, y - DOTSIZE / 2, DOTSIZE, DOTSIZE); newEllipse = new VGEllipse( ShapeDrawAction.Name, (Pen)usedPen.Clone(), new SolidBrush(usedPen.Color), (Font)usedFont.Clone(), usedFontColor, dotBoundingRect, usedGroup, name, string.Empty); this.Elements.Add(newEllipse); } fixBoundingRect = this.GetBoundingRectFromRow(sampleType, row); this.spotlightRegion.AddEllipse(fixBoundingRect); break; case FixationDrawingMode.AttentionMap: if (drawNumber) { dotBoundingRect = new RectangleF(x - DOTSIZE / 2, y - DOTSIZE / 2, DOTSIZE, DOTSIZE); newEllipse = new VGEllipse( ShapeDrawAction.Name, (Pen)usedPen.Clone(), new SolidBrush(usedPen.Color), (Font)usedFont.Clone(), usedFontColor, dotBoundingRect, usedGroup, name, string.Empty); this.Elements.Add(newEllipse); } float[,] kernelMultiplied = AttentionMaps.MultiplyKernel(factor, AttentionMaps.KernelSize); AttentionMaps.AddKernelToArray( this.distributionArray, (int)x, (int)y, eyeMonX, eyeMonY, AttentionMaps.KernelSize, kernelMultiplied); break; } } // if (bkgBrush != null) // { // bkgBrush.Dispose(); // } } catch (Exception ex) { ExceptionMethods.HandleException(ex); } }