Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing and Re-Adding a MenuBar breaks Width #3136

Closed
tznind opened this issue Jan 7, 2024 · 5 comments
Closed

Removing and Re-Adding a MenuBar breaks Width #3136

tznind opened this issue Jan 7, 2024 · 5 comments
Labels
Milestone

Comments

@tznind
Copy link
Collaborator

tznind commented Jan 7, 2024

Describe the bug

Removing and Re-Adding a View should not change any of it's size/position parameters.

But for MenuBar it does, it changes Dim.Fill(0) to Dim.Absolute(0)

Strangely it manifests only for the second menu bar and not the first. Do not understand why but is consistent. I first noticed this in gui-cs/TerminalGuiDesigner#287 .

TerminalGuiDesigner will sometimes remove and re-add a View to a parent. This sometimes is for sensible reasons (e.g. dragging into a new view container). Also sometimes to avoid Exceptions being thrown for changing some properties while mounted. It is important that removing and re-adding does not modify properties (other than parent :) )

[Fact]
public void RemoveAndThenAddMenuBar_ShouldNotChangeWidth ()
{
	MenuBar menuBar;
	MenuBar menuBar2;

	var w = new Window ();
	menuBar2 = new Terminal.Gui.MenuBar ();
	menuBar = new Terminal.Gui.MenuBar ();
	w.Width = Dim.Fill (0);
	w.Height = Dim.Fill (0);
	w.X = 0;
	w.Y = 0;

	w.Visible = true;
	w.Modal = false;
	w.Title = "";
	menuBar.Width = Dim.Fill (0);
	menuBar.Height = 1;
	menuBar.X = 0;
	menuBar.Y = 0;
	menuBar.Visible = true;
	w.Add (menuBar);

	menuBar2.Width = Dim.Fill (0);
	menuBar2.Height = 1;
	menuBar2.X = 0;
	menuBar2.Y = 4;
	menuBar2.Visible = true;
	w.Add (menuBar2);


	var menuBars = w.Subviews.OfType<MenuBar> ().ToArray ();
	Assert.Equal (2, menuBars.Length);

	Assert.Equal (Dim.Fill (0), menuBars [0].Width);
	Assert.Equal (Dim.Fill (0), menuBars [1].Width);

	// Goes wrong here
	w.Remove (menuBar);
	w.Remove (menuBar2);

	w.Add (menuBar);
	w.Add (menuBar2);

	// These assertions fail
	Assert.Equal (Dim.Fill (0), menuBars [0].Width);
	Assert.Equal (Dim.Fill (0), menuBars [1].Width);
}
  Message: 
Assert.Equal() Failure: Values differ
Expected: Absolute(0)
Actual:   Fill(0)

  Stack Trace: 
MenuBarTests.RemoveAndThenAddMenuBar_ShouldNotChangeWidth() line 2806
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

tznind added a commit to gui-cs/TerminalGuiDesigner that referenced this issue Jan 7, 2024
@tig
Copy link
Collaborator

tig commented Jan 7, 2024

This is likely related to the spaghetti code that is "Toplevel".

See the issues listed here: #3135

@tig
Copy link
Collaborator

tig commented Jan 7, 2024

I've added your test to #3135 and changed it to this in order to pass for now (use View instead of Window)

		var w = new View ();
		menuBar2 = new Terminal.Gui.MenuBar ();
		menuBar = new Terminal.Gui.MenuBar ();
		w.Width = Dim.Fill (0);
		w.Height = Dim.Fill (0);
		w.X = 0;
		w.Y = 0;

		w.Visible = true;
		//w.Modal = false;

tig added a commit to tig/Terminal.Gui that referenced this issue Jan 7, 2024
@BDisp
Copy link
Collaborator

BDisp commented Jan 7, 2024

The affecting code is the RemoveMenuStatusBar method. Commenting the MenuBar?.Dispose (); and the StatusBar?.Dispose (); will not fail. A super-view must only dispose a sub-view if the super-view is being disposed.

	internal void RemoveMenuStatusBar (View view)
	{
		if (view is MenuBar) {
			//MenuBar?.Dispose ();
			MenuBar = null;
		}
		if (view is StatusBar) {
			//StatusBar?.Dispose ();
			StatusBar = null;
		}
	}

