WPF: Use the custom text editor for editing text of text annotation in annotation viewer.

Code samples for VintaSoft Annotation .NET Plug-in. Here you can request a code sample.

Moderator: Alex

Post Reply
Alex
Site Admin
Posts: 1474
Joined: Thu Jul 10, 2008 2:21 pm

WPF: Use the custom text editor for editing text of text annotation in annotation viewer.

Post by Alex » Fri Mar 03, 2017 12:52 pm

This topic contains a code snippet that shows how to use the custom text editor for editing the text of text annotation in WPF annotation viewer:

Code: Select all

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

using Vintasoft.Imaging;
using Vintasoft.Imaging.Annotation;
using Vintasoft.Imaging.Annotation.Wpf.UI;
using Vintasoft.Imaging.Annotation.Wpf.UI.VisualTools;
using Vintasoft.Imaging.Annotation.Wpf.UI.VisualTools.UserInteraction;
using Vintasoft.Imaging.Wpf;
using Vintasoft.Imaging.Wpf.UI;
using Vintasoft.Imaging.Wpf.UI.VisualTools.UserInteraction;
using Vintasoft.Imaging.Wpf.Utils;


namespace WpfApplication1
{
    /// <summary>
    /// Main window.
    /// </summary>
    public partial class Window1 : Window
    {

        #region Fields

        /// <summary>
        /// Determines that the building process of annotation is finished.
        /// </summary>
        bool _isAnnotationBuildingFinished = false;

        /// <summary>
        /// Determines that the text editing must be started when text annotation is created.
        /// </summary>
        bool _startTextEditingWhenTextAnnotationIsCreated = false;

        #endregion



        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Window1"/> class.
        /// </summary>
        public Window1()
        {
            InitializeComponent();

            WpfAnnotationVisualTool annotationTool = annotationViewer.AnnotationVisualTool;

            annotationTool.AnnotationBuildingFinished +=
                new EventHandler<WpfAnnotationViewEventArgs>(annotationTool_AnnotationBuildingFinished);
            annotationTool.ActiveInteractionControllerChanged +=
                new PropertyChangedEventHandler<IWpfInteractionController>(annotationTool_ActiveInteractionControllerChanged);
        }

        #endregion



        #region Methods

        /// <summary>
        /// Raizes event <see cref="E:System.Windows.Window.Closed" />.
        /// </summary>
        protected override void OnClosed(EventArgs e)
        {
            annotationViewer.Images.ClearAndDisposeItems();

            base.OnClosed(e);
        }

