Browse Source

Merge branch 'master' into fixes/2660-treeview-selection

pull/2702/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
4eab39fa8a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      src/Avalonia.Diagnostics/DevTools.xaml
  2. 8
      src/Avalonia.Diagnostics/DevTools.xaml.cs
  3. 2
      src/Avalonia.Diagnostics/ViewLocator.cs
  4. 65
      src/Avalonia.Diagnostics/ViewModels/DevToolsViewModel.cs
  5. 13
      src/Avalonia.Diagnostics/ViewModels/EventsViewModel.cs
  6. 16
      src/Avalonia.Diagnostics/ViewModels/IDevToolViewModel.cs
  7. 7
      src/Avalonia.Diagnostics/ViewModels/TreePageViewModel.cs
  8. 16
      src/Avalonia.Diagnostics/Views/ControlDetailsView.cs
  9. 5
      src/Avalonia.Diagnostics/Views/PropertyChangedExtensions.cs
  10. 3
      src/Avalonia.Diagnostics/Views/TreePage.xaml.cs

37
src/Avalonia.Diagnostics/DevTools.xaml

@ -1,23 +1,24 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Avalonia.Diagnostics.DevTools">
<Grid RowDefinitions="Auto,*,Auto">
<TabStrip SelectedIndex="{Binding SelectedTab, Mode=TwoWay}">
<TabStripItem Content="Logical Tree"/>
<TabStripItem Content="Visual Tree"/>
<TabStripItem Content="Events"/>
</TabStrip>
<Grid RowDefinitions="*,Auto" Margin="4">
<ContentControl Content="{Binding Content}" Grid.Row="1"/>
<StackPanel Spacing="4" Orientation="Horizontal" Grid.Row="2">
<TextBlock>Hold Ctrl+Shift over a control to inspect.</TextBlock>
<Separator Width="8"/>
<TextBlock>Focused:</TextBlock>
<TextBlock Text="{Binding FocusedControl}"/>
<Separator Width="8"/>
<TextBlock>Pointer Over:</TextBlock>
<TextBlock Text="{Binding PointerOverElement}"/>
</StackPanel>
</Grid>
<TabControl Grid.Row="0" Items="{Binding Tools}" SelectedItem="{Binding SelectedTool}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
<StackPanel Grid.Row="1" Spacing="4" Orientation="Horizontal">
<TextBlock>Hold Ctrl+Shift over a control to inspect.</TextBlock>
<Separator Width="8" />
<TextBlock>Focused:</TextBlock>
<TextBlock Text="{Binding FocusedControl}" />
<Separator Width="8" />
<TextBlock>Pointer Over:</TextBlock>
<TextBlock Text="{Binding PointerOverElement}" />
</StackPanel>
</Grid>
</UserControl>

8
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<ViewModelBase>(),
}
},
Title = "Avalonia DevTools"
};
devToolsWindow.Closed += devTools.DevToolsClosed;

2
src/Avalonia.Diagnostics/ViewLocator.cs

@ -31,4 +31,4 @@ namespace Avalonia.Diagnostics
return data is TViewModel;
}
}
}
}

65
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<IDevToolViewModel>
{
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<IDevToolViewModel> 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);
}

13
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<FiredEvent> RecordedEvents { get; } = new ObservableCollection<FiredEvent>();
@ -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)

16
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
{
/// <summary>
/// View model interface for tool showing up in DevTools
/// </summary>
public interface IDevToolViewModel
{
/// <summary>
/// Name of a tool.
/// </summary>
string Name { get; }
}
}

7
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

16
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<Control>())
{
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<string>(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<object>(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<string>((nameof(property.Priority))).ToBinding(),
};

5
src/Avalonia.Diagnostics/Views/PropertyChangedExtenions.cs → 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;

3
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;

Loading…
Cancel
Save