コード例 #1
0
        /// <summary>
        /// Initializes the specified element and its descendants by hooking property bindings and events.
        /// </summary>
        /// <param name="element">The element.</param>
        private void InitElement(SkiaFrameworkElement element)
        {
            if (!GetIsInitialized(element))
            {
                if (EnableBinding)
                {
                    foreach (var bindingProperty in element.GetBindingProperties())
                    {
                        var container = BindingEventContainer.Generate(element, bindingProperty);
                        container.ValueChanged += OnBindingContainerValueChanged;
                        _containers.Add(container);

                        _bindingThrottlers.Add(container.BindingProperty, new ActionThrottle(TimeSpan.FromMilliseconds(1000d / BindingFPS), _host.Dispatcher));
                    }
                }

                element.ChildAdded   += Element_ChildAdded;
                element.ChildRemoved += Element_ChildRemoved;

                SetIsInitialized(element, true);
            }

            foreach (var child in element.Children)
            {
                InitElement(child);
            }
        }
コード例 #2
0
        private static SkiaFrameworkElement LoadTreeInternal(FrameworkElement root)
        {
            SkiaFrameworkElement item = SkiaElementResolver.Default.CreateElementFor(root);

            if (item != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
                {
                    var element = VisualTreeHelper.GetChild(root, i) as FrameworkElement;

                    if (element != null)
                    {
                        var treeItem = LoadTreeInternal(element);

                        if (treeItem != null)
                        {
                            treeItem.Parent = item;
                            item.Children.Add(treeItem);
                        }
                    }
                }

                return(item);
            }

            return(null);
        }
コード例 #3
0
        private List <SkiaFrameworkElement> Flatten(SkiaFrameworkElement element, List <SkiaFrameworkElement> list)
        {
            list.Add(element);

            foreach (var item in element.Children)
            {
                Flatten(item, list);
            }

            return(list);
        }
コード例 #4
0
        /// <summary>
        /// Performs a rendering pass on the specified <see cref="SkiaFrameworkElement"/> and its descendants.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="mode">The mode.</param>
        protected void RenderSingle(SkiaFrameworkElement element, BindingPropertyMode mode)
        {
            SkiaFrameworkElement toRender = element.Parent != null ? element.Parent : element;

            var bounds = toRender.Bounds;

            if (mode == BindingPropertyMode.AffectsLayout)
            {
                toRender.InvalidateBounds();

                if (toRender.Bounds.Contains(bounds))
                {
                    bounds = toRender.Bounds;
                }
                else
                {
                    bounds.Width  += 1;
                    bounds.Height += 1;
                }
            }

            if (bounds.Left < Source.Width && bounds.Top < Source.Height)
            {
                Source.Lock();

                T context = CreateDrawingContext();

                context.BeginDrawing();

                context.ClipRect(bounds, new CornerRadius());
                context.Clear(Colors.Transparent);

                SkiaTree.Root.Invalidate(context, bounds, 1);

                context.EndDrawing();

                if (bounds.Right > Source.Width)
                {
                    bounds.Width = Source.Width - bounds.Left;
                }

                if (bounds.Bottom > Source.Height)
                {
                    bounds.Height = Source.Height - bounds.Top;
                }

                OnRenderCompleted(Source.BackBuffer, (int)Source.Width, (int)Source.Height, (int)Source.Width * 4);

                Source.AddDirtyRect(new Int32Rect((int)Math.Max(bounds.Left, 0), (int)Math.Max(bounds.Top, 0), (int)bounds.Width, (int)bounds.Height));
                Source.Unlock();
            }
        }
コード例 #5
0
        /// <summary>
        /// Generates a new <see cref="BindingEventContainer"/> for the specified Skia element and binding property.
        /// </summary>
        /// <param name="skiaElement">The skia element.</param>
        /// <param name="bindingProperty">The binding property.</param>
        /// <returns></returns>
        public static BindingEventContainer Generate(SkiaFrameworkElement skiaElement, BindingProperty bindingProperty)
        {
            BindingEventContainer container = new BindingEventContainer(skiaElement, bindingProperty);

            Binding binding = new Binding();

            binding.Mode    = BindingMode.OneWay;
            binding.Source  = skiaElement.WpfElement;
            binding.Path    = new PropertyPath(bindingProperty.DependencyProperty);
            binding.IsAsync = true;
            BindingOperations.SetBinding(container, BindingEventContainer.ValueProperty, binding);

            return(container);
        }
