Skip to content

Commit

Permalink
Reorder child windows recursively when window has been activated.
Browse files Browse the repository at this point in the history
  • Loading branch information
hamster620 committed Aug 31, 2022
1 parent 757356c commit f08400e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Application.Avalonia.Tests/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
</Rectangle>
</Border>

<TextBox HorizontalAlignment="Left" Margin="5" Width="200"/>

</StackPanel>

</Window>
21 changes: 14 additions & 7 deletions Application.Avalonia.Tests/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace CarinaStudio
partial class MainWindow : Controls.Window<IApp>
{
DoubleAnimator? animator;
TestDialog? testDialog;


public MainWindow()
Expand All @@ -27,15 +28,20 @@ private void InitializeComponent()
}


void Test()
public void Test()
{
/*
if (this.OwnedWindows.Count > 0)
_ = new TestDialog().ShowDialog(this);
if (this.testDialog == null)
{
this.testDialog = new TestDialog().Also(it =>
{
it.Closed += (_, e) => this.testDialog = null;
});
this.testDialog.Show(this);
}
else
new TestDialog().Show(this);
*/

new TestDialog().ShowDialog(this.testDialog);

/*
var transform = this.Find<Rectangle>("rect")?.RenderTransform as TranslateTransform;
if (transform == null)
return;
Expand All @@ -50,6 +56,7 @@ void Test()
it.ProgressChanged += (_, e) => transform.X = it.Value;
it.Start();
});
*/
}
}
}
48 changes: 32 additions & 16 deletions Application.Avalonia/Controls/Window.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Avalonia;
using System.Threading.Tasks;
using Avalonia;
using CarinaStudio.Configuration;
using CarinaStudio.Threading;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -34,7 +35,7 @@ public abstract class Window : Avalonia.Controls.Window, IApplicationObject

// Fields.
readonly ScheduledAction checkDialogsAction;
readonly List<(Avalonia.Controls.Window, bool)> children;
readonly IList<(Avalonia.Controls.Window, bool)> children;
bool hasDialogs;
bool isClosed;
bool isOpened;
Expand All @@ -53,30 +54,40 @@ protected Window()
var hasDialogs = false;
var isAvalonia_0_10_15_OrAbove = AvaloniaVersion.Major == 0
&& (AvaloniaVersion.Minor > 10 || AvaloniaVersion.Build >= 15);
var isActive = this.IsActive;
void RefreshChildWindowPositions(Avalonia.Controls.Window parent)
{
var childWindows = parent is Window window
? window.children
: GetInternalChildWindows(parent);
if (childWindows == null || childWindows.Count == 0)
return;
foreach (var (childWindow, isDialog) in childWindows)
{
if (!childWindow.Topmost)
{
childWindow.Topmost = true;
childWindow.Topmost = false;
}
RefreshChildWindowPositions(childWindow);
}
}
foreach (var (childWindow, isDialog) in this.children!)
{
if (isDialog)
{
hasDialogs = true;
if (!isAvalonia_0_10_15_OrAbove)
break;
}
if (!childWindow.Topmost)
{
childWindow.Topmost = true;
childWindow.Topmost = false;
break;
}
}
RefreshChildWindowPositions(this);
if (this.hasDialogs != hasDialogs)
this.SetAndRaise<bool>(HasDialogsProperty, ref this.hasDialogs, hasDialogs);
});
this.children = typeof(Avalonia.Controls.Window).GetField("_children", BindingFlags.Instance | BindingFlags.NonPublic)?.Let(it =>
(List<(Avalonia.Controls.Window, bool)>)it.GetValue(this).AsNonNull()) ?? Global.Run(() =>
{
this.Logger.LogError("Unable to get list of child window");
return new List<(Avalonia.Controls.Window, bool)>();
});
this.children = GetInternalChildWindows(this) ?? Global.Run(() =>
{
this.Logger.LogError("Unable to get list of child window");
return new (Avalonia.Controls.Window, bool)[0];
});
this.GetObservable(IsActiveProperty).Subscribe(_ => this.checkDialogsAction.Schedule());
this.AddHandler(PointerWheelChangedEvent, (_, e) =>
{
Expand All @@ -92,6 +103,11 @@ protected Window()
public IApplication Application { get; } = CarinaStudio.Application.Current;


// Get internal list of child windows.
static IList<(Avalonia.Controls.Window, bool)>? GetInternalChildWindows(Avalonia.Controls.Window window) =>
typeof(Avalonia.Controls.Window).GetField("_children", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(window) as IList<ValueTuple<Avalonia.Controls.Window, bool>>;


/// <summary>
/// Get whether at least one <see cref="Dialog{TApp}"/> owned by this window is shown or not.
/// </summary>
Expand Down

0 comments on commit f08400e

Please sign in to comment.