diff --git a/src/Avalonia.Diagnostics/DevTools.xaml b/src/Avalonia.Diagnostics/DevTools.xaml index 0f55d42e33..a538516c1a 100644 --- a/src/Avalonia.Diagnostics/DevTools.xaml +++ b/src/Avalonia.Diagnostics/DevTools.xaml @@ -1,23 +1,24 @@ - - - - - - + - - - - Hold Ctrl+Shift over a control to inspect. - - Focused: - - - Pointer Over: - - - + + + + + + + + + + Hold Ctrl+Shift over a control to inspect. + + Focused: + + + Pointer Over: + + + diff --git a/src/Avalonia.Diagnostics/DevTools.xaml.cs b/src/Avalonia.Diagnostics/DevTools.xaml.cs index e0bacf326b..ccb6151ada 100644 --- a/src/Avalonia.Diagnostics/DevTools.xaml.cs +++ b/src/Avalonia.Diagnostics/DevTools.xaml.cs @@ -1,10 +1,13 @@ +// Copyright (c) The Avalonia 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.Collections.Generic; using System.Linq; +using System.Reactive.Disposables; using System.Reactive.Linq; using Avalonia.Controls; using Avalonia.Controls.Primitives; -using Avalonia.Controls.Templates; using Avalonia.Diagnostics.ViewModels; using Avalonia.Input; using Avalonia.Input.Raw; @@ -82,7 +85,8 @@ namespace Avalonia.Diagnostics DataTemplates = { new ViewLocator(), - } + }, + Title = "Avalonia DevTools" }; devToolsWindow.Closed += devTools.DevToolsClosed; diff --git a/src/Avalonia.Diagnostics/ViewLocator.cs b/src/Avalonia.Diagnostics/ViewLocator.cs index b107338aec..cda511909a 100644 --- a/src/Avalonia.Diagnostics/ViewLocator.cs +++ b/src/Avalonia.Diagnostics/ViewLocator.cs @@ -31,4 +31,4 @@ namespace Avalonia.Diagnostics return data is TViewModel; } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs index c6d3f02e8b..bc80ab0550 100644 --- a/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs +++ b/src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs @@ -2,7 +2,9 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using System.Reactive.Linq; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using Avalonia.Controls; using Avalonia.Input; @@ -10,21 +12,23 @@ namespace Avalonia.Diagnostics.ViewModels { internal class DevToolsViewModel : ViewModelBase { - private ViewModelBase _content; - private int _selectedTab; - private TreePageViewModel _logicalTree; - private TreePageViewModel _visualTree; - private EventsViewModel _eventsView; + private IDevToolViewModel _selectedTool; private string _focusedControl; private string _pointerOverElement; public DevToolsViewModel(IControl root) { - _logicalTree = new TreePageViewModel(LogicalTreeNode.Create(root)); - _visualTree = new TreePageViewModel(VisualTreeNode.Create(root)); - _eventsView = new EventsViewModel(root); + Tools = new ObservableCollection + { + new TreePageViewModel(LogicalTreeNode.Create(root), "Logical Tree"), + new TreePageViewModel(VisualTreeNode.Create(root), "Visual Tree"), + new EventsViewModel(root) + }; + + SelectedTool = Tools.First(); UpdateFocusedControl(); + KeyboardDevice.Instance.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(KeyboardDevice.Instance.FocusedElement)) @@ -33,58 +37,33 @@ namespace Avalonia.Diagnostics.ViewModels } }; - SelectedTab = 0; root.GetObservable(TopLevel.PointerOverElementProperty) .Subscribe(x => PointerOverElement = x?.GetType().Name); } - public ViewModelBase Content + public IDevToolViewModel SelectedTool { - get { return _content; } - private set { RaiseAndSetIfChanged(ref _content, value); } + get => _selectedTool; + set => RaiseAndSetIfChanged(ref _selectedTool, value); } - public int SelectedTab - { - get { return _selectedTab; } - set - { - _selectedTab = value; - - switch (value) - { - case 0: - Content = _logicalTree; - break; - case 1: - Content = _visualTree; - break; - case 2: - Content = _eventsView; - break; - } - - RaisePropertyChanged(); - } - } + public ObservableCollection Tools { get; } public string FocusedControl { - get { return _focusedControl; } - private set { RaiseAndSetIfChanged(ref _focusedControl, value); } + get => _focusedControl; + private set => RaiseAndSetIfChanged(ref _focusedControl, value); } public string PointerOverElement { - get { return _pointerOverElement; } - private set { RaiseAndSetIfChanged(ref _pointerOverElement, value); } + get => _pointerOverElement; + private set => RaiseAndSetIfChanged(ref _pointerOverElement, value); } public void SelectControl(IControl control) { - var tree = Content as TreePageViewModel; - - if (tree != null) + if (SelectedTool is TreePageViewModel tree) { tree.SelectControl(control); } diff --git a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs index a23677afc8..1c868148ce 100644 --- a/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs +++ b/src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs @@ -5,8 +5,6 @@ using System; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; -using System.Windows.Input; - using Avalonia.Controls; using Avalonia.Data.Converters; using Avalonia.Interactivity; @@ -14,21 +12,24 @@ using Avalonia.Media; namespace Avalonia.Diagnostics.ViewModels { - internal class EventsViewModel : ViewModelBase + internal class EventsViewModel : ViewModelBase, IDevToolViewModel { private readonly IControl _root; private FiredEvent _selectedEvent; public EventsViewModel(IControl root) { - this._root = root; - this.Nodes = RoutedEventRegistry.Instance.GetAllRegistered() + _root = root; + + Nodes = RoutedEventRegistry.Instance.GetAllRegistered() .GroupBy(e => e.OwnerType) .OrderBy(e => e.Key.Name) .Select(g => new EventOwnerTreeNode(g.Key, g, this)) .ToArray(); } + public string Name => "Events"; + public EventTreeNodeBase[] Nodes { get; } public ObservableCollection RecordedEvents { get; } = new ObservableCollection(); @@ -49,7 +50,7 @@ namespace Avalonia.Diagnostics.ViewModels { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - return (bool)value ? Brushes.LightGreen : Brushes.Transparent; + return (bool)value ? Brushes.Green : Brushes.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs new file mode 100644 index 0000000000..0434230a63 --- /dev/null +++ b/src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs @@ -0,0 +1,16 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Diagnostics.ViewModels +{ + /// + /// View model interface for tool showing up in DevTools + /// + public interface IDevToolViewModel + { + /// + /// Name of a tool. + /// + string Name { get; } + } +} diff --git a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs index dba44c5d0c..6b294c98bd 100644 --- a/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs +++ b/src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs @@ -6,16 +6,19 @@ using Avalonia.VisualTree; namespace Avalonia.Diagnostics.ViewModels { - internal class TreePageViewModel : ViewModelBase + internal class TreePageViewModel : ViewModelBase, IDevToolViewModel { private TreeNode _selected; private ControlDetailsViewModel _details; - public TreePageViewModel(TreeNode[] nodes) + public TreePageViewModel(TreeNode[] nodes, string name) { Nodes = nodes; + Name = name; } + public string Name { get; } + public TreeNode[] Nodes { get; protected set; } public TreeNode SelectedNode diff --git a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs b/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs index 381b2e04b4..868bc774bb 100644 --- a/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs +++ b/src/Avalonia.Diagnostics/Views/ControlDetailsView.cs @@ -7,7 +7,6 @@ using System.Reactive.Linq; using Avalonia.Controls; using Avalonia.Diagnostics.ViewModels; using Avalonia.Media; -using Avalonia.Styling; namespace Avalonia.Diagnostics.Views { @@ -42,16 +41,6 @@ namespace Avalonia.Diagnostics.Views { Content = _grid = new SimpleGrid { - Styles = - { - new Style(x => x.Is()) - { - Setters = new[] - { - new Setter(MarginProperty, new Thickness(2)), - } - }, - }, [GridRepeater.TemplateProperty] = pt, } }; @@ -61,8 +50,11 @@ namespace Avalonia.Diagnostics.Views { var property = (PropertyDetails)i; + var margin = new Thickness(2); + yield return new TextBlock { + Margin = margin, Text = property.Name, TextWrapping = TextWrapping.NoWrap, [!ToolTip.TipProperty] = property.GetObservable(nameof(property.Diagnostic)).ToBinding(), @@ -70,6 +62,7 @@ namespace Avalonia.Diagnostics.Views yield return new TextBlock { + Margin = margin, TextWrapping = TextWrapping.NoWrap, [!TextBlock.TextProperty] = property.GetObservable(nameof(property.Value)) .Select(v => v?.ToString()) @@ -78,6 +71,7 @@ namespace Avalonia.Diagnostics.Views yield return new TextBlock { + Margin = margin, TextWrapping = TextWrapping.NoWrap, [!TextBlock.TextProperty] = property.GetObservable((nameof(property.Priority))).ToBinding(), }; diff --git a/src/Avalonia.Diagnostics/Views/PropertyChangedExtenions.cs b/src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs similarity index 85% rename from src/Avalonia.Diagnostics/Views/PropertyChangedExtenions.cs rename to src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs index 2d833763a6..0bd08929ad 100644 --- a/src/Avalonia.Diagnostics/Views/PropertyChangedExtenions.cs +++ b/src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) The Avalonia 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.ComponentModel; using System.Reactive.Linq; using System.Reflection; diff --git a/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs b/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs index d445f1cd70..88cbb03c34 100644 --- a/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs +++ b/src/Avalonia.Diagnostics/Views/TreePage.xaml.cs @@ -1,3 +1,6 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + using Avalonia.Controls; using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives;