committed by
GitHub
69 changed files with 1167 additions and 206 deletions
@ -0,0 +1,47 @@ |
|||||
|
namespace Avalonia.Diagnostics.Behaviors |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// See discussion https://github.com/AvaloniaUI/Avalonia/discussions/6773
|
||||
|
/// </summary>
|
||||
|
static class ColumnDefinition |
||||
|
{ |
||||
|
private readonly static Avalonia.Controls.GridLength ZeroWidth = |
||||
|
new Avalonia.Controls.GridLength(0, Avalonia.Controls.GridUnitType.Pixel); |
||||
|
|
||||
|
private readonly static AttachedProperty<Avalonia.Controls.GridLength?> LastWidthProperty = |
||||
|
AvaloniaProperty.RegisterAttached<Avalonia.Controls.ColumnDefinition, Avalonia.Controls.GridLength?>("LastWidth" |
||||
|
, typeof(ColumnDefinition) |
||||
|
, default); |
||||
|
|
||||
|
public readonly static AttachedProperty<bool> IsVisibleProperty = |
||||
|
AvaloniaProperty.RegisterAttached<Avalonia.Controls.ColumnDefinition, bool>("IsVisible" |
||||
|
, typeof(ColumnDefinition) |
||||
|
, true |
||||
|
, coerce: (element, visibility) => |
||||
|
{ |
||||
|
|
||||
|
var lastWidth = element.GetValue(LastWidthProperty); |
||||
|
if (visibility == true && lastWidth is { }) |
||||
|
{ |
||||
|
element.SetValue(Avalonia.Controls.ColumnDefinition.WidthProperty, lastWidth); |
||||
|
} |
||||
|
else if (visibility == false) |
||||
|
{ |
||||
|
element.SetValue(LastWidthProperty, element.GetValue(Avalonia.Controls.ColumnDefinition.WidthProperty)); |
||||
|
element.SetValue(Avalonia.Controls.ColumnDefinition.WidthProperty, ZeroWidth); |
||||
|
} |
||||
|
return visibility; |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
public static bool GetIsVisible(Avalonia.Controls.ColumnDefinition columnDefinition) |
||||
|
{ |
||||
|
return columnDefinition.GetValue(IsVisibleProperty); |
||||
|
} |
||||
|
|
||||
|
public static void SetIsVisible(Avalonia.Controls.ColumnDefinition columnDefinition, bool visibility) |
||||
|
{ |
||||
|
columnDefinition.SetValue(IsVisibleProperty, visibility); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,119 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
using Lifetimes = Avalonia.Controls.ApplicationLifetimes; |
||||
|
using App = Avalonia.Application; |
||||
|
|
||||
|
namespace Avalonia.Diagnostics.Controls |
||||
|
{ |
||||
|
class Application : AvaloniaObject |
||||
|
, Input.ICloseable |
||||
|
|
||||
|
{ |
||||
|
private readonly App _application; |
||||
|
private static readonly Version s_version = typeof(IAvaloniaObject).Assembly?.GetName()?.Version |
||||
|
?? Version.Parse("0.0.00"); |
||||
|
public event EventHandler? Closed; |
||||
|
|
||||
|
public Application(App application) |
||||
|
{ |
||||
|
_application = application; |
||||
|
|
||||
|
if (_application.ApplicationLifetime is Lifetimes.IControlledApplicationLifetime controller) |
||||
|
{ |
||||
|
EventHandler<Lifetimes.ControlledApplicationLifetimeExitEventArgs> eh = default!; |
||||
|
eh = (s, e) => |
||||
|
{ |
||||
|
controller.Exit -= eh; |
||||
|
Closed?.Invoke(s, e); |
||||
|
}; |
||||
|
controller.Exit += eh; |
||||
|
} |
||||
|
RendererRoot = application.ApplicationLifetime switch |
||||
|
{ |
||||
|
Lifetimes.IClassicDesktopStyleApplicationLifetime classic => classic.MainWindow.Renderer, |
||||
|
Lifetimes.ISingleViewApplicationLifetime single => (single.MainView as VisualTree.IVisual)?.VisualRoot?.Renderer, |
||||
|
_ => null |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
internal App Instance => _application; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines the <see cref="DataContext"/> property.
|
||||
|
/// </summary>
|
||||
|
public object? DataContext => |
||||
|
_application.DataContext; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the application's global data templates.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The application's global data templates.
|
||||
|
/// </value>
|
||||
|
public Avalonia.Controls.Templates.DataTemplates DataTemplates => |
||||
|
_application.DataTemplates; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the application's focus manager.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The application's focus manager.
|
||||
|
/// </value>
|
||||
|
public Input.IFocusManager? FocusManager => |
||||
|
_application.FocusManager; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the application's input manager.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The application's input manager.
|
||||
|
/// </value>
|
||||
|
public Input.InputManager? InputManager => |
||||
|
_application.InputManager; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the application clipboard.
|
||||
|
/// </summary>
|
||||
|
public Input.Platform.IClipboard? Clipboard => |
||||
|
_application.Clipboard; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the application's global resource dictionary.
|
||||
|
/// </summary>
|
||||
|
public IResourceDictionary Resources => |
||||
|
_application.Resources; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the application's global styles.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The application's global styles.
|
||||
|
/// </value>
|
||||
|
/// <remarks>
|
||||
|
/// Global styles apply to all windows in the application.
|
||||
|
/// </remarks>
|
||||
|
public Styling.Styles Styles => |
||||
|
_application.Styles; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Application lifetime, use it for things like setting the main window and exiting the app from code
|
||||
|
/// Currently supported lifetimes are:
|
||||
|
/// - <see cref="Lifetimes.IClassicDesktopStyleApplicationLifetime"/>
|
||||
|
/// - <see cref="Lifetimes.ISingleViewApplicationLifetime"/>
|
||||
|
/// - <see cref="Lifetimes.IControlledApplicationLifetime"/>
|
||||
|
/// </summary>
|
||||
|
public Lifetimes.IApplicationLifetime? ApplicationLifetime => |
||||
|
_application.ApplicationLifetime; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Application name to be used for various platform-specific purposes
|
||||
|
/// </summary>
|
||||
|
public string? Name => |
||||
|
_application.Name; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the root of the visual tree, if the control is attached to a visual tree.
|
||||
|
/// </summary>
|
||||
|
internal Rendering.IRenderer? RendererRoot { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using Avalonia.Data; |
||||
|
using Avalonia.Data.Converters; |
||||
|
|
||||
|
namespace Avalonia.Diagnostics.Converters |
||||
|
{ |
||||
|
internal class GetTypeNameConverter : IValueConverter |
||||
|
{ |
||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) |
||||
|
{ |
||||
|
if (value is Type type) |
||||
|
{ |
||||
|
return type.GetTypeName(); |
||||
|
} |
||||
|
return BindingOperations.DoNothing; |
||||
|
} |
||||
|
|
||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) |
||||
|
{ |
||||
|
return BindingOperations.DoNothing; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Input.Raw; |
||||
|
|
||||
|
namespace Avalonia.Diagnostics |
||||
|
{ |
||||
|
static class KeyGestureExtesions |
||||
|
{ |
||||
|
public static bool Matches(this KeyGesture gesture, RawKeyEventArgs keyEvent) => |
||||
|
keyEvent != null && |
||||
|
(KeyModifiers)(keyEvent.Modifiers & RawInputModifiers.KeyboardMask) == gesture.KeyModifiers && |
||||
|
ResolveNumPadOperationKey(keyEvent.Key) == ResolveNumPadOperationKey(gesture.Key); |
||||
|
|
||||
|
private static Key ResolveNumPadOperationKey(Key key) |
||||
|
{ |
||||
|
switch (key) |
||||
|
{ |
||||
|
case Key.Add: |
||||
|
return Key.OemPlus; |
||||
|
case Key.Subtract: |
||||
|
return Key.OemMinus; |
||||
|
case Key.Decimal: |
||||
|
return Key.OemPeriod; |
||||
|
default: |
||||
|
return key; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Avalonia.Diagnostics |
||||
|
{ |
||||
|
internal static class TypeExtesnions |
||||
|
{ |
||||
|
private static readonly ConditionalWeakTable<Type, string> s_getTypeNameCache = |
||||
|
new ConditionalWeakTable<Type, string>(); |
||||
|
|
||||
|
public static string GetTypeName(this Type type) |
||||
|
{ |
||||
|
if (!s_getTypeNameCache.TryGetValue(type, out var name)) |
||||
|
{ |
||||
|
name = type.Name; |
||||
|
if (Nullable.GetUnderlyingType(type) is Type nullable) |
||||
|
{ |
||||
|
name = nullable.Name + "?"; |
||||
|
} |
||||
|
else if (type.IsGenericType) |
||||
|
{ |
||||
|
var definition = type.GetGenericTypeDefinition(); |
||||
|
var arguments = type.GetGenericArguments(); |
||||
|
name = definition.Name.Substring(0, definition.Name.IndexOf('`')); |
||||
|
name = $"{name}<{string.Join(",", arguments.Select(GetTypeName))}>"; |
||||
|
} |
||||
|
s_getTypeNameCache.Add(type, name); |
||||
|
} |
||||
|
return name; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue