From 5773704f2d7fc97b2331ad50850536fb9b5c8d06 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 19 Jan 2016 20:27:55 +0100 Subject: [PATCH] Started updating DevTools to use XAML. --- samples/ControlCatalog/App.paml.cs | 12 ++ samples/ControlCatalog/ControlCatalog.csproj | 9 ++ samples/ControlCatalog/packages.config | 4 + .../Templates/TreeDataTemplate.cs | 9 +- src/Perspex.Base/PriorityValue.cs | 17 ++- .../Generators/TreeItemContainerGenerator.cs | 2 +- src/Perspex.Diagnostics/DevTools.cs | 120 ------------------ src/Perspex.Diagnostics/DevTools.paml | 17 +++ src/Perspex.Diagnostics/DevTools.paml.cs | 52 ++++++++ .../Perspex.Diagnostics.csproj | 27 +++- src/Perspex.Diagnostics/ViewLocator.cs | 2 +- .../ViewModels/DevToolsViewModel.cs | 57 +++++---- .../ViewModels/LogicalTreeViewModel.cs | 34 ----- .../ViewModels/TreeNode.cs | 7 + ...lTreeViewModel.cs => TreePageViewModel.cs} | 13 +- .../Views/LogicalTreeView.cs | 99 --------------- .../Views/{TreePage.cs => TreePage.paml.cs} | 18 ++- .../Views/TreePageView.paml | 24 ++++ .../Views/VisualTreeView.cs | 101 --------------- 19 files changed, 216 insertions(+), 408 deletions(-) create mode 100644 samples/ControlCatalog/packages.config delete mode 100644 src/Perspex.Diagnostics/DevTools.cs create mode 100644 src/Perspex.Diagnostics/DevTools.paml create mode 100644 src/Perspex.Diagnostics/DevTools.paml.cs delete mode 100644 src/Perspex.Diagnostics/ViewModels/LogicalTreeViewModel.cs rename src/Perspex.Diagnostics/ViewModels/{VisualTreeViewModel.cs => TreePageViewModel.cs} (71%) delete mode 100644 src/Perspex.Diagnostics/Views/LogicalTreeView.cs rename src/Perspex.Diagnostics/Views/{TreePage.cs => TreePage.paml.cs} (77%) create mode 100644 src/Perspex.Diagnostics/Views/TreePageView.paml delete mode 100644 src/Perspex.Diagnostics/Views/VisualTreeView.cs diff --git a/samples/ControlCatalog/App.paml.cs b/samples/ControlCatalog/App.paml.cs index b1aa671215..8a49ae20f1 100644 --- a/samples/ControlCatalog/App.paml.cs +++ b/samples/ControlCatalog/App.paml.cs @@ -5,6 +5,7 @@ using Perspex.Controls; using Perspex.Diagnostics; using Perspex.Markup.Xaml; using Perspex.Themes.Default; +using Serilog; namespace ControlCatalog { @@ -14,6 +15,7 @@ namespace ControlCatalog { RegisterServices(); InitializeSubsystems(GetPlatformId()); + InitializeLogging(); Styles = new DefaultTheme(); InitializeComponent(); } @@ -38,6 +40,16 @@ namespace ControlCatalog PerspexXamlLoader.Load(this); } + private void InitializeLogging() + { +#if DEBUG + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Error() + .WriteTo.Trace(outputTemplate: "{Message}") + .CreateLogger(); +#endif + } + private int GetPlatformId() { var args = Environment.GetCommandLineArgs(); diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 1a26286147..d3bf036619 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -36,6 +36,14 @@ + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.dll + True + + + ..\..\packages\Serilog.1.5.9\lib\net45\Serilog.FullNetFx.dll + True + @@ -93,6 +101,7 @@ Designer + diff --git a/samples/ControlCatalog/packages.config b/samples/ControlCatalog/packages.config new file mode 100644 index 0000000000..76c9b4d2a5 --- /dev/null +++ b/samples/ControlCatalog/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Templates/TreeDataTemplate.cs b/src/Markup/Perspex.Markup.Xaml/Templates/TreeDataTemplate.cs index 0ff1ec7a6d..ceabd09bb7 100644 --- a/src/Markup/Perspex.Markup.Xaml/Templates/TreeDataTemplate.cs +++ b/src/Markup/Perspex.Markup.Xaml/Templates/TreeDataTemplate.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Reactive.Linq; +using System.Reflection; using Perspex.Controls; using Perspex.Controls.Templates; using Perspex.Data; @@ -27,10 +28,12 @@ namespace Perspex.Markup.Xaml.Templates { if (DataType == null) { - throw new InvalidOperationException("DataTemplate must have a DataType."); + return true; + } + else + { + return DataType.GetTypeInfo().IsAssignableFrom(data.GetType().GetTypeInfo()); } - - return DataType == data.GetType(); } public IEnumerable ItemsSelector(object item) diff --git a/src/Perspex.Base/PriorityValue.cs b/src/Perspex.Base/PriorityValue.cs index e45eba172f..b68fae1869 100644 --- a/src/Perspex.Base/PriorityValue.cs +++ b/src/Perspex.Base/PriorityValue.cs @@ -224,26 +224,29 @@ namespace Perspex /// The priority level that the value came from. private void UpdateValue(object value, int priority) { - if (TypeUtilities.TryCast(_valueType, value, out value)) + object castValue; + + if (TypeUtilities.TryCast(_valueType, value, out castValue)) { var old = _value; - if (_validate != null && value != PerspexProperty.UnsetValue) + if (_validate != null && castValue != PerspexProperty.UnsetValue) { - value = _validate(value); + castValue = _validate(castValue); } ValuePriority = priority; - _value = value; + _value = castValue; _changed.OnNext(Tuple.Create(old, _value)); } else if (_logger != null) { _logger.Error( - "Binding produced invalid value for {$Type} {$Property}: {$Value}", - _valueType, + "Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})", _name, - value); + _valueType, + value, + value.GetType()); } } diff --git a/src/Perspex.Controls/Generators/TreeItemContainerGenerator.cs b/src/Perspex.Controls/Generators/TreeItemContainerGenerator.cs index e630924a97..046d018321 100644 --- a/src/Perspex.Controls/Generators/TreeItemContainerGenerator.cs +++ b/src/Perspex.Controls/Generators/TreeItemContainerGenerator.cs @@ -77,7 +77,7 @@ namespace Perspex.Controls.Generators result.SetValue(ContentProperty, template.Build(item)); result.SetValue(ItemsProperty, template.ItemsSelector(item)); - result.SetValue(IsExpandedProperty, template.IsExpanded(item)); + //result.SetValue(IsExpandedProperty, template.IsExpanded(item)); if (!(item is IControl)) { diff --git a/src/Perspex.Diagnostics/DevTools.cs b/src/Perspex.Diagnostics/DevTools.cs deleted file mode 100644 index a9364d2566..0000000000 --- a/src/Perspex.Diagnostics/DevTools.cs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) The Perspex Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Reactive.Linq; -using Perspex.Controls; -using Perspex.Diagnostics.ViewModels; -using Perspex.Input; -using Perspex.Themes.Default; -using ReactiveUI; - -namespace Perspex.Diagnostics -{ - public class DevTools : Decorator - { - public static readonly PerspexProperty RootProperty = - PerspexProperty.Register("Root"); - - private readonly DevToolsViewModel _viewModel; - - public DevTools() - { - _viewModel = new DevToolsViewModel(); - this.GetObservable(RootProperty).Subscribe(x => _viewModel.Root = x); - - InitializeComponent(); - } - - public Control Root - { - get { return GetValue(RootProperty); } - set { SetValue(RootProperty, value); } - } - - public static IDisposable Attach(Window window) - { - return window.AddHandler( - KeyDownEvent, - WindowPreviewKeyDown, - Interactivity.RoutingStrategies.Tunnel); - } - - private static void WindowPreviewKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.F12) - { - Window window = new Window - { - Width = 1024, - Height = 512, - Content = new DevTools - { - Root = (Window)sender, - }, - }; - - window.Show(); - } - } - - private void InitializeComponent() - { - DataTemplates.Add(new ViewLocator()); - Styles.Add(new DefaultTheme()); - - Child = new Grid - { - RowDefinitions = new RowDefinitions("*,Auto"), - Children = new Controls.Controls - { - new TabControl - { - Items = new[] - { - new TabItem - { - Header = "Logical Tree", - [!ContentControl.ContentProperty] = _viewModel.WhenAnyValue(x => x.LogicalTree), - }, - new TabItem - { - Header = "Visual Tree", - [!ContentControl.ContentProperty] = _viewModel.WhenAnyValue(x => x.VisualTree), - } - }, - }, - new StackPanel - { - Orientation = Orientation.Horizontal, - Gap = 4, - [Grid.RowProperty] = 1, - Children = new Controls.Controls - { - new TextBlock - { - Text = "Focused: " - }, - new TextBlock - { - [!TextBlock.TextProperty] = _viewModel - .WhenAnyValue(x => x.FocusedControl) - .Select(x => x?.GetType().Name ?? "(null)") - }, - new TextBlock - { - Text = "Pointer Over: " - }, - new TextBlock - { - [!TextBlock.TextProperty] = _viewModel - .WhenAnyValue(x => x.PointerOverElement) - .Select(x => x?.GetType().Name ?? "(null)") - } - } - } - } - }; - } - } -} diff --git a/src/Perspex.Diagnostics/DevTools.paml b/src/Perspex.Diagnostics/DevTools.paml new file mode 100644 index 0000000000..76f58222e1 --- /dev/null +++ b/src/Perspex.Diagnostics/DevTools.paml @@ -0,0 +1,17 @@ + + + + + + + + + + + Focused: + + Pointer Over: + + + + \ No newline at end of file diff --git a/src/Perspex.Diagnostics/DevTools.paml.cs b/src/Perspex.Diagnostics/DevTools.paml.cs new file mode 100644 index 0000000000..8b607a496f --- /dev/null +++ b/src/Perspex.Diagnostics/DevTools.paml.cs @@ -0,0 +1,52 @@ +using System; +using Perspex.Controls; +using Perspex.Controls.Templates; +using Perspex.Diagnostics.ViewModels; +using Perspex.Input; +using Perspex.Interactivity; +using Perspex.Markup.Xaml; +using ReactiveUI; + +namespace Perspex.Diagnostics +{ + public class DevTools : UserControl + { + public DevTools(IControl root) + { + this.InitializeComponent(); + this.DataContext = new DevToolsViewModel(root); + } + + public static IDisposable Attach(Window window) + { + return window.AddHandler( + KeyDownEvent, + WindowPreviewKeyDown, + RoutingStrategies.Tunnel); + } + + private static void WindowPreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.F12) + { + Window window = new Window + { + Width = 1024, + Height = 512, + Content = new DevTools((IControl)sender), + DataTemplates = new DataTemplates + { + new ViewLocator(), + } + }; + + window.Show(); + } + } + + private void InitializeComponent() + { + PerspexXamlLoader.Load(this); + } + } +} diff --git a/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj b/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj index 17db490d9b..e36079a39e 100644 --- a/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj +++ b/src/Perspex.Diagnostics/Perspex.Diagnostics.csproj @@ -40,6 +40,14 @@ + + {3e53a01a-b331-47f3-b828-4a5717e77a24} + Perspex.Markup.Xaml + + + {6417e941-21bc-467b-a771-0de389353ce6} + Perspex.Markup + {D211E587-D8BC-45B9-95A4-F297C8FA5200} Perspex.Animation @@ -86,23 +94,24 @@ Properties\SharedAssemblyInfo.cs - - - + + + TreePageView.paml + + + DevTools.paml + - - - @@ -124,6 +133,12 @@ + + Designer + + + Designer + + + + + + + \ No newline at end of file diff --git a/src/Perspex.Diagnostics/Views/VisualTreeView.cs b/src/Perspex.Diagnostics/Views/VisualTreeView.cs deleted file mode 100644 index d8d6ca03ce..0000000000 --- a/src/Perspex.Diagnostics/Views/VisualTreeView.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) The Perspex Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Reactive.Linq; -using Perspex.Controls; -using Perspex.Controls.Templates; -using Perspex.Diagnostics.ViewModels; -using Perspex.Media; -using ReactiveUI; - -namespace Perspex.Diagnostics.Views -{ - using Controls = Controls.Controls; - - internal class VisualTreeView : TreePage - { - private static readonly PerspexProperty ViewModelProperty = - PerspexProperty.Register("ViewModel"); - - public VisualTreeView() - { - InitializeComponent(); - this.GetObservable(DataContextProperty) - .Subscribe(x => ViewModel = (VisualTreeViewModel)x); - } - - public VisualTreeViewModel ViewModel - { - get { return GetValue(ViewModelProperty); } - private set { SetValue(ViewModelProperty, value); } - } - - private void InitializeComponent() - { - TreeView tree; - - Content = new Grid - { - ColumnDefinitions = new ColumnDefinitions - { - new ColumnDefinition(1, GridUnitType.Star), - new ColumnDefinition(4, GridUnitType.Pixel), - new ColumnDefinition(3, GridUnitType.Star), - }, - Children = new Controls - { - (tree = new TreeView - { - DataTemplates = new DataTemplates - { - new FuncTreeDataTemplate(GetHeader, x => x.Children), - }, - [!ItemsControl.ItemsProperty] = this.WhenAnyValue(x => x.ViewModel.Nodes), - }), - new GridSplitter - { - Width = 4, - Orientation = Orientation.Vertical, - [Grid.ColumnProperty] = 1, - }, - new ContentControl - { - [!ContentProperty] = this.WhenAnyValue(x => x.ViewModel.Details), - [Grid.ColumnProperty] = 2, - } - } - }; - - tree.GetObservable(TreeView.SelectedItemProperty) - .OfType() - .Subscribe(x => ViewModel.SelectedNode = x); - } - - private Control GetHeader(VisualTreeNode node) - { - var result = new StackPanel - { - Orientation = Orientation.Horizontal, - Gap = 8, - Children = new Controls - { - new TextBlock - { - FontStyle = node.IsInTemplate ? FontStyle.Italic : FontStyle.Normal, - Text = node.Type, - }, - new TextBlock - { - [!TextBlock.TextProperty] = node.WhenAnyValue(x => x.Classes), - } - } - }; - - result.PointerEnter += AddAdorner; - result.PointerLeave += RemoveAdorner; - - return result; - } - } -}