using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Tango.Core; using Tango.Editors; namespace Tango.Editors { /// /// /// Represents a editor with position, size and angle control. /// /// /// /// /// /// The following example demonstrates a basic scenario of using and by creating a simple video projection application with the following features: /// /// /// Use the mouse to draw any type of tile of the editor surface. /// Apply any input shape on any tile. /// Load any video and display it on any of the selected tile. /// Built in support for undo, redo, cut, copy and paste, delete and select operations. /// Built in support for saving/loading the editor state to memory or file. /// Built in support for tile and editor properties adjustment using the . /// /// /// /// /// Code-Behind. /// /// /// [ContentProperty("InnerContent")] public partial class FrameworkElementEditor : ElementEditor { /// /// Initializes a new instance of the class. /// public FrameworkElementEditor() : base() { InitializeComponent(); } /// /// Initializes a new instance of the class. /// /// The framework element. public FrameworkElementEditor(FrameworkElement frameworkElement) : this() { Element = frameworkElement; } /// /// Initializes a new instance of the class. /// /// The framework element. /// The bounds. public FrameworkElementEditor(FrameworkElement frameworkElement, Rect bounds) : this(frameworkElement) { Left = bounds.Left; Top = bounds.Top; Width = bounds.Width; Height = bounds.Height; } /// /// Gets or sets the framework element. /// public FrameworkElement Element { get { return (FrameworkElement)GetValue(ElementProperty); } set { SetValue(ElementProperty, value); } } public static readonly DependencyProperty ElementProperty = DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(FrameworkElementEditor), new PropertyMetadata(null)); /// /// Clones this instance. /// /// public override IElementEditor Clone() { try { FrameworkElementEditor cloned = new FrameworkElementEditor(); if (Element is IConfigurable) { cloned.Element = (Element as IConfigurable).Clone() as FrameworkElement; } else { cloned.Element = FrameworkElementCloner.Clone(Element); } cloned.ElementDetached = ElementDetached; cloned.Top = Top; cloned.Left = Left; cloned.Width = Width; cloned.Height = Height; cloned.Angle = Angle; cloned.Background = Background; cloned.Foreground = Foreground; cloned.CornersBrush = CornersBrush; return cloned; } catch (Exception ex) { throw new InvalidOperationException("Could not clone this editor. You may have to create a custom editor and implement a custom Clone method.", ex); } } /// /// Gets the hosted element. /// [ParameterIgnore] public override Object HostedElement { get { return Element; } } /// /// Gets a configuration object representing the configurable properties. This configuration can be serialized to a stream or file, and later be loaded and applied to the configurable object. /// /// public override IConfiguration GetConfiguration() { FrameworkElementEditorConfiguration config = new FrameworkElementEditorConfiguration(base.GetConfiguration() as ElementEditorConfiguration); try { config.ElementXaml = FrameworkElementCloner.Serialize(Element); } catch { Debug.WriteLine("Could not serialize framework element with ID " + ID); } return config; } /// /// Invoked when the attached editor has changed. /// protected override void OnAttachedEditorChanged() { base.OnAttachedEditorChanged(); } /// /// Applies the specified configuration with an optional animation if supported by the configurable type. /// /// The configuration. /// The animation. public override void SetConfiguration(IConfiguration configuration, ConfigurationAnimation animation) { if (!(configuration is FrameworkElementEditorConfiguration)) { throw new InvalidConfigurationException(); } var config = configuration as FrameworkElementEditorConfiguration; try { Element = FrameworkElementCloner.Deserialize(config.ElementXaml); } catch { Debug.WriteLine("Could not deserialize framework element with ID " + ID); } base.SetConfiguration(configuration, animation); } /// /// Called when the editor detached property has changed. /// protected override void OnElementDetachedChanged() { base.OnElementDetachedChanged(); if (ElementDetached) { Element.Bind(Canvas.LeftProperty, this, LeftProperty, BindingMode.TwoWay); Element.Bind(Canvas.TopProperty, this, TopProperty, BindingMode.TwoWay); Element.Bind(FrameworkElement.WidthProperty, this, WidthProperty, BindingMode.TwoWay); Element.Bind(FrameworkElement.HeightProperty, this, HeightProperty, BindingMode.TwoWay); Element.RenderTransformOrigin = new Point(0.5, 0.5); RotateTransform rotate = new RotateTransform(); Element.RenderTransform = rotate; rotate.Bind(RotateTransform.AngleProperty, this, AngleProperty, BindingMode.TwoWay); } else { Element.Unbind(Canvas.LeftProperty); Element.Unbind(Canvas.TopProperty); Element.Unbind(FrameworkElement.WidthProperty); Element.Unbind(FrameworkElement.HeightProperty); Element.RenderTransform = null; } } } }