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; }
/// <inheritdoc/> public FrameworkElement ResolveEditor(PropertyItem propertyItem) { FrameworkElement editorControl; DependencyProperty bindingProperty; if (propertyItem.Instance is TimeIntervalAnnotationDisplayData objectData) { // Get the schema definition for the property item. AnnotationSchemaDefinition schemaDefinition = objectData.Definition.SchemaDefinitions.FirstOrDefault(s => s.Name == propertyItem.DisplayName); // If the schema is finite and not readonly, then display the possible values in a combobox, otherwise // just display the current value in a readonly textbox. Non-finite schemas are always displayed // in a textbox since there are infinite vallues possible. if (!propertyItem.IsReadOnly && schemaDefinition.Schema.IsFiniteAnnotationSchema) { // Create the combobox and load it with the schema values ComboBox comboBox = new ComboBox(); Type schemaType = schemaDefinition.Schema.GetType(); MethodInfo valuesProperty = schemaType.GetProperty("Values").GetGetMethod(); comboBox.ItemsSource = (IEnumerable)valuesProperty.Invoke(schemaDefinition.Schema, new object[] { }); comboBox.SelectedItem = propertyItem.Value; editorControl = comboBox; bindingProperty = ComboBox.SelectedItemProperty; } else { // create the textbox and optionally make it readonly TextBox textBox = new TextBox(); textBox.IsReadOnly = propertyItem.IsReadOnly; editorControl = textBox; bindingProperty = TextBox.TextProperty; } // Bind the editor control to the property item's value property. Binding binding = new Binding(nameof(PropertyItem.Value)); binding.Source = propertyItem; binding.ValidatesOnExceptions = true; binding.ValidatesOnDataErrors = true; binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay; binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; BindingOperations.SetBinding(editorControl, bindingProperty, binding); return(editorControl); } else { throw new ArgumentException($"{nameof(propertyItem)} argument must be a {nameof(TimeIntervalAnnotationDisplayData)}"); } }
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(); }