Update peer handling
This commit is contained in:
Родитель
d4a6183103
Коммит
2c63ccdd39
|
@ -4,7 +4,7 @@ namespace Microsoft.StandardUI.VisualEnvironment.WpfNative
|
|||
{
|
||||
public class WpfNativeVisualEnvironment : IVisualEnvironment
|
||||
{
|
||||
public IVisualizer CreateVisualizer(in Rect cullingRect) => new WpfNativeVisualizer(cullingRect);
|
||||
public IDrawingContext CreateDrawingContext(in Rect cullingRect) => new WpfNativeVisualizer(cullingRect);
|
||||
|
||||
public void RenderToBuffer(IVisual visual, IntPtr pixels, int width, int height, int rowBytes)
|
||||
{
|
||||
|
|
|
@ -1,52 +1,60 @@
|
|||
using Microsoft.StandardUI.Controls;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Microsoft.StandardUI.Wpf
|
||||
{
|
||||
public class StandardUIControlWpf : System.Windows.Controls.Control, IStandardUIControlEnvironmentPeer
|
||||
public class StandardControl<TControl> : System.Windows.Controls.Control, IControl, IStandardControlEnvironmentPeer where TControl : IControl
|
||||
{
|
||||
private StandardUIControl _standardUIControl;
|
||||
private ControlTemplateWpf? _controlTemplateWpf;
|
||||
private StandardControlImplementation<TControl> _implementation;
|
||||
private StandardUIFrameworkElement? _buildContent;
|
||||
|
||||
public StandardUIControlWpf(StandardUIControl standardUIControl)
|
||||
protected void InitImplementation(StandardControlImplementation<TControl> implementation)
|
||||
{
|
||||
_standardUIControl = standardUIControl;
|
||||
_implementation = implementation;
|
||||
|
||||
_buildContent = (StandardUIFrameworkElement?)implementation.Build();
|
||||
|
||||
Width = standardUIControl.Width;
|
||||
MinWidth = standardUIControl.MinWidth;
|
||||
MaxWidth = standardUIControl.MaxWidth;
|
||||
Height = standardUIControl.Height;
|
||||
MinHeight = standardUIControl.MinHeight;
|
||||
MaxHeight = standardUIControl.MaxHeight;
|
||||
if (_buildContent != null)
|
||||
{
|
||||
AddVisualChild(_buildContent);
|
||||
AddLogicalChild(_buildContent);
|
||||
}
|
||||
}
|
||||
|
||||
void IUIElement.Measure(Size availableSize)
|
||||
{
|
||||
Measure(availableSize.ToWpfSize());
|
||||
}
|
||||
|
||||
void IUIElement.Arrange(Rect finalRect)
|
||||
{
|
||||
Arrange(finalRect.ToWpfRect());
|
||||
}
|
||||
|
||||
Size IUIElement.DesiredSize => SizeExtensions.FromWpfSize(DesiredSize);
|
||||
|
||||
IUIPropertyObject? IControl.GetTemplateChild(string childName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
|
||||
{
|
||||
_standardUIControl.Measure(new Size(constraint.Width, constraint.Height));
|
||||
return _standardUIControl.DesiredSize.ToWpfSize();
|
||||
_implementation.Measure(new Size(constraint.Width, constraint.Height));
|
||||
return _implementation.DesiredSize.ToWpfSize();
|
||||
}
|
||||
|
||||
protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
|
||||
{
|
||||
_standardUIControl.Arrange(new Rect(0, 0, arrangeSize.Width, arrangeSize.Height));
|
||||
_implementation.Arrange(new Rect(0, 0, arrangeSize.Width, arrangeSize.Height));
|
||||
return arrangeSize;
|
||||
}
|
||||
|
||||
/*
|
||||
protected override int VisualChildrenCount => _standardUIControl.Content != null ? 1 : 0;
|
||||
double IUIElement.ActualX => throw new System.NotImplementedException();
|
||||
|
||||
protected override Visual GetVisualChild(int index)
|
||||
{
|
||||
IUIElement? content = _standardUIControl.Content;
|
||||
|
||||
if (content == null)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Control has no content");
|
||||
if (index != 0)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Index out of range; control only has a single visual child.");
|
||||
|
||||
return (Visual)content;
|
||||
}
|
||||
*/
|
||||
double IUIElement.ActualY => throw new System.NotImplementedException();
|
||||
|
||||
public object GetValue(IUIProperty dp)
|
||||
{
|
||||
|
@ -66,7 +74,22 @@ namespace Microsoft.StandardUI.Wpf
|
|||
SetValue(wpfDependencyProperty, value);
|
||||
}
|
||||
|
||||
IControlTemplate? IStandardUIControlEnvironmentPeer.Template
|
||||
protected override int VisualChildrenCount => _buildContent != null ? 1 : 0;
|
||||
|
||||
IUIElement? IStandardControlEnvironmentPeer.BuildContent => _buildContent;
|
||||
|
||||
protected override Visual GetVisualChild(int index)
|
||||
{
|
||||
if (_buildContent == null)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Control returned null from build");
|
||||
if (index != 0)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Index out of range; control only has a single visual child.");
|
||||
|
||||
return _buildContent;
|
||||
}
|
||||
|
||||
#if false
|
||||
IControlTemplate? IControl.Template
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -90,7 +113,9 @@ namespace Microsoft.StandardUI.Wpf
|
|||
_controlTemplateWpf = controlTemplateWpf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
IUIPropertyObject? IStandardUIControlEnvironmentPeer.GetTemplateChild(string childName)
|
||||
{
|
||||
System.Windows.DependencyObject? child = this.GetTemplateChild(childName);
|
||||
|
@ -100,5 +125,6 @@ namespace Microsoft.StandardUI.Wpf
|
|||
// TODO:Finish this
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -43,10 +43,6 @@ namespace Microsoft.StandardUI.Wpf
|
|||
public IPolyQuadraticBezierSegment CreatePolyQuadraticBezierSegment(Points points) => throw new NotImplementedException();
|
||||
public IQuadraticBezierSegment CreateQuadraticBezierSegment(in Point point1, in Point point2) => throw new NotImplementedException();
|
||||
|
||||
/*** Environment peers ***/
|
||||
|
||||
public IStandardUIControlEnvironmentPeer CreateStandardUIControlEnvironmentPeer(StandardUIControl standardUIControl) => new StandardUIControlWpf(standardUIControl);
|
||||
|
||||
/*** Infrastructure objects ***/
|
||||
|
||||
public IUIPropertyMetadata CreatePropertyMetadata(object defaultValue) => throw new NotImplementedException();
|
||||
|
|
|
@ -11,12 +11,12 @@ namespace Microsoft.StandardUI.Wpf
|
|||
{
|
||||
StandardUIFrameworkElementHelper _helper = new StandardUIFrameworkElementHelper();
|
||||
|
||||
public void Measure(Size availableSize)
|
||||
void IUIElement.Measure(Size availableSize)
|
||||
{
|
||||
Measure(availableSize.ToWpfSize());
|
||||
}
|
||||
|
||||
public void Arrange(Rect finalRect)
|
||||
void IUIElement.Arrange(Rect finalRect)
|
||||
{
|
||||
Arrange(finalRect.ToWpfRect());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace Microsoft.StandardUI.Wpf
|
|||
Rect cullingRect = new Rect(0, 0, 200, 200);
|
||||
|
||||
IVisual visual;
|
||||
using (IVisualizer visualizer = visualEnvironment.CreateVisualizer(cullingRect)) {
|
||||
using (IDrawingContext visualizer = visualEnvironment.CreateDrawingContext(cullingRect)) {
|
||||
OnVisualize(visualizer);
|
||||
visual = visualizer.End();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace Microsoft.StandardUI.Wpf
|
|||
InvalidateVisual();
|
||||
}
|
||||
|
||||
public virtual void OnVisualize(IVisualizer visualizer)
|
||||
public virtual void OnVisualize(IDrawingContext visualizer)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
using Microsoft.StandardUI.Controls;
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Microsoft.StandardUI.Wpf
|
||||
{
|
||||
public class StandardUIUserControlWpf : StandardUIControlWpf
|
||||
{
|
||||
private StandardUIUserControl _userControl;
|
||||
|
||||
public StandardUIUserControlWpf(StandardUIUserControl userControl) : base(userControl)
|
||||
{
|
||||
_userControl = userControl;
|
||||
|
||||
Width = userControl.Width;
|
||||
MinWidth = userControl.MinWidth;
|
||||
MaxWidth = userControl.MaxWidth;
|
||||
Height = userControl.Height;
|
||||
MinHeight = userControl.MinHeight;
|
||||
MaxHeight = userControl.MaxHeight;
|
||||
|
||||
var content = (System.Windows.UIElement?) userControl.Content;
|
||||
if (content != null)
|
||||
AddLogicalChild(content);
|
||||
}
|
||||
|
||||
protected override int VisualChildrenCount => _userControl.Content != null ? 1 : 0;
|
||||
|
||||
protected override Visual GetVisualChild(int index)
|
||||
{
|
||||
IUIElement? content = _userControl.Content;
|
||||
|
||||
if (content == null)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Control has no content");
|
||||
if (index != 0)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Index out of range; control only has a single visual child.");
|
||||
|
||||
return (Visual)content;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Microsoft.StandardUI.Controls
|
||||
{
|
||||
public interface IStandardControlEnvironmentPeer : IDependencyObjectEnvironmentPeer
|
||||
{
|
||||
public IUIElement? BuildContent { get; }
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
namespace Microsoft.StandardUI.Controls
|
||||
{
|
||||
public interface IStandardUIControlEnvironmentPeer : IDependencyObjectEnvironmentPeer
|
||||
{
|
||||
double Width { get; set; }
|
||||
public double MinWidth { get; set; }
|
||||
public double MaxWidth { get; set; }
|
||||
|
||||
double Height { get; set; }
|
||||
public double MinHeight { get; set; }
|
||||
public double MaxHeight { get; set; }
|
||||
|
||||
public IControlTemplate? Template { get; set; }
|
||||
|
||||
public IUIPropertyObject? GetTemplateChild(string childName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.StandardUI.Controls
|
||||
{
|
||||
public abstract class StandardControlImplementation<TControl> where TControl : IControl
|
||||
{
|
||||
public TControl Control { get; }
|
||||
|
||||
public StandardControlImplementation(TControl control)
|
||||
{
|
||||
Control = control;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the contents of the control.
|
||||
/// </summary>
|
||||
/// <returns>control contents, or null if all content is drawn via Render</returns>
|
||||
public virtual IUIElement? Build() => null;
|
||||
|
||||
/// <summary>
|
||||
/// This method can be overridden to add further graphical elements (not previously defined in a logical tree) to a control.
|
||||
/// The drawing instructions here aren't displayed immediately; instead they captured in an IVisual, shown later as part
|
||||
/// of rendering the control.
|
||||
///
|
||||
/// There are two basic ways to create output for a control - create children for it (including shape primitives)
|
||||
/// or create an IVisual by drawing to the IDrawingContext here. You can also combine approaches. In general, creating
|
||||
/// children is more flexible, as those children can get input events and be replaced via templates. Each child will
|
||||
/// also show up in UI hierarchy inspector tooling (like the Live Visual Tree in Visual Studio) as a separate element.
|
||||
/// On the other hand, drawing to the IDrawingContext is lighter weight - all drawing instructions are combined into a
|
||||
/// single IVisual, which in some cases is even stored on the GPU.
|
||||
/// </summary>
|
||||
/// <param name="drawingContext">drawing context that should draw to</param>
|
||||
public virtual void Render(IDrawingContext drawingContext) { }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the named element in the instantiated ControlTemplate visual tree.
|
||||
/// </summary>
|
||||
/// <param name="childName">The name of the element to find.</param>
|
||||
/// <returns>The named element from the template, if the element is found. Can
|
||||
/// return null if no element with name childName was found in the template.</returns>
|
||||
protected IUIPropertyObject GetTemplateChild(string childName)
|
||||
{
|
||||
// TODO: Finish this
|
||||
return null;
|
||||
}
|
||||
|
||||
public Size DesiredSize { get; private set; }
|
||||
|
||||
public void Measure(Size availableSize)
|
||||
{
|
||||
var desiredSize = MeasureOverride(availableSize);
|
||||
|
||||
//enforce that MeasureCore can not return PositiveInfinity size even if given Infinte availabel size.
|
||||
//Note: NegativeInfinity can not be returned by definition of Size structure.
|
||||
if (double.IsPositiveInfinity(desiredSize.Width) || double.IsPositiveInfinity(desiredSize.Height))
|
||||
throw new InvalidOperationException($"Layout measurement override of element '{GetType().FullName}' should not return PositiveInfinity as its DesiredSize, even if Infinity is passed in as available size.");
|
||||
|
||||
//enforce that MeasureCore cannot return NaN size.
|
||||
if (double.IsNaN(desiredSize.Width) || double.IsNaN(desiredSize.Height))
|
||||
throw new InvalidOperationException($"Layout measurement override of element '{GetType().FullName}' should not return NaN values as its DesiredSize.");
|
||||
|
||||
DesiredSize = desiredSize;
|
||||
}
|
||||
|
||||
public void Arrange(Rect finalRect)
|
||||
{
|
||||
ArrangeOverride(new Size(finalRect.Width, finalRect.Height));
|
||||
}
|
||||
|
||||
protected virtual Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
IUIElement? buildContent = EnvironmentPeer.BuildContent;
|
||||
|
||||
// By default, return the size of the content
|
||||
if (buildContent != null)
|
||||
{
|
||||
buildContent.Measure(availableSize);
|
||||
return buildContent.DesiredSize;
|
||||
}
|
||||
|
||||
return new Size(0.0, 0.0);
|
||||
}
|
||||
|
||||
protected virtual Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
IUIElement? buildContent = EnvironmentPeer.BuildContent;
|
||||
|
||||
// By default, give all the space to the content
|
||||
if (buildContent != null)
|
||||
{
|
||||
Rect finalRect = new Rect(0, 0, finalSize.Width, finalSize.Height);
|
||||
buildContent.Arrange(finalRect);
|
||||
}
|
||||
|
||||
return finalSize;
|
||||
}
|
||||
|
||||
private IStandardControlEnvironmentPeer EnvironmentPeer => (IStandardControlEnvironmentPeer)Control;
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
using System;
|
||||
using static Microsoft.StandardUI.FactoryStatics;
|
||||
|
||||
namespace Microsoft.StandardUI.Controls
|
||||
{
|
||||
public abstract class StandardUIControl : IUIElement
|
||||
{
|
||||
IStandardUIControlEnvironmentPeer _peer;
|
||||
|
||||
public StandardUIControl(IStandardUIControlEnvironmentPeer? peer = null)
|
||||
{
|
||||
if (peer == null)
|
||||
peer = StandardUIControlEnvironmentPeer(this);
|
||||
_peer = peer;
|
||||
}
|
||||
|
||||
public double Width
|
||||
{
|
||||
get => _peer.Width;
|
||||
set => _peer.Height = value;
|
||||
}
|
||||
|
||||
public double MinWidth
|
||||
{
|
||||
get => _peer.MinWidth;
|
||||
set => _peer.MinWidth = value;
|
||||
}
|
||||
|
||||
public double MaxWidth
|
||||
{
|
||||
get => _peer.MaxWidth;
|
||||
set => _peer.MaxWidth = value;
|
||||
}
|
||||
|
||||
public double Height
|
||||
{
|
||||
get => _peer.Height;
|
||||
set => _peer.Height = value;
|
||||
}
|
||||
|
||||
public double MinHeight
|
||||
{
|
||||
get => _peer.MinHeight;
|
||||
set => _peer.MinHeight = value;
|
||||
}
|
||||
|
||||
public double MaxHeight
|
||||
{
|
||||
get => _peer.MaxHeight;
|
||||
set => _peer.MaxHeight = value;
|
||||
}
|
||||
|
||||
public IControlTemplate Template
|
||||
{
|
||||
get => _peer.Template;
|
||||
set => _peer.Template = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the named element in the instantiated ControlTemplate visual tree.
|
||||
/// </summary>
|
||||
/// <param name="childName">The name of the element to find.</param>
|
||||
/// <returns>The named element from the template, if the element is found. Can
|
||||
/// return null if no element with name childName was found in the template.</returns>
|
||||
protected IUIPropertyObject GetTemplateChild(string childName)
|
||||
{
|
||||
// TODO: Finish this
|
||||
return null;
|
||||
}
|
||||
|
||||
public Size DesiredSize { get; private set; }
|
||||
|
||||
public double ActualX => throw new NotImplementedException();
|
||||
|
||||
public double ActualY => throw new NotImplementedException();
|
||||
|
||||
public double ActualWidth => throw new NotImplementedException();
|
||||
|
||||
public double ActualHeight => throw new NotImplementedException();
|
||||
|
||||
public void Measure(Size availableSize)
|
||||
{
|
||||
var desiredSize = MeasureOverride(availableSize);
|
||||
|
||||
//enforce that MeasureCore can not return PositiveInfinity size even if given Infinte availabel size.
|
||||
//Note: NegativeInfinity can not be returned by definition of Size structure.
|
||||
if (double.IsPositiveInfinity(desiredSize.Width) || double.IsPositiveInfinity(desiredSize.Height))
|
||||
throw new InvalidOperationException($"Layout measurement override of element '{GetType().FullName}' should not return PositiveInfinity as its DesiredSize, even if Infinity is passed in as available size.");
|
||||
|
||||
//enforce that MeasureCore cannot return NaN size.
|
||||
if (double.IsNaN(desiredSize.Width) || double.IsNaN(desiredSize.Height))
|
||||
throw new InvalidOperationException($"Layout measurement override of element '{GetType().FullName}' should not return NaN values as its DesiredSize.");
|
||||
|
||||
DesiredSize = desiredSize;
|
||||
}
|
||||
|
||||
public void Arrange(Rect finalRect)
|
||||
{
|
||||
ArrangeOverride(new Size(finalRect.Width, finalRect.Height));
|
||||
}
|
||||
|
||||
protected abstract Size MeasureOverride(Size availableSize);
|
||||
protected abstract Size ArrangeOverride(Size finalSize);
|
||||
|
||||
public object GetValue(IUIProperty dp) => _peer.GetValue(dp);
|
||||
public object ReadLocalValue(IUIProperty dp) => _peer.ReadLocalValue(dp);
|
||||
public void SetValue(IUIProperty dp, object value) => _peer.SetValue(dp, value);
|
||||
|
||||
/// <summary>
|
||||
/// This method can be overridden to add further graphical elements (not previously defined in a logical tree) to a drawn element.
|
||||
/// It's similar to the OnRender method in WPF.
|
||||
/// </summary>
|
||||
/// <param name="visualizer">visualizer that should draw to</param>
|
||||
public virtual void OnVisualize(IVisualizer visualizer) { }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
namespace Microsoft.StandardUI.Controls
|
||||
{
|
||||
public class StandardUIUserControl : StandardUIControl
|
||||
public class StandardUserControlImplementation<TControl> : StandardControlImplementation<TControl> where TControl : IControl
|
||||
{
|
||||
public StandardUserControlImplementation(TControl control) : base(control)
|
||||
{
|
||||
}
|
||||
|
||||
public IUIElement? Content { get; set; }
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
|
@ -30,9 +30,6 @@ namespace Microsoft.StandardUI
|
|||
|
||||
/*** Environment peers ***/
|
||||
|
||||
public static IStandardUIControlEnvironmentPeer StandardUIControlEnvironmentPeer(StandardUIControl standardUIControl) =>
|
||||
Factory.CreateStandardUIControlEnvironmentPeer(standardUIControl);
|
||||
|
||||
/*** Infrastructure objects ***/
|
||||
|
||||
public static IUIPropertyMetadata UIPropertyMetdata(object defaultValue) => Factory.CreatePropertyMetadata(defaultValue);
|
||||
|
|
|
@ -42,10 +42,6 @@ namespace Microsoft.StandardUI
|
|||
IPathGeometry CreatePathGeometry(ITransform? transform, IEnumerable<IPathFigure> figures, FillRule fillRule);
|
||||
IPathFigure CreatePathFigure(IEnumerable<IPathSegment> segments, Point startPoint, bool isClosed, bool isFilled);
|
||||
|
||||
/*** Environment peers ***/
|
||||
|
||||
IStandardUIControlEnvironmentPeer CreateStandardUIControlEnvironmentPeer(StandardUIControl standardUIControl);
|
||||
|
||||
/*** Infrastructure objects ***/
|
||||
|
||||
IUIPropertyMetadata CreatePropertyMetadata(object defaultValue);
|
||||
|
|
|
@ -44,11 +44,6 @@ namespace Microsoft.StandardUI
|
|||
public IPathGeometry CreatePathGeometry(ITransform? transform, IEnumerable<IPathFigure> figures, FillRule fillRule) => throw CreateInitNotCalledException();
|
||||
public IPathFigure CreatePathFigure(IEnumerable<IPathSegment> segments, Point startPoint, bool isClosed, bool isFilled) => throw CreateInitNotCalledException();
|
||||
|
||||
/*** Environment peers ***/
|
||||
|
||||
public IStandardUIControlEnvironmentPeer CreateStandardUIControlEnvironmentPeer(StandardUIControl standardUIControl) =>
|
||||
throw CreateInitNotCalledException();
|
||||
|
||||
/*** Infrastructure objects ***/
|
||||
|
||||
public IUIPropertyMetadata CreatePropertyMetadata(object defaultValue) => throw CreateInitNotCalledException();
|
||||
|
|
Загрузка…
Ссылка в новой задаче