Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 22, 2025

Fixes

Proposed Changes/Todos

  • Add OpenMenu() method to programmatically open first menu item
  • Add OpenMenu(Point?) overload for custom positioning
  • Update MenuBar documentation with dropdown usage pattern
  • Add comprehensive unit tests (3 new tests, all passing)
  • Fix test compilation errors (replaced Toplevel with Runnable)

Changes

Public API Additions

MenuBar.OpenMenu()

  • Opens first MenuBarItem with PopoverMenu
  • Activates MenuBar and sets focus automatically
  • Returns bool indicating success

MenuBar.OpenMenu(Point? position)

  • Opens menu at specified screen coordinates
  • Enables alignment with adjacent controls (e.g., TextField)
  • Falls back to default positioning if null

Implementation

Modified ShowItem() to accept optional Point? position parameter. When provided, positions PopoverMenu at specified coordinates instead of default MenuBarItem bottom-left.

Documentation

Added class-level example showing TextField + MenuBar dropdown pattern:

var tf = new TextField { Width = 10 };
var menuBarItem = new MenuBarItem ("▼", 
    new MenuItem [] {
        new ("Item 1", () => tf.Text = "Item 1"),
        new ("Item 2", () => tf.Text = "Item 2")
    });
var mb = new MenuBar ([menuBarItem]) {
    Width = 1,
    Y = Pos.Top (tf),
    X = Pos.Right (tf)
};
mb.Enter += (s, e) => mb.OpenMenu (new Point (tf.FrameToScreen ().X, tf.FrameToScreen ().Bottom));

Bug Fixes

Fixed compilation errors in test methods by using new Runnable() instead of new Toplevel() to align with the existing test pattern in MenuBarTests class.

Notes

  • First menu item selection already works via Menu.OnVisibleChanged - no fix needed
  • MenuBar.DefaultBorderStyle already LineStyle.None - clean appearance by default
  • All changes additive - no breaking changes

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui - if you use Visual Studio, hit CTRL-K-D to automatically reformat your files before committing.
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working
Original prompt

This section details on the original issue you should resolve

<issue_title>Enable using MenuBar as an alternative for ComboBox</issue_title>
<issue_description>See comments below.

Essence is the current ComboBox is a bugfarm and barely works. It needs to be replaced.

This Issue is to create a new View named DropDownList.

This comment illustrates how it can be built

#2404 (comment)

</issue_description>

Comments on the Issue (you are @copilot in this section)

@tig Would it make sense to rename this Issue to "Enable using MenuBar as a replacement for ComboBox?" @tig I agree we should have both.

I don't believe "combo" as a term makes sense for this one tho.

Is it really a new view or is it just a MenuBar used in a particular way?</comment_new>
<comment_new>@tig
Do the api docs describe how to do this?</comment_new>
<comment_new>@tig
Why isn't Onfocus true by default?

Yesterday I was goofing with Focus stuff and realized it might make sense for Menubar to participate in tabstops along with the other subviews of a view.</comment_new>
<comment_new>@tig

That's not the normal behavior on a app, but you can do that behavior for Terminal.Gui. It's debatable.

Yeah. Probably best to leave it as is. It was just an idle thought.</comment_new>
<comment_new>@tig
Here's a tweaked scenario. I realy love this!

		public override void Setup ()
		{
			var tf = new TextField () { Width = 10 };
			Application.Top.Add (tf);

			MenuBarItem menu = null;

			MenuItem CreateMenuItem (int i)
			{
				return new MenuItem ($"Item {i}", null, () => {
					tf.Text = menu.Children [i - 1].Title;
				});
			}

			menu = new MenuBarItem ($"{Application.Driver.DownArrow}",
				Enumerable.Range (1, 5).Select (
						(a) => CreateMenuItem (a))
					.ToArray ());

			var mb = new MenuBar (new [] { menu }) {
				CanFocus = true,
				Width = 1,
				Y = Pos.Top (tf),
				X = Pos.Right (tf)
			};

			// HACKS required to make this work:
			mb.Enter += (s, e) => {
				// BUG: This does not select menu item 0
				// Instead what happens is the first keystroke the user presses
				// gets swallowed and focus is moved to 0.  Result is that you have
				// to press down arrow twice to select first menu item and/or have to
				// press Tab twice to move focus back to TextField
				mb.OpenMenu ();
			};

			Application.Top.Add (mb);

This mostly works today as @tznind notes.

4Sl96Je 1

What needs to be fixed to make this really be done:

  • The menu should pop down aligned to the left of the textField.
  • MenuBorderStyle = LineStyle.None might look better

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add DropDownList view as alternative to ComboBox Fixes #2404. Add OpenMenu() methods to MenuBar for dropdown list usage Nov 22, 2025
Copilot AI requested a review from tig November 22, 2025 01:52
Copilot finished work on behalf of tig November 22, 2025 01:52
@codecov
Copy link

codecov bot commented Nov 22, 2025

Codecov Report

❌ Patch coverage is 90.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.34%. Comparing base (0eafb59) to head (01c94ce).
⚠️ Report is 1 commits behind head on v2_develop.

Files with missing lines Patch % Lines
Terminal.Gui/App/PopoverWrapper.cs 80.00% 2 Missing and 2 partials ⚠️
Terminal.Gui/App/PopoverBaseImpl.cs 0.00% 0 Missing and 1 partial ⚠️
Terminal.Gui/Views/Shortcut.cs 95.45% 1 Missing ⚠️
Additional details and impacted files
@@               Coverage Diff               @@
##           v2_develop    #4412       +/-   ##
===============================================
- Coverage       77.45%   66.34%   -11.12%     
===============================================
  Files             386      388        +2     
  Lines           44585    44644       +59     
  Branches         6272     6282       +10     
===============================================
- Hits            34533    29618     -4915     
- Misses           8206    13103     +4897     
- Partials         1846     1923       +77     
Files with missing lines Coverage Δ
Terminal.Gui/App/ViewPopoverExtensions.cs 100.00% <100.00%> (ø)
Terminal.Gui/Views/Menu/MenuBar.cs 82.17% <100.00%> (+0.15%) ⬆️
Terminal.Gui/App/PopoverBaseImpl.cs 79.54% <0.00%> (-1.85%) ⬇️
Terminal.Gui/Views/Shortcut.cs 84.87% <95.45%> (-4.97%) ⬇️
Terminal.Gui/App/PopoverWrapper.cs 80.00% <80.00%> (ø)

... and 159 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0eafb59...01c94ce. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tig
Copy link
Collaborator

tig commented Dec 6, 2025

@copilot Investigate and fix the failing integration and unit tests.

Copy link
Contributor Author

Copilot AI commented Dec 6, 2025

@copilot Investigate and fix the failing integration and unit tests.

Fixed in commit 854a095. The test compilation errors were caused by using new Toplevel() instead of new Runnable() in the three new test methods. All tests now pass:

  • ✅ 21 MenuBar unit tests passing
  • ✅ 304 integration tests passing
  • ✅ 1168 total unit tests passing

Copilot finished work on behalf of tig December 6, 2025 16:32
@tig tig marked this pull request as ready for review December 6, 2025 16:37
@tig tig marked this pull request as draft December 6, 2025 16:37
@tig
Copy link
Collaborator

tig commented Dec 6, 2025

@copilot here's my git remote -v:

git remote -v
bdisp tig:BDisp/Terminal.Gui (fetch)
bdisp tig:BDisp/Terminal.Gui (push)
copilot https://github.com/gui-cs/Terminal.Gui.git (fetch)
copilot https://github.com/gui-cs/Terminal.Gui.git (push)
origin tig:tig/Terminal.Gui (fetch)
origin tig:tig/Terminal.Gui (push)
upstream tig:gui-cs/Terminal.Gui (fetch)
upstream tig:gui-cs/Terminal.Gui (push)

Help me pull this down locally. git checkout copilot/enable-menubar-replacement says:

git checkout copilot/enable-menubar-replacement
hint: If you meant to check out a remote tracking branch on, e.g. 'origin',
hint: you can do so by fully qualifying the name with the --track option:
hint:
hint: git checkout --track origin/
hint:
hint: If you'd like to always have checkouts of an ambiguous prefer
hint: one remote, e.g. the 'origin' remote, consider setting
hint: checkout.defaultRemote=origin in your config.
fatal: 'copilot/enable-menubar-replacement' matched multiple (2) remote tracking branches

Copy link
Contributor Author

Copilot AI commented Dec 6, 2025

@copilot here's my git remote -v:

git remote -v
...

Based on your remotes, the branch is on the copilot remote. Use:

git fetch copilot
git checkout --track copilot/copilot/enable-menubar-replacement

Or if you want to check it out with a different local name:

git checkout -b enable-menubar-replacement copilot/copilot/enable-menubar-replacement

This will create a local branch tracking the remote branch from the copilot remote.

Copilot finished work on behalf of tig December 6, 2025 16:54
tig added 3 commits December 6, 2025 11:09
Refactored `DropDownListExample` for modularity and lifecycle management. Introduced `PopoverWrapper<TView>` to enable any `View` to function as a popover, along with `ViewPopoverExtensions` for a fluent API. Added `PopoverWrapperExample` project to demonstrate usage with examples like `ListView`, forms, and `ColorPicker`.

Enhanced `Shortcut` class with a configurable `MarginThickness` property. Updated `PopoverBaseImpl` to redraw UI on visibility changes. Added comprehensive unit tests for `PopoverWrapper` and extensions. Updated `Terminal.sln` to include the new project. Added detailed documentation in `README.md`.

Improved code maintainability, modularity, and user experience.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable using MenuBar as an alternative for ComboBox

2 participants