private void EditFiniteAnnotationValue(TimeIntervalAnnotationDisplayData displayData, int trackId) { // Get the schema definition AnnotationSchemaDefinition schemaDefinition = displayData.Definition.SchemaDefinitions[trackId]; // Get the collection of possible values Type schemaType = schemaDefinition.Schema.GetType(); MethodInfo valuesProperty = schemaType.GetProperty("Values").GetGetMethod(); IEnumerable values = (IEnumerable)valuesProperty.Invoke(schemaDefinition.Schema, new object[] { }); // Create a new context menu ContextMenu contextMenu = new ContextMenu(); // Create a menuitem for each value, with a command to update the value on the annotation. foreach (object value in values) { var metadata = this.GetAnnotationValueMetadata(value, schemaDefinition.Schema); contextMenu.Items.Add(MenuItemHelper.CreateAnnotationMenuItem( value.ToString(), metadata.BorderColor, metadata.FillColor, new PsiCommand(() => this.StreamVisualizationObject.SetAnnotationValue(displayData.Annotation, schemaDefinition.Name, value)))); } // Add a handler so that the timeline visualization panel continues to receive mouse move messages // while the context menu is displayed, and remove the handler once the context menu closes. MouseEventHandler mouseMoveHandler = new MouseEventHandler(this.FindTimelineVisualizationPanelView().ContextMenuMouseMove); contextMenu.AddHandler(MouseMoveEvent, mouseMoveHandler, true); contextMenu.Closed += (sender, e) => contextMenu.RemoveHandler(MouseMoveEvent, mouseMoveHandler); // Show the context menu contextMenu.IsOpen = true; }
private void EditUnrestrictedAnnotationValue(TimeIntervalAnnotationDisplayData displayData, int trackId) { // Get the schema definition AnnotationSchemaDefinition schemaDefinition = displayData.Definition.SchemaDefinitions[trackId]; // Get the current value object value = displayData.Annotation.Data.Values[schemaDefinition.Name]; // Get the associated metadata AnnotationSchemaValueMetadata schemaMetadata = this.GetAnnotationValueMetadata(value, schemaDefinition.Schema); // Style the text box to match the schema of the annotation value this.EditUnrestrictedAnnotationTextBox.Foreground = new SolidColorBrush(ToMediaColor(schemaMetadata.TextColor)); this.EditUnrestrictedAnnotationTextBox.Background = new SolidColorBrush(ToMediaColor(schemaMetadata.FillColor)); this.EditUnrestrictedAnnotationTextBox.BorderBrush = new SolidColorBrush(ToMediaColor(schemaMetadata.BorderColor)); this.EditUnrestrictedAnnotationTextBox.BorderThickness = new Thickness(schemaMetadata.BorderWidth); // The textbox's tag holds context information to allow us to update the value in the display object when // the text in the textbox changes. Note that we must set the correct tag before we set the text, otherwise // setting the text will cause it to be copied to the last annotation that we edited. this.EditUnrestrictedAnnotationTextBox.Tag = new UnrestrictedAnnotationValueContext(displayData, schemaDefinition.Name); this.EditUnrestrictedAnnotationTextBox.Text = value.ToString(); // Set the textbox position to exactly cover the annotation value var navigatorViewDuration = this.Navigator.ViewRange.Duration.TotalSeconds; var labelStart = Math.Min(navigatorViewDuration, Math.Max((displayData.StartTime - this.Navigator.ViewRange.StartTime).TotalSeconds, 0)); var labelEnd = Math.Max(0, Math.Min((displayData.EndTime - this.Navigator.ViewRange.StartTime).TotalSeconds, navigatorViewDuration)); var verticalSpace = this.StreamVisualizationObject.Padding / this.ScaleTransform.ScaleY; var lo = (double)(trackId + verticalSpace) / this.StreamVisualizationObject.TrackCount; var hi = (double)(trackId + 1 - verticalSpace) / this.StreamVisualizationObject.TrackCount; this.EditUnrestrictedAnnotationTextBox.Width = (labelEnd - labelStart) * this.Canvas.ActualWidth / this.Navigator.ViewRange.Duration.TotalSeconds; this.EditUnrestrictedAnnotationTextBox.Height = (hi - lo) * this.Canvas.ActualHeight; (this.EditUnrestrictedAnnotationTextBox.RenderTransform as TranslateTransform).X = labelStart * this.Canvas.ActualWidth / this.Navigator.ViewRange.Duration.TotalSeconds; (this.EditUnrestrictedAnnotationTextBox.RenderTransform as TranslateTransform).Y = lo * this.Canvas.ActualHeight; // Initially select the entire text of the textbox, then show the textbox and set keyboard focus to it. this.EditUnrestrictedAnnotationTextBox.SelectAll(); this.EditUnrestrictedAnnotationTextBox.Visibility = Visibility.Visible; this.EditUnrestrictedAnnotationTextBox.Focus(); }
/// <summary> /// Initializes a new instance of the <see cref="TimeIntervalAnnotationVisualizationObjectViewItem"/> class. /// </summary> /// <param name="parent">The parent view.</param> /// <param name="annotationDisplayData">The data for all annotations in this view item.</param> internal TimeIntervalAnnotationVisualizationObjectViewItem(TimeIntervalAnnotationVisualizationObjectView parent, TimeIntervalAnnotationDisplayData annotationDisplayData) { this.parent = parent; this.annotationDisplayData = annotationDisplayData; annotationDisplayData.PropertyChanged += this.AnnotationDisplayData_PropertyChanged; this.figures = new List <Path>(); this.labels = new List <Grid>(); foreach (AnnotationSchemaDefinition schemaDefinition in annotationDisplayData.Definition.SchemaDefinitions) { PathFigure annotationElementFigure = new PathFigure() { StartPoint = new Point(0, 0), IsClosed = true, IsFilled = true, }; annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); PathGeometry pathGeometry = new PathGeometry() { Transform = this.parent.TransformGroup }; pathGeometry.Figures.Add(annotationElementFigure); Path path = new Path() { Data = pathGeometry }; this.figures.Add(path); Grid labelGrid = new Grid { RenderTransform = new TranslateTransform(), IsHitTestVisible = false, }; TextBlock textBlock = new TextBlock() { VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(3), IsHitTestVisible = false, }; labelGrid.Children.Add(textBlock); this.labels.Add(labelGrid); // Get the current value object value = annotationDisplayData.Annotation.Data.Values[schemaDefinition.Name]; // Get the metadata associtaed with the value AnnotationSchemaValueMetadata schemaMetadata = this.GetAnnotationValueMetadata(value, schemaDefinition.Schema); // Set the colors etc path.Stroke = this.parent.GetBrush(schemaMetadata.BorderColor); path.StrokeThickness = schemaMetadata.BorderWidth; path.Fill = this.parent.GetBrush(schemaMetadata.FillColor); textBlock.Foreground = this.parent.GetBrush(schemaMetadata.TextColor); } foreach (Path figure in this.figures) { this.parent.Canvas.Children.Add(figure); } foreach (Grid label in this.labels) { this.parent.Canvas.Children.Add(label); } }
public UnrestrictedAnnotationValueContext(TimeIntervalAnnotationDisplayData displayData, string valueName) { this.DisplayData = displayData; this.ValueName = valueName; }
/// <summary> /// Initializes a new instance of the <see cref="TimeIntervalAnnotationVisualizationObjectViewItem"/> class. /// </summary> /// <param name="parent">The parent view.</param> /// <param name="annotationDisplayData">The data for all annotations in this view item.</param> internal TimeIntervalAnnotationVisualizationObjectViewItem(TimeIntervalAnnotationVisualizationObjectView parent, TimeIntervalAnnotationDisplayData annotationDisplayData) { this.parent = parent; this.annotationDisplayData = annotationDisplayData; annotationDisplayData.PropertyChanged += this.AnnotationDisplayData_PropertyChanged; this.figures = new List <Path>(); this.labels = new List <Grid>(); foreach (var attributeSchema in annotationDisplayData.AnnotationSchema.AttributeSchemas) { var annotationElementFigure = new PathFigure() { StartPoint = new Point(0, 0), IsClosed = true, IsFilled = true, }; annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); annotationElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); var pathGeometry = new PathGeometry() { Transform = this.parent.TransformGroup }; pathGeometry.Figures.Add(annotationElementFigure); var path = new Path() { Data = pathGeometry }; this.figures.Add(path); var labelGrid = new Grid { RenderTransform = new TranslateTransform(), IsHitTestVisible = false, }; var textBlock = new TextBlock() { VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(3), IsHitTestVisible = false, }; labelGrid.Children.Add(textBlock); this.labels.Add(labelGrid); // Set the colors etc var annotationValue = annotationDisplayData.Annotation.AttributeValues[attributeSchema.Name]; path.Fill = this.parent.GetBrush(annotationValue.FillColor); textBlock.Foreground = this.parent.GetBrush(annotationValue.TextColor); } var borderElementFigure = new PathFigure() { StartPoint = new Point(0, 0), IsClosed = true, IsFilled = true, }; borderElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); borderElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); borderElementFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); var borderPathGeometry = new PathGeometry() { Transform = this.parent.TransformGroup }; borderPathGeometry.Figures.Add(borderElementFigure); this.borderPath = new Path() { Data = borderPathGeometry, Stroke = new SolidColorBrush(Colors.Gray), StrokeThickness = 2, }; // Insert the figure and labels in the parent canvas, but at the beginning, starting // from index 1. At index 0 we have the track highlight child. Inserting from index // 1 ensures that the track label items remain towards the tail of the list of canvas // children, making sure they stay on top in z-order. int index = 2; foreach (var figure in this.figures) { this.parent.Canvas.Children.Insert(index++, figure); } foreach (var label in this.labels) { this.parent.Canvas.Children.Insert(index++, label); } this.parent.Canvas.Children.Insert(index++, this.borderPath); }