コード例 #6
0
        /// <summary>
        /// Invalidates the specified element <see cref="Bounds"/>.
        /// </summary>
        /// <param name="parent">The parent.</param>
        private void InvalidateBounds(SkiaFrameworkElement parent)
        {
            Bounds = GetBounds();
            var bounds = Bounds;

            if (parent != null)
            {
                bounds.Offset(parent.Bounds.Left, parent.Bounds.Top);
                Bounds = bounds;
            }

            foreach (var child in Children)
            {
                child.InvalidateBounds(this);
            }
        }
コード例 #7
0
        /// <summary>
        /// Creates a new instance of a <see cref="SkiaFrameworkElement"/> by looking for a proper registration of the specified <see cref="FrameworkElement"/> type.
        /// When no registration was found, will return a default instance of <see cref="SkiaFrameworkElement"/>.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns></returns>
        public SkiaFrameworkElement CreateElementFor(FrameworkElement element)
        {
            Type skiaType = null;

            if (_binders.TryGetValue(element.GetType(), out skiaType))
            {
                SkiaFrameworkElement skiaElement = Activator.CreateInstance(skiaType) as SkiaFrameworkElement;
                skiaElement.WpfElement = element;
                return(skiaElement);
            }
            else
            {
                SkiaFrameworkElement defaultElement = Activator.CreateInstance(typeof(SkiaFrameworkElement)) as SkiaFrameworkElement;
                defaultElement.WpfElement = element;
                return(defaultElement);
            }
        }
コード例 #8
0
        private SkiaFrameworkElement Find(SkiaFrameworkElement element, Func <SkiaFrameworkElement, bool> predicate)
        {
            if (predicate(element))
            {
                return(element);
            }

            foreach (var item in element.Children)
            {
                var result = Find(item, predicate);
                if (result != null)
                {
                    return(result);
                }
            }

            return(null);
        }
コード例 #9
0
        /// <summary>
        /// Creates a new <see cref="DrawingStyle"/> based on the specified <see cref="SkiaFrameworkElement"/>.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns></returns>
        public static DrawingStyle FromElement(SkiaFrameworkElement element)
        {
            DrawingStyle style = new DrawingStyle();

            style.EdgeMode = RenderOptions.GetEdgeMode(element);
            style.Effect   = element.WpfElement.Effect;

            if (element.Parent != null && element.Parent.WpfElement.RenderTransform != Transform.Identity)
            {
                style.Transform       = element.Parent.WpfElement.RenderTransform;
                style.TransformOrigin = element.Parent.WpfElement.RenderTransformOrigin;
            }
            else
            {
                style.Transform       = element.WpfElement.RenderTransform;
                style.TransformOrigin = element.WpfElement.RenderTransformOrigin;
            }
            return(style);
        }
コード例 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BindingEventContainer"/> class.
 /// </summary>
 /// <param name="skiaElement">The skia element.</param>
 /// <param name="bindingProperty">The binding property.</param>
 public BindingEventContainer(SkiaFrameworkElement skiaElement, BindingProperty bindingProperty)
 {
     SkiaElement     = skiaElement;
     BindingProperty = bindingProperty;
 }
コード例 #11
0
 /// <summary>
 /// Disposes the specified element.
 /// </summary>
 /// <param name="element">The element.</param>
 private void DisposeElement(SkiaFrameworkElement element)
 {
     element.ChildAdded   -= Element_ChildAdded;
     element.ChildRemoved -= Element_ChildRemoved;
 }
コード例 #12
0
 public static bool GetIsInitialized(SkiaFrameworkElement element)
 {
     return((bool)element.GetValue(IsInitializedProperty));
 }
コード例 #13
0
 public static void SetIsInitialized(SkiaFrameworkElement element, bool value)
 {
     element.SetValue(IsInitializedProperty, value);
 }
コード例 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkiaTree"/> class.
 /// </summary>
 /// <param name="root">The root.</param>
 public SkiaTree(SkiaFrameworkElement root)
 {
     Root = root;
 }