The Toplevel.Remove is also wrong because of if (this is Toplevel Toplevel && (Toplevel.MenuBar != null) {. So this is always Toplevel and must call RemoveMenuStatusBar no matter MenuBar != null or StatusBar != null.

	///<inheritdoc/>
	public override void Remove (View view)
	{
		RemoveMenuStatusBar (view);
		base.Remove (view);
	}

Unit test for the StatusBar:

		[Fact]
		public void RemoveAndThenAddStatusBar_ShouldNotChangeWidth ()
		{
			StatusBar statusBar;
			StatusBar statusBar2;

			var w = new Window ();
			statusBar2 = new StatusBar () { Id = "statusBar2" };
			statusBar = new StatusBar () { Id = "statusBar" };
			w.Width = Dim.Fill (0);
			w.Height = Dim.Fill (0);
			w.X = 0;
			w.Y = 0;

			w.Visible = true;
			w.Modal = false;
			w.Title = "";
			statusBar.Width = Dim.Fill (0);
			statusBar.Height = 1;
			statusBar.X = 0;
			statusBar.Y = 0;
			statusBar.Visible = true;
			w.Add (statusBar);
			Assert.Equal (w.StatusBar, statusBar);

			statusBar2.Width = Dim.Fill (0);
			statusBar2.Height = 1;
			statusBar2.X = 0;
			statusBar2.Y = 4;
			statusBar2.Visible = true;
			w.Add (statusBar2);
			Assert.Equal (w.StatusBar, statusBar2);

			var menuBars = w.Subviews.OfType<StatusBar> ().ToArray ();
			Assert.Equal (2, menuBars.Length);

			Assert.Equal (Dim.Fill (0), menuBars [0].Width);
			Assert.Equal (Dim.Fill (0), menuBars [1].Width);

			// Goes wrong here
			w.Remove (statusBar);
			w.Remove (statusBar2);

			w.Add (statusBar);
			w.Add (statusBar2);

			// These assertions fail
			Assert.Equal (Dim.Fill (0), menuBars [0].Width);
			Assert.Equal (Dim.Fill (0), menuBars [1].Width);
		}

@tig tig added the bug label Jan 8, 2024
tig added a commit that referenced this issue Jan 13, 2024
…works. Fixes `AutoSize` etc... (#3130)

* Removes CheckAbsoulte and updates unit tests to match

* Fixed code that was dependent on ToString behavior vs. direct test for null

* Dim/Pos != null WIP

* Moved AutoSize specific tests out of Pos/Dim tests

* Broke out AutoSize = false tests to new file

* Commented test TODOs

* New test

* Removed unused API and cleaned up code

* Removed unused API and cleaned up code

* Cleaned up code

* Cleaned up code

* reorg'd Toplevel tests

* Fixed Create and related unit tests

* Added test from #3136

* Removed TopLevel.Create

* Fixed SetCurrentOverlappedAsTop

* Updated pull request template

* Updated pull request template

* Revert "Updated pull request template"

This reverts commit d807190.

* reverting

* re-reverting

* Fixed every thing but autosize scenarios??

* Fixed hexview

* Fixed contextmenu

* Fixed more minor issues in tests

* Fixed more minor issues in tests

* Debugging Dialog test failure

* Fixed bad Dialog test. Was cleary invalid

* Fixed OnResizeNeeded bug

* Fixed OnResizeNeeded bug

* Fixed UICatalog to not eat exceptions

* Fixed TextView

* Removed Frame overrides

* Made Frame non-virtual

* Fixed radioGroup

* Fixed TabView

* Hcked ScrolLBarView unit tests to pass

* All AutoSize tests pass!

* All tests pass!!!!!!!

* Updated API docs. Cleaned up code.

* Fixed ColorPicker

* Added 'Bounds =' unit tests

* Refactored TextFormatter.Size setting logic

* Cleaned up OnResizeNeeded (api docs and usages)

* Merges in #3019 changes. Makes OnResizeNeeded non-virtual. If we find a use-case where someone wants to override it we can change this back.

* Fixed FileDialog bounds warning

* Removed resharper settings from editorconfig

* Added Pos.Center test to AllViewsTests.cs.
Modernized RadioGroup.
Fixed ProgressBar.

* Reverted formatting

* Reverted formatting

* Reverted formatting

* Reverted formatting

* Reverted formatting

* Reverted formatting

* Reverted formatting

* Code cleanup

* Code cleanup

* Code cleanup

* Code cleanup

* Code cleanup

* Code cleanup

* Code cleanup

* Code cleanup

* Reverted formatting
@tig tig added this to the V2 Beta milestone May 27, 2024
@BDisp
Copy link
Collaborator

BDisp commented Jun 17, 2024

I think that some of what is stated here has already been implemented, right?
Another solution that could help while the MenuBar is being built and dragged, is to create two methods for suspending (allows manipulating objects with new values ​​without performing any layout) and resuming (allows resetting manipulated objects with their original values ​​and summarizing the layout immediately ) the layout, as already discussed.

@tig
Copy link
Collaborator

tig commented Jun 17, 2024

I just added the RemoveAndThenAddStatusBar_ShouldNotChangeWidth you proposed above to #3533 and it passes.

The menu test is already in v2_develop. I think this can be closed once #3533 is done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: ✅ Done
Development

No branches or pull requests

3 participants