mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-27 00:07:58 +01:00
* Fixes #2776. Pressing Alt key on a Window with only a MenuBar throws System.InvalidOperationException. * Add unit test. * Fix extra bracket. * Prevents throw exception if Application.Current is null. * Fix unit test because OnLeave is now invoked on toplevel removing, preventing two views having focus. * Fix unit test method name. * Fix Window by not layout on his subviews when adding a new view after the Application.Begin was already running. * FindAndOpenMenuByHotkey now search inside Menus and inside his Children. * Add unit test for Window LayoutSubviews and FindAndOpenChildrenMenuByHotkey menu method. * Prevents button to be clear when it's invisible. * Fixes 2780. Moving a Window that is Application.Top shouldn't be allowed. * Fix condition if Window and Application.Top. * Always LayoutSubviews and PositionToplevels after Clear. * Fixes #2787. MenuItem with CanExecute returning false is select when a MenuBar is opened. * Leveraging the power of CanExecute feature. * Fixes #2789. StatusItem should have a disabled attribute if it can't execute. * Allows positioning a child window outside the limits of the menu and the status bar. * Change to a more appropriate name. * Simplifies all the run actions. * Prevents open menu bar if it's invisible and close all opened menus. * Fix mdi run loop. * Fix hot key on mdi toplevels. * Fix position on mdi toplevels. * Fix Top.Redraw by set state.Toplevel.SetNeedsDisplay if it's needed to redraw. * Fix MdiTop by repainted when a keystroke is generated by keyboard. * Rename local fields. * Force redraw if application.Top needs display. * Added more features to the scenario. * Change the scenarios to run as Application.Top instead of sub-views. * Add a new scenario similar but as Mdi Container. * Add a bunch of new unit tests to prove all this PR. * Only it's need to redraw Application.Top if it's a Mdi Container. * Remove unnecessary code. * Unit test that proves that a MDI child leaves no trace when the location is changed. * Removes unnecessary Application.Init because theses uses Run<T> which already call it. * Ensures a menu bar been closed after run an action. * Ensures that another view can be focused if not IsMenuOpen and LastFocused is null, instead of focused the menu itself. * Ensures a focused contentview subview being focused if MostFocused is null. * Ensures a MdiTop subview to have priority if it's focused and thus make it Current. * Allow a MdiChild be closed when pressing Application.QuitKey. * More unit tests proving the changes. * Ensures the top.MostFocused is focused. * Ensures MdiChild on the front if MdiTop.MostFocused isn't valid, like ContentView. * Add unit test showing MdiChild on the front. * Fix an issue where NullReferenceException can be throws everywhere while get the Application.MdiChildes property. --------- Co-authored-by: Tig <tig@users.noreply.github.com>
701 lines
18 KiB
C#
701 lines
18 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Terminal.Gui;
|
|
using Xunit;
|
|
|
|
// Alias Console to MockConsole so we don't accidentally use Console
|
|
using Console = Terminal.Gui.FakeConsole;
|
|
|
|
namespace Terminal.Gui.TopLevelTests {
|
|
public class MdiTests {
|
|
public MdiTests ()
|
|
{
|
|
#if DEBUG_IDISPOSABLE
|
|
Responder.Instances.Clear ();
|
|
Application.RunState.Instances.Clear ();
|
|
#endif
|
|
}
|
|
|
|
|
|
[Fact]
|
|
public void Dispose_Toplevel_IsMdiContainer_False_With_Begin_End ()
|
|
{
|
|
Application.Init (new FakeDriver ());
|
|
|
|
var top = new Toplevel ();
|
|
var rs = Application.Begin (top);
|
|
Application.End (rs);
|
|
|
|
Application.Shutdown ();
|
|
|
|
#if DEBUG_IDISPOSABLE
|
|
Assert.Equal (2, Responder.Instances.Count);
|
|
Assert.True (Responder.Instances [0].WasDisposed);
|
|
Assert.True (Responder.Instances [1].WasDisposed);
|
|
#endif
|
|
}
|
|
|
|
[Fact]
|
|
public void Dispose_Toplevel_IsMdiContainer_True_With_Begin ()
|
|
{
|
|
Application.Init (new FakeDriver ());
|
|
|
|
var mdi = new Toplevel { IsMdiContainer = true };
|
|
var rs = Application.Begin (mdi);
|
|
Application.End (rs);
|
|
|
|
Application.Shutdown ();
|
|
#if DEBUG_IDISPOSABLE
|
|
Assert.Equal (2, Responder.Instances.Count);
|
|
Assert.True (Responder.Instances [0].WasDisposed);
|
|
Assert.True (Responder.Instances [1].WasDisposed);
|
|
#endif
|
|
}
|
|
|
|
[Fact, AutoInitShutdown]
|
|
public void Application_RequestStop_With_Params_On_A_Not_MdiContainer_Always_Use_Application_Current ()
|
|
{
|
|
var top1 = new Toplevel ();
|
|
var top2 = new Toplevel ();
|
|
var top3 = new Window ();
|
|
var top4 = new Window ();
|
|
var d = new Dialog ();
|
|
|
|
// top1, top2, top3, d1 = 4
|
|
var iterations = 4;
|
|
|
|
top1.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (top2);
|
|
};
|
|
top2.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (top3);
|
|
};
|
|
top3.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (top4);
|
|
};
|
|
top4.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (d);
|
|
};
|
|
|
|
d.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
// This will close the d because on a not MdiContainer the Application.Current it always used.
|
|
Application.RequestStop (top1);
|
|
Assert.True (Application.Current == d);
|
|
};
|
|
|
|
d.Closed += (e) => Application.RequestStop (top1);
|
|
|
|
Application.Iteration += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
if (iterations == 4) {
|
|
Assert.True (Application.Current == d);
|
|
} else if (iterations == 3) {
|
|
Assert.True (Application.Current == top4);
|
|
} else if (iterations == 2) {
|
|
Assert.True (Application.Current == top3);
|
|
} else if (iterations == 1) {
|
|
Assert.True (Application.Current == top2);
|
|
} else {
|
|
Assert.True (Application.Current == top1);
|
|
}
|
|
|
|
Application.RequestStop (top1);
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (top1);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
class Mdi : Toplevel {
|
|
public Mdi ()
|
|
{
|
|
IsMdiContainer = true;
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MdiContainer_With_Toplevel_RequestStop_Balanced ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d = new Dialog ();
|
|
|
|
// MdiChild = c1, c2, c3
|
|
// d1 = 1
|
|
var iterations = 4;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d);
|
|
};
|
|
|
|
// More easy because the Mdi Container handles all at once
|
|
d.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
// This will not close the MdiContainer because d is a modal toplevel and will be closed.
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
d.Closed += (e) => {
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
Application.Iteration += () => {
|
|
if (iterations == 4) {
|
|
// The Dialog was not closed before and will be closed now.
|
|
Assert.True (Application.Current == d);
|
|
Assert.False (d.Running);
|
|
} else {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
for (int i = 0; i < iterations; i++) {
|
|
Assert.Equal ((iterations - i + 1).ToString (), Application.MdiChildes [i].Id);
|
|
}
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MdiContainer_With_Application_RequestStop_MdiTop_With_Params ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d = new Dialog ();
|
|
|
|
// MdiChild = c1, c2, c3
|
|
// d1 = 1
|
|
var iterations = 4;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d);
|
|
};
|
|
|
|
// Also easy because the Mdi Container handles all at once
|
|
d.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
// This will not close the MdiContainer because d is a modal toplevel
|
|
Application.RequestStop (mdi);
|
|
};
|
|
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
d.Closed += (e) => Application.RequestStop (mdi);
|
|
|
|
Application.Iteration += () => {
|
|
if (iterations == 4) {
|
|
// The Dialog was not closed before and will be closed now.
|
|
Assert.True (Application.Current == d);
|
|
Assert.False (d.Running);
|
|
} else {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
for (int i = 0; i < iterations; i++) {
|
|
Assert.Equal ((iterations - i + 1).ToString (), Application.MdiChildes [i].Id);
|
|
}
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MdiContainer_With_Application_RequestStop_MdiTop_Without_Params ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d = new Dialog ();
|
|
|
|
// MdiChild = c1, c2, c3 = 3
|
|
// d1 = 1
|
|
var iterations = 4;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d);
|
|
};
|
|
|
|
//More harder because it's sequential.
|
|
d.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
// Close the Dialog
|
|
Application.RequestStop ();
|
|
};
|
|
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
d.Closed += (e) => Application.RequestStop (mdi);
|
|
|
|
Application.Iteration += () => {
|
|
if (iterations == 4) {
|
|
// The Dialog still is the current top and we can't request stop to MdiContainer
|
|
// because we are not using parameter calls.
|
|
Assert.True (Application.Current == d);
|
|
Assert.False (d.Running);
|
|
} else {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
for (int i = 0; i < iterations; i++) {
|
|
Assert.Equal ((iterations - i + 1).ToString (), Application.MdiChildes [i].Id);
|
|
}
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void IsMdiChild_Testing ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d = new Dialog ();
|
|
|
|
Application.Iteration += () => {
|
|
Assert.False (mdi.IsMdiChild);
|
|
Assert.True (c1.IsMdiChild);
|
|
Assert.True (c2.IsMdiChild);
|
|
Assert.True (c3.IsMdiChild);
|
|
Assert.False (d.IsMdiChild);
|
|
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void Modal_Toplevel_Can_Open_Another_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d1 = new Dialog ();
|
|
var d2 = new Dialog ();
|
|
|
|
// MdiChild = c1, c2, c3 = 3
|
|
// d1, d2 = 2
|
|
var iterations = 5;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d1);
|
|
};
|
|
d1.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d2);
|
|
};
|
|
|
|
d2.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Assert.True (Application.Current == d2);
|
|
Assert.True (Application.Current.Running);
|
|
// Trying to close the Dialog1
|
|
d1.RequestStop ();
|
|
};
|
|
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
d1.Closed += (e) => {
|
|
Assert.True (Application.Current == d1);
|
|
Assert.False (Application.Current.Running);
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
Application.Iteration += () => {
|
|
if (iterations == 5) {
|
|
// The Dialog2 still is the current top and we can't request stop to MdiContainer
|
|
// because Dialog2 and Dialog1 must be closed first.
|
|
// Dialog2 will be closed in this iteration.
|
|
Assert.True (Application.Current == d2);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.False (d1.Running);
|
|
} else if (iterations == 4) {
|
|
// Dialog1 will be closed in this iteration.
|
|
Assert.True (Application.Current == d1);
|
|
Assert.False (Application.Current.Running);
|
|
} else {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
for (int i = 0; i < iterations; i++) {
|
|
Assert.Equal ((iterations - i + 1).ToString (), Application.MdiChildes [i].Id);
|
|
}
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void Modal_Toplevel_Can_Open_Another_Not_Modal_Toplevel_But_RequestStop_To_The_Caller_Also_Sets_Current_Running_To_False_Too ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
var d1 = new Dialog ();
|
|
var c4 = new Toplevel ();
|
|
|
|
// MdiChild = c1, c2, c3, c4 = 4
|
|
// d1 = 1
|
|
var iterations = 5;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (d1);
|
|
};
|
|
d1.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
Application.Run (c4);
|
|
};
|
|
|
|
c4.Ready += () => {
|
|
Assert.Equal (4, Application.MdiChildes.Count);
|
|
// Trying to close the Dialog1
|
|
d1.RequestStop ();
|
|
};
|
|
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
d1.Closed += (e) => {
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
Application.Iteration += () => {
|
|
if (iterations == 5) {
|
|
// The Dialog2 still is the current top and we can't request stop to MdiContainer
|
|
// because Dialog2 and Dialog1 must be closed first.
|
|
// Using request stop here will call the Dialog again without need
|
|
Assert.True (Application.Current == d1);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.True (c4.Running);
|
|
} else {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
for (int i = 0; i < iterations; i++) {
|
|
Assert.Equal ((iterations - i + (iterations == 4 && i == 0 ? 2 : 1)).ToString (),
|
|
Application.MdiChildes [i].Id);
|
|
}
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MoveCurrent_Returns_False_If_The_Current_And_Top_Parameter_Are_Both_With_Running_Set_To_False ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
|
|
// MdiChild = c1, c2, c3
|
|
var iterations = 3;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
c3.RequestStop ();
|
|
c1.RequestStop ();
|
|
};
|
|
// Now this will close the MdiContainer propagating through the MdiChildes.
|
|
c1.Closed += (e) => {
|
|
mdi.RequestStop ();
|
|
};
|
|
Application.Iteration += () => {
|
|
if (iterations == 3) {
|
|
// The Current still is c3 because Current.Running is false.
|
|
Assert.True (Application.Current == c3);
|
|
Assert.False (Application.Current.Running);
|
|
// But the childes order were reorder by Running = false
|
|
Assert.True (Application.MdiChildes [0] == c3);
|
|
Assert.True (Application.MdiChildes [1] == c1);
|
|
Assert.True (Application.MdiChildes [^1] == c2);
|
|
} else if (iterations == 2) {
|
|
// The Current is c1 and Current.Running is false.
|
|
Assert.True (Application.Current == c1);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.True (Application.MdiChildes [0] == c1);
|
|
Assert.True (Application.MdiChildes [^1] == c2);
|
|
} else if (iterations == 1) {
|
|
// The Current is c2 and Current.Running is false.
|
|
Assert.True (Application.Current == c2);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.True (Application.MdiChildes [^1] == c2);
|
|
} else {
|
|
// The Current is mdi.
|
|
Assert.True (Application.Current == mdi);
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MdiContainer_Throws_If_More_Than_One ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var mdi2 = new Mdi ();
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Throws<InvalidOperationException> (() => Application.Run (mdi2));
|
|
mdi.RequestStop ();
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void MdiContainer_Open_And_Close_Modal_And_Open_Not_Modal_Toplevels_Randomly ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var logger = new Toplevel ();
|
|
|
|
var iterations = 1; // The logger
|
|
var running = true;
|
|
var stageCompleted = true;
|
|
var allStageClosed = false;
|
|
var mdiRequestStop = false;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (logger);
|
|
};
|
|
|
|
logger.Ready += () => Assert.Single (Application.MdiChildes);
|
|
|
|
Application.Iteration += () => {
|
|
if (stageCompleted && running) {
|
|
stageCompleted = false;
|
|
var stage = new Window () { Modal = true };
|
|
|
|
stage.Ready += () => {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
stage.RequestStop ();
|
|
};
|
|
|
|
stage.Closed += (_) => {
|
|
if (iterations == 11) {
|
|
allStageClosed = true;
|
|
}
|
|
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
if (running) {
|
|
stageCompleted = true;
|
|
|
|
var rpt = new Window ();
|
|
|
|
rpt.Ready += () => {
|
|
iterations++;
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
};
|
|
|
|
Application.Run (rpt);
|
|
}
|
|
};
|
|
|
|
Application.Run (stage);
|
|
|
|
} else if (iterations == 11 && running) {
|
|
running = false;
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
|
|
} else if (!mdiRequestStop && running && !allStageClosed) {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
} else if (!mdiRequestStop && !running && allStageClosed) {
|
|
Assert.Equal (iterations, Application.MdiChildes.Count);
|
|
mdiRequestStop = true;
|
|
mdi.RequestStop ();
|
|
} else {
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
|
|
[Fact]
|
|
[AutoInitShutdown]
|
|
public void AllChildClosed_Event_Test ()
|
|
{
|
|
var mdi = new Mdi ();
|
|
var c1 = new Toplevel ();
|
|
var c2 = new Window ();
|
|
var c3 = new Window ();
|
|
|
|
// MdiChild = c1, c2, c3
|
|
var iterations = 3;
|
|
|
|
mdi.Ready += () => {
|
|
Assert.Empty (Application.MdiChildes);
|
|
Application.Run (c1);
|
|
};
|
|
c1.Ready += () => {
|
|
Assert.Single (Application.MdiChildes);
|
|
Application.Run (c2);
|
|
};
|
|
c2.Ready += () => {
|
|
Assert.Equal (2, Application.MdiChildes.Count);
|
|
Application.Run (c3);
|
|
};
|
|
c3.Ready += () => {
|
|
Assert.Equal (3, Application.MdiChildes.Count);
|
|
c3.RequestStop ();
|
|
c2.RequestStop ();
|
|
c1.RequestStop ();
|
|
};
|
|
// Now this will close the MdiContainer when all MdiChildes was closed
|
|
mdi.AllChildClosed += () => {
|
|
mdi.RequestStop ();
|
|
};
|
|
Application.Iteration += () => {
|
|
if (iterations == 3) {
|
|
// The Current still is c3 because Current.Running is false.
|
|
Assert.True (Application.Current == c3);
|
|
Assert.False (Application.Current.Running);
|
|
// But the childes order were reorder by Running = false
|
|
Assert.True (Application.MdiChildes [0] == c3);
|
|
Assert.True (Application.MdiChildes [1] == c2);
|
|
Assert.True (Application.MdiChildes [^1] == c1);
|
|
} else if (iterations == 2) {
|
|
// The Current is c2 and Current.Running is false.
|
|
Assert.True (Application.Current == c2);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.True (Application.MdiChildes [0] == c2);
|
|
Assert.True (Application.MdiChildes [^1] == c1);
|
|
} else if (iterations == 1) {
|
|
// The Current is c1 and Current.Running is false.
|
|
Assert.True (Application.Current == c1);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.True (Application.MdiChildes [^1] == c1);
|
|
} else {
|
|
// The Current is mdi.
|
|
Assert.True (Application.Current == mdi);
|
|
Assert.False (Application.Current.Running);
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
iterations--;
|
|
};
|
|
|
|
Application.Run (mdi);
|
|
|
|
Assert.Empty (Application.MdiChildes);
|
|
}
|
|
}
|
|
}
|