        /// <summary>
        /// Loads images to viewer.
        /// </summary>
        private void loadImage_Click(object sender, RoutedEventArgs e)
        {
            // if building of annotation is not finished
            if (!_isAnnotationBuildingFinished)
            {
                WpfAnnotationVisualTool annotationTool = annotationViewer.AnnotationVisualTool;
                annotationTool.CancelAnnotationBuilding();
            }

            // remove all images
            annotationViewer.Images.ClearAndDisposeItems();

            Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
            dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            dialog.Filter = "Jpeg file|*.jpg;*.jpeg|Tiff file|*.tiff;*.tif|Png file|*.png|Bmp file|*.bmp";
            if (dialog.ShowDialog(this) == true)
            {
                try
                {
                    // load images
                    annotationViewer.Images.Add(dialog.FileName);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            addTextAnnotation.IsEnabled = annotationViewer.Image != null;
        }

        /// <summary>
        /// Adds text annotation.
        /// </summary>
        private void addTextAnnotation_Click(object sender, RoutedEventArgs e)
        {
            WpfAnnotationVisualTool annotationTool = annotationViewer.AnnotationVisualTool;

            // if building of annotation is not finished
            if (!_isAnnotationBuildingFinished)
                annotationTool.CancelAnnotationBuilding();

            _isAnnotationBuildingFinished = false;
            // create text annotation
            TextAnnotationData textAnnotation = new TextAnnotationData();

            textAnnotation.Text = "Text";
            textAnnotation.FontBrush = new AnnotationSolidBrush(System.Drawing.Color.DarkGreen);
            textAnnotation.FillBrush = new AnnotationSolidBrush(System.Drawing.Color.LightGray);
            textAnnotation.Border = true;
            textAnnotation.Outline.Width = 5;
            textAnnotation.Outline.Brush = new AnnotationSolidBrush(System.Drawing.Color.Blue);

            // build annotation
            annotationTool.AddAndBuildAnnotation(textAnnotation);
        }

        private void startTextEditingCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            _startTextEditingWhenTextAnnotationIsCreated = (bool)startTextEditingCheckBox.IsChecked;
        }


        /// <summary>
        /// Building of annotation is finished.
        /// </summary>
        private void annotationTool_AnnotationBuildingFinished(object sender, WpfAnnotationViewEventArgs e)
        {
            _isAnnotationBuildingFinished = true;

            if (_startTextEditingWhenTextAnnotationIsCreated &&
                e.AnnotationView is WpfTextAnnotationView)
            {
                e.AnnotationView.InteractionControllerChanged +=
                    new PropertyChangedEventHandler<IWpfInteractionController>(TextAnnotation_InteractionControllerChanged);
            }
        }

        /// <summary>
        /// The interaction controller of text annotation is changed.
        /// </summary>
        void TextAnnotation_InteractionControllerChanged(object sender, PropertyChangedEventArgs<IWpfInteractionController> e)
        {
            WpfRectangularTextAnnotationTransformer transformer =
                e.NewValue as WpfRectangularTextAnnotationTransformer;
            if (transformer != null)
            {
                WpfAnnotationView view = (WpfAnnotationView)sender;
                transformer.ShowTextBox(annotationViewer, new Point(0, 0));

                TextBox textBox = transformer.TextBox;
                textBox.Focus();
                textBox.Select(textBox.Text.Length, 0);
                textBox.ScrollToEnd();
                view.InteractionControllerChanged -=
                    new PropertyChangedEventHandler<IWpfInteractionController>(TextAnnotation_InteractionControllerChanged);
            }
        }

        /// <summary>
        /// The interaction controller of annotation is changed.
        /// </summary>
        private void annotationTool_ActiveInteractionControllerChanged(object sender,
            PropertyChangedEventArgs<IWpfInteractionController> e)
        {
            if (e.OldValue is WpfRectangularTextAnnotationTransformer)
            {
                WpfRectangularTextAnnotationTransformer transformer =
                    (WpfRectangularTextAnnotationTransformer)e.OldValue;

                transformer.TextBoxTransformer.TextBoxUpdated -=
                    new EventHandler<WpfTextObjectTextBoxTransformerEventArgs>(TextBoxTransformer_TextBoxUpdated);
            }

            if (e.NewValue is WpfRectangularTextAnnotationTransformer)
            {
                WpfRectangularTextAnnotationTransformer transformer =
                    (WpfRectangularTextAnnotationTransformer)e.NewValue;

                WpfTextObjectTextBoxTransformer textBoxTransformer = transformer.TextBoxTransformer;

                if (startTextEditingOneClickRadioButton.IsChecked == true)
                    textBoxTransformer.ActivateClickCount = 1;
                else if (startTextEditingDoubleClickRadioButton.IsChecked == true)
                    textBoxTransformer.ActivateClickCount = 2;

                textBoxTransformer.TextBoxUpdated +=
                    new EventHandler<WpfTextObjectTextBoxTransformerEventArgs>(TextBoxTransformer_TextBoxUpdated);
            }
        }

        /// <summary>
        /// Updates the text box of text annotation.
        /// </summary>
        void TextBoxTransformer_TextBoxUpdated(object sender, WpfTextObjectTextBoxTransformerEventArgs e)
        {
            TextBox textBox = e.TextBox;
            WpfTextAnnotationView annotationView = (WpfTextAnnotationView)e.TextObject;

            Scale scaleToImage = e.Viewer.ViewerState.ScaleToImage;
            Resolution imageResolution = e.Viewer.Image.Resolution;

            Scale textBoxScale = new Scale(
                (float)(scaleToImage.Horizontal * (imageResolution.Horizontal / 96.0)),
                (float)(scaleToImage.Vertical * (imageResolution.Vertical / 96.0)));

            // update colors of text box
            UpdateTextBoxColors(textBox, annotationView, textBoxScale);
            // update font of text box
            UpdateTextBoxFontStyle(textBox, annotationView, textBoxScale);
            // update location and size of text box
            UpdateTextBoxLocationAndSize(textBox, annotationView, e.Viewer, textBoxScale);
        }

        /// <summary>
        /// Updates colors of the text box.
        /// </summary>
        /// <param name="textBox">The text box.</param>
        /// <param name="annotationView">The annotation view.</param>
        /// <param name="textBoxScale">The scale of the text box.</param>
        private void UpdateTextBoxColors(TextBox textBox, WpfTextAnnotationView annotationView, Scale textBoxScale)
        {
            // if background color is solid
            if (annotationView.FillBrush is AnnotationSolidBrush)
            {
                // get brush
                AnnotationSolidBrush solidBrush = (AnnotationSolidBrush)annotationView.FillBrush;
                // create solid brush
                textBox.Background = new SolidColorBrush(WpfObjectConverter.CreateWindowsColor(solidBrush.Color));
            }
            else
                throw new NotImplementedException();

            // if font color is solid
            if (annotationView.FontBrush is AnnotationSolidBrush)
            {
                // get brush
                AnnotationSolidBrush solidBrush = (AnnotationSolidBrush)annotationView.FontBrush;
                // create solid brush
                textBox.Foreground = new SolidColorBrush(WpfObjectConverter.CreateWindowsColor(solidBrush.Color));
            }
            else
                throw new NotImplementedException();

            // create thickness of border
            Thickness borderThickness = new Thickness();
            // create brush of border
            SolidColorBrush borderBrush = new SolidColorBrush(Colors.Transparent);
            // if border is visible
            if (annotationView.Border)
            {
                // create brush
                borderBrush = new SolidColorBrush(
                    WpfObjectConverter.CreateWindowsColor(annotationView.Outline.Color));

                // get border width
                double width = annotationView.Outline.Width;
                // create thickness of border
                borderThickness = new Thickness(
                    width * textBoxScale.Horizontal,
                    width * textBoxScale.Vertical,
                    width * textBoxScale.Horizontal,
                    width * textBoxScale.Vertical);
            }
            // update thickness of border
            textBox.BorderThickness = borderThickness;
            // update brush of border
            textBox.BorderBrush = borderBrush;
        }

        /// <summary>
        /// Updates font style of the text box.
        /// </summary>
        /// <param name="textBox">The text box.</param>
        /// <param name="annotationView">The annotation view.</param>
        /// <param name="textBoxScale">The scale of the text box.</param>
        private void UpdateTextBoxFontStyle(
            TextBox textBox,
            WpfTextAnnotationView annotationView,
            Scale textBoxScale)
        {
            AnnotationFont font = annotationView.Font;

            // create font family of text
            textBox.FontFamily = new FontFamily(font.FamilyName);

            // calculate font size
            double fontSize = font.Size * textBoxScale.Horizontal;
            // convert font size to device independent pixels
            switch (font.Unit)
            {
                case AnnotationFontUnit.Display:
                    fontSize *= 96.0 / ImagingEnvironment.ScreenDpiX;
                    break;

                case AnnotationFontUnit.Document:
                    fontSize *= 96.0 / 300;
                    break;

                case AnnotationFontUnit.Inch:
                    fontSize *= 96.0;
                    break;

                case AnnotationFontUnit.Millimeter:
                    fontSize *= 96.0 / 25.4;
                    break;

                case AnnotationFontUnit.Point:
                    fontSize *= 96.0 / 72;
                    break;
            }
            textBox.FontSize = fontSize;

            // if font is italic
            if (font.Italic)
                textBox.FontStyle = FontStyles.Italic;

            // if font is bold
            if (font.Bold)
                textBox.FontWeight = FontWeights.Bold;

            // if font is strikeout
            if (font.Strikeout)
            {
                TextDecoration strikeout = new TextDecoration();
                strikeout.Location = TextDecorationLocation.Strikethrough;
                textBox.TextDecorations.Add(strikeout);
            }

            // if font is underline
            if (font.Underline)
            {
                TextDecoration underline = new TextDecoration();
                underline.Location = TextDecorationLocation.Underline;
                textBox.TextDecorations.Add(underline);
            }
        }

        /// <summary>
        /// Updates the size and location of the text box.
        /// </summary>
        /// <param name="textBox">The text box.</param>
        /// <param name="annotationView">The annotation view.</param>
        /// <param name="viewer">The viewer.</param>
        /// <param name="textBoxScale">The scale of the text box.</param>
        private void UpdateTextBoxLocationAndSize(
            TextBox textBox,
            WpfTextAnnotationView annotationView,
            WpfImageViewer viewer,
            Scale textBoxScale)
        {
            // update horizontal alignment of text
            switch (annotationView.TextHorizontalAlignment)
            {
                case AlignmentX.Center:
                    textBox.HorizontalContentAlignment = HorizontalAlignment.Center;
                    break;

                case AlignmentX.Left:
                    textBox.HorizontalContentAlignment = HorizontalAlignment.Left;
                    break;

                case AlignmentX.Right:
                    textBox.HorizontalContentAlignment = HorizontalAlignment.Right;
                    break;
            }

            // update vertical alignment of text
            switch (annotationView.TextVerticalAlignment)
            {
                case AlignmentY.Bottom:
                    textBox.VerticalContentAlignment = VerticalAlignment.Bottom;
                    break;

                case AlignmentY.Center:
                    textBox.VerticalContentAlignment = VerticalAlignment.Center;
                    break;

                case AlignmentY.Top:
                    textBox.VerticalContentAlignment = VerticalAlignment.Top;
                    break;
            }

            // get point transform of the annotation for image viewer
            WpfPointTransform transform = annotationView.GetPointTransform(viewer);

            // location of annotation
            Point location = annotationView.Location;
            // size of annotation
            Size size = annotationView.Size;

            // calculate top-left point of annotation
            Point topLeftPoint = new Point(location.X - size.Width / 2, location.Y - size.Height / 2);
            topLeftPoint = transform.TransformPoint(topLeftPoint);

            // calculate bottom-right point of annotation
            Point bottomRightPoint = new Point(location.X + size.Width / 2, location.Y + size.Height / 2);
            bottomRightPoint = transform.TransformPoint(bottomRightPoint);

            // calculate bounding box of text box
            double textBoxX = topLeftPoint.X;
            double textBoxY = topLeftPoint.Y;
            double textBoxWidth = bottomRightPoint.X - topLeftPoint.X;
            double textBoxHeight = bottomRightPoint.Y - topLeftPoint.Y;

            if (textBoxWidth <= 0)
                textBoxWidth = 0;
            if (textBoxHeight <= 0)
                textBoxHeight = 0;

            // update location and size of text box
            Canvas.SetLeft(textBox, textBoxX);
            Canvas.SetTop(textBox, textBoxY);
            textBox.Width = textBoxWidth;
            textBox.Height = textBoxHeight;

            // calculate padding of text
            double textPaddingLeft = annotationView.TextPadding.Left * textBoxScale.Horizontal;
            double textPaddingTop = annotationView.TextPadding.Top * textBoxScale.Vertical;
            double textPaddingRight = annotationView.TextPadding.Right * textBoxScale.Horizontal;
            double textPaddingBottom = annotationView.TextPadding.Bottom * textBoxScale.Vertical;

            // if border is not visible
            if (!annotationView.Border)
            {
                double borderHorizontal = annotationView.Outline.Width * textBoxScale.Horizontal;
                double borderVertical = annotationView.Outline.Width * textBoxScale.Vertical;

                // update padding of text
                textPaddingLeft += borderHorizontal;
                textPaddingTop += borderVertical;
                textPaddingRight += borderHorizontal;
                textPaddingBottom += borderVertical;
            }

            textBox.Padding = new Thickness(
                textPaddingLeft,
                textPaddingTop,
                textPaddingRight,
                textPaddingBottom);

            // if annotation is mirrored
            if (annotationView.HorizontalMirrored ||
                annotationView.VerticalMirrored)
            {
                // create transform
                TransformGroup layoutTransform = new TransformGroup();
                // if annotation is horizontal mirrored
                if (annotationView.HorizontalMirrored)
                    layoutTransform.Children.Add(new ScaleTransform(-1, 1));
                // if annotation is vertical mirrored
                if (annotationView.VerticalMirrored)
                    layoutTransform.Children.Add(new ScaleTransform(1, -1));
                textBox.LayoutTransform = layoutTransform;
            }

            // if annotation is rotated
            if (annotationView.Rotation != 0)
            {
                // rotate annotation at center of annotation
                textBox.RenderTransformOrigin = new Point(0.5, 0.5);
                // rotate annotation
                textBox.RenderTransform = new RotateTransform(annotationView.Rotation);
            }
        }
        
        private void startTextEditingClickRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if (annotationViewer == null)
                return;

            IWpfInteractionController controller =
                annotationViewer.AnnotationVisualTool.ActiveInteractionController;

            if (controller is WpfRectangularTextAnnotationTransformer)
            {
                WpfRectangularTextAnnotationTransformer transformer =
                    (WpfRectangularTextAnnotationTransformer)controller;

                WpfTextObjectTextBoxTransformer textBoxTransformer = transformer.TextBoxTransformer;

                if (startTextEditingOneClickRadioButton.IsChecked == true)
                    textBoxTransformer.ActivateClickCount = 1;
                else if (startTextEditingDoubleClickRadioButton.IsChecked == true)
                    textBoxTransformer.ActivateClickCount = 2;
            }
        }

        #endregion

    }
}

Source codes of WPF application can be downloaded here.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest